Data.table:过滤表上的更新连接未生效问题求助
data.table子集连接更新未生效的问题
问题场景
现有两个data.table对象dat_a和dat_b,二者拥有相同的postcode列,需要将dat_a中values为NaN的对应值替换为dat_b中的值,但不修改其他行。
示例数据:
dat_a <- data.table(postcode = LETTERS[1:10], values = c(1:8, NaN, 10)) dat_b <- data.table(postcode = LETTERS[1:10], values = c(990:999))
执行以下代码后,原表dat_a完全没有变化:
dat_a[is.nan(values) ][dat_b, values := i.values, on = .(postcode)]
但在代码末尾加[]后,会显示修改后的子集副本:
dat_a[is.nan(values) ][dat_b, values := i.values, on = .(postcode)][] # 输出结果: # postcode values # 1: I 998
问题原因
data.table的链式调用[...][...]中,第一个[is.nan(values)]返回的是原表的子集副本,后续的:=修改的是这个临时副本而非原表dat_a,因此原表不会发生变化。
解决方法
方法1:直接在原表的子集上进行连接更新
通过过滤出dat_a中需要修改的行,再与dat_b连接获取对应值,直接修改原表:
dat_a[is.nan(values), values := dat_b[.SD, i.values, on = .(postcode)]]
.SD代表当前过滤后的子集,通过on = .(postcode)与dat_b匹配,提取dat_b的values(即i.values)进行替换。
方法2:全表连接后按条件替换
通过全表连接,仅对符合条件的行进行值替换,其他行保持原值:
dat_a[dat_b, values := ifelse(is.nan(values), i.values, values), on = .(postcode)]
多条件场景适配
针对实际场景中需要多条件过滤的情况(如postcode == "I" & age == 23 & qualification == "bachelors"),只需将条件加入过滤逻辑即可,无需提前过滤dat_b:
# 假设dat_a和dat_b包含age、qualification列 dat_a[is.nan(values) & postcode == "I" & age == 23 & qualification == "bachelors", values := dat_b[.SD, i.values, on = .(postcode, age, qualification)]]
内容的提问来源于stack exchange,提问作者Maharero
相关产品推荐
相关产品推荐

