用于滚动统计的数据滚动子集

时间:2015-08-20 23:26:39

标签: r data.table

我有一个奇怪的问题,我知道我可以使用apply或其他一些循环结构解决但我觉得应该有一个非常聪明的方法来做到这一点。我有一个data.table example_dt,我从中提取2个id列,形成一个名为id_dt的id data.table。然后,我想使用这些id来索引example_dt来计算一些统计信息。诀窍是第一个id id1需要匹配。第二个ID id2只需要在一定范围内。我重命名id_dt中的列以避免命名冲突。我不完全确定data.table

中的范围界限是怎么回事
library(data.table)
example_dt <- data.table( id1 = c(rep('a', 7), rep('b', 7)), id2 = c(1:7, 1:7), x1 = c(rep(1:2,7)))
id_dt <- example_dt[,.(id1, id2)]
setnames(id_dt, names(id_dt), c('id1_idx','id2_idx') )
result_dt <- id_dt[,example_dt[id1 == id1_idx & id2 <= id2_idx & id2 >= id2_idx - 2, mean(x1)]]

我得到的只是1.5

的单一值
> result_dt
[1] 1.5

我想要的是:

id1 id2 x1  mean
a   1   1   1
a   2   2   1.5
a   3   1   1.333333333
a   4   2   1.666666667
a   5   1   1.333333333
a   6   2   1.666666667
a   7   1   1.333333333
b   1   2   2
b   2   1   1.5
b   3   2   1.666666667
b   4   1   1.333333333
b   5   2   1.666666667
b   6   1   1.333333333
b   7   2   1.666666667

就像我说的,我知道我可以用apply或其他一些循环结构来做。我想知道是否有一些我不知道的聪明data.table咒语。谢谢你的帮助!

1 个答案:

答案 0 :(得分:4)

这是使用rolling joins的一种方式:

setkey(example_dt, id1, id2)
idx1 = example_dt[.(id1, id2-2), roll=-Inf, which=TRUE]
idx2 = example_dt[.(id1, id2), roll=Inf, which=TRUE]

mapply(function(x,y) mean(example_dt$x1[x:y]), idx1, idx2)
#  [1] 1.000000 1.500000 1.333333 1.666667 1.333333 1.666667 1.333333 2.000000 1.500000
# [10] 1.666667 1.333333 1.666667 1.333333 1.666667

也可以使用foverlaps()来完成,但这似乎有点过分。我建议您在?data.table参数处查看roll并在那里处理示例,如果您无法控制此...(直到联接的插图已完成)。对于其他插图,请查看Getting started页面。对于计划的小插图,请查看this post

这已经出现了很多次,可能值得在between()data.table能够执行此功能(有效)。我认为项目页面上有一个FR。

至于为什么你得到一个值,你正在做DT[rows, mean(col)],它为col中指定的行读取.. extract rows,并计算其均值。这应该返回一个值。