我有一个奇怪的问题,我知道我可以使用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
咒语。谢谢你的帮助!
答案 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
,并计算其均值。这应该返回一个值。