我正在尝试更新data.table的特定条目。我的i子集是另一个data.table。当我尝试传递:=命令一个与子集长度相同的向量时,我收到一个警告。我可以通过循环来解决这个问题,但我认为有更好的方法。此代码复制了我的结果:
DT <- data.table(ID = 1:10,V = rnorm(10))
setkey(DT,ID)
DT.alt <- DT[ID < 5,] ##Create a data.table with a subset of the observations
setkey(DT.alt,ID)
DT[,V:=rnorm(10)] ## Works
DT[DT.alt,V:=rnorm(1)] ## Works
DT[DT.alt,V:=rnorm(4)] ## Warning and the first element is used for all rows
请注意,这有效,但我真的需要循环吗?
for(i in 1:dim(DT.alt)[1]) DT[DT.alt[i,],V:=rnorm(1)]
我认为我做错了什么,感谢任何帮助。
答案 0 :(得分:4)
在data.table
版本&lt; = 1.9.2中,join
形式的x[i, j=...]
- 也就是说,也使用了j
的联接被设计为通过(或)by-without-by
操作隐式的。换句话说,这将为j
中的每个值计算i
。所以它不会像你想要的那样工作。
此设计选择已在current development version 1.9.3中更改(在某些时候将其推送到CRAN版本1.9.4),以保持一致性,在很多用户的反馈之后。您可以查看讨论here,here和功能请求(FR)here。
所以在1.9.3
中,这将按预期工作(如@BenBarnes指出的那样)。也就是说,默认情况下,x[i, j=...]
将首先执行join
和评估j
一次,而不是为每个j
获取i
。如果您不喜欢旧行为,则必须明确说明by
,如下所示:
## v 1.9.3
## performs the join and then calculates/evaluates j
x[i, j]
## explicitly state by to obtain j for each i
x[i, j, by=.EACHI]
当此版本命中CRAN时,还应该有一个使用旧版本的规定(以便现有代码不会中断),并警告此功能将在下一个版本中弃用(或类似那个 - 如何做到这一点尚未最终确定。)
总而言之,您的代码将按照预期的>= 1.9.3
版本运行。
请注意,
.EACHI
中尚未记录?data.table
功能。这仍然是一个开发版本。当它被发布到CRAN时,您可以在.EACHI
中找到?data.table
的文档,其中包含所有其他特殊变量,例如.I
,.N
,{{ 1}},.GRP
等也有记录。
HTH
编辑:如果您使用.BY
有效地执行此操作,那么您可以首先找到匹配的索引,如下所示:
<= 1.9.2