19

有没有一种巧妙的方法来连接 R 中的时间键值接近但不完全相同的数据表?例如,假设我有一个针对不同时间段给出的结果数据表:

DT1 = data.table(x=rep(c("a","b","c"),each=3), time=c(10,30,60), v=1:9)

在这里,我们有一些在不同时间(时间)获取的不同类别(x)的值(v)。现在假设我有来自另一个来源的数据,这些数据为不同类别提供了一些时间值:

DT2=data.table(x=rep(c("a","b","c"),each=1),time=c(10,10,60))

我可能有兴趣尝试将 DT2 中的时间尽可能与 DT1 匹配,以预测我的 DT2 类别的值 v。我想做类似的事情

setkeyv(DT2,c("x","time"))
merge(DT1,DT2,by=c("time","v")

返回:

   time x v
1:   10 a 1
2:   10 b 4
3:   60 c 9

但是,如果我的时间没有相同的精度怎么办?例如:

DT2=data.table(x=rep(c("a","b","c"),each=1),time=c(17,54,3))

有没有办法执行类似的合并,但 DT2 的选择时间接近 DT1 的时间?也就是说 17 接近 30,54 接近 60,3 接近 10?

如果这个简单的例子不清楚,我将简要解释我遇到的更大的问题。我有一个包含列的数据表:类别、时间、输出 1、输出 2...有数百个类别与相关时间。我可能想在特定时间为所有类别提取输出 1。由于时间的采样没有明显的逻辑,有时时间会四舍五入到最接近的偶数秒;在其他情况下,时间会四舍五入到最接近的分钟甚至 10 分钟。

我可以编写一个脚本以更常见的格式重写时间,但我很好奇是否有我没有见过的光滑的 data.table 解决方案。我探索了滚动合并,但没有成功。

4

2 回答 2

23

另一种选择可能是roll='nearest'(CRAN v1.8.8 中的新功能)。

> setkey(DT1,x,time)
> DT1
   x time v
1: a   10 1
2: a   30 2
3: a   60 3
4: b   10 4
5: b   30 5
6: b   60 6
7: c   10 7
8: c   30 8
9: c   60 9
> DT2
   x time
1: a   17
2: b   54
3: c    3
> DT1[DT2,roll="nearest"]
   x time v
1: a   17 1
2: b   54 6
3: c    3 7

请注意,17 似乎比 30 更接近 10,因此是第一行的结果。

如果您需要滚动到下一个观察值(下一个观察值向后进行):

> DT1[DT2,roll=-Inf]
   x time v
1: a   17 2
2: b   54 6
3: c    3 7
于 2013-03-30T23:05:51.363 回答
4

您可以使用findInterval来完成此操作:

setkey(DT2, time)
DT1[, id := findInterval(DT1$time, DT2$time)]
DT2[, id := 1:3]

setkey(DT1, "x", "id")
setkey(DT2, "x", "id")
print(DT1[DT2][, id := NULL])
#    x time v time.1
# 1: a   30 2     17
# 2: b   60 6     54
# 3: c   10 7      3

想法:首先按时间对 data.table 进行排序,因为 的第二个参数findInterval需要增加值的顺序。现在,使用来查找fall中的值在findInterval哪个区间并将其存储在. 在这种特殊情况下,它恰好介于 1 到 3 之间。因此,将这些值设置为. 一旦你找到了区间并得到,那就很简单了。而不是设置and ,设置and作为键并进行合并。3, 17, 54DT1$timeididDT2idxtimexid

注意:假设您DT1$time的值为 0,则该间隔将为 0。因此,您将获得 4 个唯一值 (0:3)。在这种情况下,最好将 DT2 也设置为 time = 0 值。我只是想在这里指出这一点。我会把它留给你。

于 2013-03-30T00:19:26.213 回答