Why does mapply not return date-objects?
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 unlist
ing 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))
精彩评论