带有日期的外部产品

时间:2011-11-03 18:45:46

标签: r outer-join lubridate

给定日期时间值的向量,我需要在每个原始日期时间data.frame小时创建包含日期时间的0:10 - 过去0小时的第一列,过去1小时后的第二列等。

我很难找到使用lubridate内容轻松完成此操作的方法。我认为这应该有效:

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), "+")

但该管道中的各个部分都崩溃了。最终我收到了这个错误:

Error in FUN(X[[1L]], ...) : invalid 'times' argument

似乎来自rep.POSIXct()rep.period()无法处理非单位长度的times参数。或者其他什么。

它可能无论如何都不会起作用,因为outer()返回一个矩阵,而日期对象,甚至POSIXct日期(内部只是整数)似乎不能是矩阵中的元素。

在我做了大约10次其他猜测之后,我发现有效(只是为了得到时间,而不是把它们放在数据框中)是这样的:

with_tz(do.call(c, lapply(rt, function(x) x+hours(0:3))), tz(rt[1]))

with_tz()添加是必要的,因为c()会丢失时区属性。我还必须do.call(c, lapply(...))而不仅仅是sapply(...),因为sapply()失去了这是约会的事实。

也许另一种选择是通过do.call(cbind, ...)或其他东西来创建数据框。

一般情况下,如果我们发现R日期/时间任务在概念上很容易但在找到解决方案之前需要大量体操,那么我们可以通过对lubridate进行更改来消除障碍,管他呢。我想这可能是那个时代之一。 =)

1 个答案:

答案 0 :(得分:4)

这不使用outer(),但我认为它可以让你到达目的地。它确实使用了plyr

library("lubridate")
library("plyr")

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"))

offsets = 0:10
names(offsets) <- offsets

dat <- data.frame(llply(offsets, function(offset){rt+hours(offset)}))

offsets变量命名只会使data.frame的列名变得更好。

> str(dat)
'data.frame':   5 obs. of  11 variables:
 $ X0 : POSIXct, format: "2011-11-03 19:24:12" "2011-10-28 20:48:21" ...
 $ X1 : POSIXct, format: "2011-11-03 20:24:12" "2011-10-28 21:48:21" ...
 $ X2 : POSIXct, format: "2011-11-03 21:24:12" "2011-10-28 22:48:21" ...
 $ X3 : POSIXct, format: "2011-11-03 22:24:12" "2011-10-28 23:48:21" ...
 $ X4 : POSIXct, format: "2011-11-03 23:24:12" "2011-10-29 00:48:21" ...
 $ X5 : POSIXct, format: "2011-11-04 00:24:12" "2011-10-29 01:48:21" ...
 $ X6 : POSIXct, format: "2011-11-04 01:24:12" "2011-10-29 02:48:21" ...
 $ X7 : POSIXct, format: "2011-11-04 02:24:12" "2011-10-29 03:48:21" ...
 $ X8 : POSIXct, format: "2011-11-04 03:24:12" "2011-10-29 04:48:21" ...
 $ X9 : POSIXct, format: "2011-11-04 04:24:12" "2011-10-29 05:48:21" ...
 $ X10: POSIXct, format: "2011-11-04 05:24:12" "2011-10-29 06:48:21" ...

更新:

Ken对ldply()data.frame(llply())的评论让我意识到还有另一种方法可以解决这个问题。

dat <- ldply(rt, `+`, hours(0:10))

给出了

> str(dat)
'data.frame':   5 obs. of  11 variables:
 $ V1 : POSIXct, format: "2011-11-03 12:24:12" "2011-10-28 13:48:21" ...
 $ V2 : POSIXct, format: "2011-11-03 13:24:12" "2011-10-28 14:48:21" ...
 $ V3 : POSIXct, format: "2011-11-03 14:24:12" "2011-10-28 15:48:21" ...
 $ V4 : POSIXct, format: "2011-11-03 15:24:12" "2011-10-28 16:48:21" ...
 $ V5 : POSIXct, format: "2011-11-03 16:24:12" "2011-10-28 17:48:21" ...
 $ V6 : POSIXct, format: "2011-11-03 17:24:12" "2011-10-28 18:48:21" ...
 $ V7 : POSIXct, format: "2011-11-03 18:24:12" "2011-10-28 19:48:21" ...
 $ V8 : POSIXct, format: "2011-11-03 19:24:12" "2011-10-28 20:48:21" ...
 $ V9 : POSIXct, format: "2011-11-03 20:24:12" "2011-10-28 21:48:21" ...
 $ V10: POSIXct, format: "2011-11-03 21:24:12" "2011-10-28 22:48:21" ...
 $ V11: POSIXct, format: "2011-11-03 22:24:12" "2011-10-28 23:48:21" ...

请注意,除了不同的列名(V1-V11而不是X0-X10)之外,这些日期已经转换为本地时间(在我的情况下是PDT):

> dat$V1
[1] "2011-11-03 12:24:12 PDT" "2011-10-28 13:48:21 PDT"
[3] "2011-11-04 03:06:14 PDT" "2011-10-31 10:10:05 PDT"
[5] "2011-10-27 23:35:59 PDT"