我正在处理一个有数百万行的数据表。它有一个非唯一键。一个特定的列(比如v1)具有几行的NA。当v1具有NA时,我需要更新此列(v1)和另一列(v2)。更新这些列的值来自另一个数据表。以下代码模拟数据集:
set.seed(1)
DT1<-data.table(
id1=c(rep(1, 3), rep(2, 3)),
id2=c("a", "e", "n", "e", "e", "c"),
v1=c(rnorm(1), rep(NA,2), rnorm(1), NA, rnorm(1)),
v2=rnorm(6))
setkey(DT1, id2)
DT2<-data.table(id2=c("n","u", "e"), v1=c(1, 2, 3), v2=c(11, 22, 33))
setkey(DT2, id2)
DT1; DT2
更新后,DT1将显示为:
> DT1
id1 id2 v1 v2
1: 1 a -0.6264538 1.5952808
2: 2 c -0.8356286 0.5757814
3: 1 e 3 33
4: 2 e 0.1836433 0.4874291
5: 2 e 3 33
6: 1 n 1 11
请注意,第4行未更新,因为v1具有值。
我尝试了以下代码,但它更新了所有匹配的行(包括第4行)
DT1[DT2[unique(DT1[is.na(v1), id2]),nomatch=0], c("v1","v2"):=list(i.v1,i.v2)]
如果我提供上述代码的过滤器(如下所示),DT1保持不变。
DT1[is.na(v1)][DT2[unique(DT1[is.na(v1), id2]),nomatch=0], c("v1","v2"):=list(i.v1,i.v2)]
我做错了什么?
为这样的问题编写R / data.table代码会有什么更优雅的方法?
请帮忙。
答案 0 :(得分:3)
这是一种可能性:
DT1[is.na(v1), c("v1", "v2") := DT2[.SD[["id2"]], list(v1, v2)]]
# id1 id2 v1 v2
#1: 1 a -0.6264538 1.5952808
#2: 2 c -0.8356286 0.5757814
#3: 1 e 3.0000000 33.0000000
#4: 2 e 0.1836433 0.4874291
#5: 2 e 3.0000000 33.0000000
#6: 1 n 1.0000000 11.0000000