开发者

Why does mapply not return date-objects?

开发者 https://www.devze.com 2023-04-11 11:56 出处:网络
I have a function that takes a Date-object and returns one. However, when I applied the function to a data.frame column using the mapply function, I ran into problems: I didn\'t get Date-objects back,

I have a function that takes a Date-object and returns one. However, when I applied the function to a data.frame column using the mapply function, I ran into problems: I didn't get Date-objects back, as expected, but numbers. Any idea how I could convert those to Date-objects? Also, I would be interested in what's happening here. Help is really appreciated!

Minimal example:

#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开发者_JS百科, df[, "Col_A"]) #Returns [1] 10958 15097; Why? What is that?


Your function is returning 'dates', just not in the format you are used to. Dates are stored internally as days since [some fixed date]. (I can't remember off the top of my head which one, and varies slightly by specific format.)

If you wrap your mapply call in as.Date you'll see the output you expect.

To see what's going on here, consider that mapply is using sapply under the hood. So for example:

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

But remember that sapply by default is unlisting results for convenience. If we specify simplify = FALSE:

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

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

So when R coerced the list to a vector, the class information is dropped and only the internal storage is retained, namely the number of days since [whatever that specific date is]. And of course, mapply also has a SIMPLIFY argument that acts in the same way.


Another option is something like 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"


Can use this single line of code after you run mapply

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号