为什么mapply不返回日期对象?

10

我有一个函数可以接收一个日期对象并返回一个日期对象。但是,当我使用mapply函数将该函数应用于数据框列时,遇到了问题:我没有得到预期的日期对象,而是数字。您有什么想法如何将它们转换为日期对象吗?此外,我很想知道这里发生了什么。真的非常感谢您的帮助!

最小示例:

#Define simple function that takes a date-object and returns a date-object
add_day <- function(dat) {return(dat + 1)}

#Set up data.frame with two date-object entries in one column
df <- data.frame(Col_A = c(as.Date("01/01/00", "%m/%d/%y"), as.Date("05/02/11", "%m/%d/%y")))
#That is the desired result: give a date-object to the function, get one back
add_day(df[1, "Col_A"]) #Returns [1] "2000-01-02"
add_day(df[2, "Col_A"]) #Returns [1] "2011-05-03"

#Why does it not work here? What do I get back?
mapply(add_day, df[, "Col_A"]) #Returns [1] 10958 15097; Why? What is that?

为什么不这样做:add_day(df$Col_A) #[1] "2000-01-02" "2011-05-03"?或者我猜想:df$Col_A + 1,但我还是使用函数应用。 - IRTFM
3个回答

14

你的函数确实返回了“日期”,只不过它们的格式与你所熟悉的不同。日期在内部存储为自某个固定日期以来的天数。(我想不起来是哪个日期,而且具体格式会略有不同。)

如果你将mapply调用包装在as.Date中,你将看到你期望的输出。

要查看这里发生了什么,请考虑mapply在底层使用sapply。例如:

sapply(df[,1],add_day)
[1] 10958 15097

但要记住,默认情况下 sapply 将结果进行了方便的 unlist 操作。如果我们指定 simplify = FALSE

sapply(df[,1],add_day,simplify = FALSE)
[[1]]
[1] "2000-01-02"

[[2]]
[1] "2011-05-03"

因此,当R将列表强制转换为向量时,类信息会被丢弃,只保留内部存储,即自某个特定日期以来的天数。当然,mapply也有一个SIMPLIFY参数,其作用相同。


谢谢Joran,这是一个很好的解释。 - Christoph_J

12

另一种选择是使用类似于sapply.preserving.attributes的东西:

sapply.preserving.attributes = function(l, ...) {
    r = sapply(l, ...)
    attributes(r) = attributes(l)
    r
}

> sapply.preserving.attributes(dates, add_day)
[1] "2000-01-02" "2011-05-03"

谢谢Owen,你的选项很好。我会在我的代码中使用你的函数。 - Christoph_J
刚看到这个。非常棒的函数! - Ricardo Saporta

0

在运行mapply之后,可以使用这一行代码

df$date <- as.Date(as.numeric(df$date))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接