使用apply转换R中的日期并处理NA日期



这似乎应该容易得多,我相信有人可以帮助我。我正试图使用lubridate包中的floor_date()将每个日期从日期的data.frame更改为相应月份的第一个日期,但其中一些日期是NA。我宁愿不用假日期来代替NA。

我尝试过以下方法:

library(lubridate)
a<-c(as.Date("2011-05-04"), as.Date("2011-06-12"))
b<-c(as.Date("2012-03-01"), NA)
test <- data.frame(a,b)
apply(test, 1, function(y) sapply(y, function(x) if(!is.na(x)) floor_date(x, "month") else na.pass(x)))
apply(test, 1, function(y) ifelse(!is.na(y)), floor_date(y, "month"), na.pass(y))

第一个调用返回:

Error in object[[name, exact = TRUE]] : subscript out of bounds

第二个调用返回:

Error in update.default(x, mdays = 1, hours = 0, minutes = 0, seconds = 0) : 
need an object with call component

谢谢你的帮助!

我不知道lubridate,但有了base R.提供的出色的数据处理设施,您可以轻松做到这一点

这里有一个小辅助功能,可以毫无怨言地执行您想要的计算:

firstOfMonth <- function(dates) {
    as.Date(strftime(dates, format="%Y-%m-01"))
}
firstOfMonth(a)
# [1] "2011-05-01" "2011-06-01"
firstOfMonth(b)
# [1] "2012-03-01" NA   
data.frame(lapply(test, firstOfMonth))
#            a          b
# 1 2011-05-01 2012-03-01
# 2 2011-06-01       <NA>

你试过package zoo吗?

library(zoo)
a<-c(as.Date("2011-05-04"), as.Date("2011-06-12"))
b<-c(as.Date("2012-03-01"), NA)
test <- data.frame(
        "a" = as.Date(as.yearmon(a)),
        "b" = as.Date(as.yearmon(b))
)

这个怎么样?

my_floor_date <- function(x,...) {idx <- !is.na(x); x[idx] <- floor_date(x[idx], ...); x}
transform(test, a=my_floor_date(a, "month"), b=my_floor_date(b, "month"))

如果你想像你尝试的那样在一行中完成,这会起作用:

data.frame(lapply(test,function (y) (as.Date(sapply(y,function(x) if (is.na(x)) NA else floor_date(x,'month'))))))

这里真正的问题是lubridate函数本身,它应该允许您向update.Date传递一个参数,告诉它忽略NA。上面的strftime解决方案绝对是最干净的。

此外,正如评论中所提到的,您的解决方案之所以不起作用,是因为您使用了apply而不是lapply

floor_date()中的NA错误已在今天发送给CRAN的lubridate 1.1.0中修复。S3更新日期方法中的NA错误仍然存在(在开发版本中已修复)。同时,

floor_date(as.POSIXlt(test$b), unit = "month")

会起作用。

最新更新