Given a vector of datetime values, I needed to create a data.frame containing datetimes at 0:10 hours past each original datetime – the first column 0 hours past, the second column 1 hour past, etc.
I had some trouble finding a way to do this easily using lubridate stuff. I thought this should work:
rt <- ymd_hms(c("2011-11-03 19:24:12", "2011-10-28 20:48:21",
"2011-11-04 10:06:14", "2011-10-31 17:10:05", "2011-10-28 06:35:59"))
result <- outer(rt, hours(0:10), "+")
But various parts in that pipeline break down. Ultimately I get this error:
Error in FUN(X[[1L]], ...) : invalid 'times' argument
which seems to come from rep.POSIXct()‘s or rep.period()‘s inability to handle a non-unit-length times argument. Or something.
And it probably wouldn’t have worked anyway, because outer() returns a matrix, and date objects, even POSIXct dates (which are internally just integers) it seems can’t be elements in a matrix.
What I figured out that worked (just to get the times, not to put them in a data frame), after about 10 other guesses, was this:
with_tz(do.call(c, lapply(rt, function(x) x+hours(0:3))), tz(rt[1]))
The with_tz() addition is necessary because c() loses the timezone attribute. I also have to do do.call(c, lapply(...)) rather than just sapply(...) because sapply() loses the fact that it’s a date.
Maybe another alternative would be to create a data frame by doing do.call(cbind, ...) or something.
In general, it would be great if, whenever we find R date/time tasks that seem conceptually easy but require a lot of gymnastics before finding a solution, we could remove the roadblocks by making changes to lubridate, or whatever. I’m thinking this might be one of those times. =)
This doesn’t use
outer(), but I think it gets you where you want. It does useplyr.Giving names to the
offsetsvariable just makes the column names of thedata.framenicer.UPDATE:
Ken’s comment about
ldply()versusdata.frame(llply())made me realize there is another way to approach this.which gives
Note that, in addition to different column names (V1-V11 rather than X0-X10), these dates have been converted to local time (PDT, in my case):