如何基于dt1的var1条件合并两个data.table?已尝试两种方法失败
问题:data.table条件合并仅保留var1=1时的匹配值
我想要合并两个data.table,仅当dt1中的var1等于1时才合并对应的值。示例数据如下:
library(data.table) # 示例数据表 dt1 <- data.table(id = 1:5, var1 = c(1, 0, 1, 0, 1), name1 = c("A", "B", "C", "D", "E")) dt2 <- data.table(name2 = c("A", "B", "C", "D", "E"), other_var = 101:105)
dt1输出:
id var1 name1 1: 1 1 A 2: 2 0 B 3: 3 1 C 4: 4 0 D 5: 5 1 E
dt2输出:
name2 other_var 1: A 101 2: B 102 3: C 103 4: D 104 5: E 105
期望合并后的结果为:
id var1 name1 other_var 1: 1 1 A 101 2: 2 0 B NA 3: 3 1 C 103 4: 4 0 D NA 5: 5 1 E 105
我尝试了以下两种写法,但均未成功:
dt1[var1 == 1][dt2, other_var := i.other_var, on = .(name1 = name2)]
和
dt1[dt2, on = .(name1 = name2), other_var := i.other_var, var1 == 1]
请问我哪里出错了?正确的做法是什么?
错误原因分析
- 第一种写法:
dt1[var1 == 1][dt2, ...]是先筛选出var1=1的子集,再和dt2合并赋值,但这个操作是在子集副本上修改,不会影响原dt1,所以原dt1的其他行不会生成NA,也无法保留原数据的完整性。 - 第二种写法:
dt1[dt2, ..., var1 == 1]里的条件var1 ==1放在了第三个参数位置,而data.table的x[i, j, by]语法中,第三个参数是分组参数,不是行筛选条件,因此这个条件不会生效,最终会给所有匹配行赋值,达不到只给var1=1的行赋值的目的。
正确解法
方法1:赋值时直接加条件判断
利用ifelse在赋值环节限定仅var1=1的行取匹配值,其余行设为NA:
dt1[dt2, on = .(name1 = name2), other_var := ifelse(var1 == 1, i.other_var, NA)]
方法2:先全量匹配再修正不符合条件的行
先完成全量合并,再将var1≠1的行的other_var设为NA:
dt1[dt2, on = .(name1 = name2), other_var := i.other_var] dt1[var1 != 1, other_var := NA]
方法3:仅对var1=1的行进行匹配赋值
直接定位到var1=1的行,再匹配dt2赋值,未被定位的行自动保留NA:
dt1[var1 == 1, other_var := dt2[.SD, on = .(name2 = name1), x.other_var]]
执行任意一种方法后,dt1都会得到期望的输出:
id var1 name1 other_var 1: 1 1 A 101 2: 2 0 B NA 3: 3 1 C 103 4: 4 0 D NA 5: 5 1 E 105
内容的提问来源于stack exchange,提问作者Juustomies6
相关产品推荐
相关产品推荐

