使用data.table 1.9.3更新基于连接的data.table子集不再起作用

时间:2014-04-25 09:47:26

标签: r data.table

我很抱歉提出一个新问题,但我不允许发表评论,并且回复的帖子已被删除。

尝试从Update subset of data.table based on join重现示例,使用R 3.1.0下的1.9.3给出了不同的结果(不是预期的)。我知道1.9.3是不稳定的,但由于其他问题,1.9.2对我不起作用 - 见http://r.789695.n4.nabble.com/Change-in-list-behavior-inside-join-td4687469.html

  

来自dnlbrky here

的引文

我有两个数据表,DT1和DT2:

set.seed(1)
DT1<-data.table(id1=rep(1:3,2),id2=sample(letters,6), v1=rnorm(6), key="id2")
DT1
##    id1 id2         v1
## 1:   2   e  0.7383247
## 2:   1   g  1.5952808
## 3:   2   j  0.3295078
## 4:   3   n -0.8204684
## 5:   3   s  0.5757814
## 6:   1   u  0.4874291

DT2<-data.table(id2=c("n","u"), v1=0, key="id2")
DT2
##    id2 v1
## 1:   n  0
## 2:   u  0

我想基于与DT2的连接更新DT1,但仅针对DT1的子集。例如,对于DT1 [id1 == 3],我希望第4行中的v1值可以更新,如下所示:

DT1
##    id1 id2         v1
## 1:   2   e  0.7383247
## 2:   1   g  1.5952808
## 3:   2   j  0.3295078
## 4:   3   n          0
## 5:   3   s  0.5757814
## 6:   1   u  0.4874291

我知道如何更新表(使用:=赋值运算符),如何连接表(DT1 [DT2])以及如何对表进行子集(DT1 [id1 == 3])。但是我不确定如何一次完成这三个。

编辑:请注意,原始示例仅尝试更新一列,但我的实际数据需要更新许多列。考虑DT1b和DT2b中的其他方案:

set.seed(2)
DT1b<-DT1[,v2:=rnorm(6)] # Copy DT1 and add a new column
setkey(DT1b,id2)
DT1b
##    id1 id2         v1          v2
## 1:   2   e  0.7383247 -0.89691455
## 2:   1   g  1.5952808  0.18484918
## 3:   2   j  0.3295078  1.58784533
## 4:   3   n -0.8204684 -1.13037567
## 5:   3   s  0.5757814 -0.08025176
## 6:   1   u  0.4874291  0.13242028

DT2b<-rbindlist(list(DT2,data.table(id2="e",v1=0))) # Copy DT2 and add a new row
DT2b[,v2:=-1] # Add a new column to DT2b
setkey(DT2b,id2)
DT2b
##    id2 v1 v2
## 1:   e  0 -1
## 2:   n  0 -1
## 3:   u  0 -1

根据@nmel和@BlueMagister的有用答案,我想出了更新方案的解决方案:

DT1b[DT2b[DT1b[id1 %in% c(1,2)],nomatch=0],c("v1","v2"):=list(i.v1,i.v2)]
DT1b
##    id1 id2         v1          v2
## 1:   2   e  0.0000000 -1.00000000
## 2:   1   g  1.5952808  0.18484918
## 3:   2   j  0.3295078  1.58784533
## 4:   3   n -0.8204684 -1.13037567
## 5:   3   s  0.5757814 -0.08025176
## 6:   1   u  0.0000000 -1.00000000
  

结束引用

这可以使用data.table 1.8.10重现,但是它不再使用data.table 1.9.3 @ R 3.1.0。结果是:

DT1b[DT2b[DT1b[id1 %in% c(1,2)],nomatch=0],c("v1","v2"):=list(i.v1,i.v2)]
DT1b
    id1 id2         v1          v2
## 1:   2   e  0.7383247 -0.89691455
## 2:   1   g  1.5952808  0.18484918
## 3:   2   j  0.3295078  1.58784533
## 4:   3   n -0.8204684 -1.13037567
## 5:   3   s  0.5757814 -0.08025176
## 6:   1   u  0.4874291  0.13242028

由于

DT1b[DT2b[DT1b[id1 %in% c(1,2)],nomatch=0], list(i.v1)]
##   id1 id2        v1         v2 i.v1 i.v2 i.id1      i.v1       i.v2
## 1:   2   e 0.7383247 -0.8969145    0   -1     2 0.7383247 -0.8969145
## 2:   1   u 0.4874291  0.1324203    0   -1     1 0.4874291  0.1324203 

有人有建议,如何解决?

nachti

编辑:

如果我修复了由1.9.3引起的代码(参见@arun),那么它不再适用于1.8.11。这是一个问题,因为它是在一个包中使用不同版本的R和data.table的函数中实现的。 1.9.3中默认值的更改破坏了现有代码,但不应该这样(参见.DT FAQ 1.8)。如果代码可以使用不同版本的DT,那就没问题了。

0 个答案:

没有答案