如何在R的data.table中基于当前行条件创建关联筛选列
基于data.table中其他行的条件匹配创建新列
我有一个规模较大的data.table,想要创建一个新列b_m1,根据当前行的a_m1值,匹配表中其他行的a列,获取对应的b值。示例数据如下:
library(data.table) dt<-data.table(a=seq.Date(as.Date("2023-11-01"), as.Date("2023-11-30"), by="day"), b=c(1:27, 46, 34, 101)) dt$a_m1<-c(seq.Date(as.Date("2023-11-16"), as.Date("2023-11-30"), by="day"), seq.Date(as.Date("2023-11-01"), as.Date("2023-11-15"), by="day"))
生成的data.table内容:
a b a_m1 1: 2023-11-01 1 2023-11-16 2: 2023-11-02 2 2023-11-17 3: 2023-11-03 3 2023-11-18 4: 2023-11-04 4 2023-11-19 5: 2023-11-05 5 2023-11-20 6: 2023-11-06 6 2023-11-21 7: 2023-11-07 7 2023-11-22 8: 2023-11-08 8 2023-11-23 9: 2023-11-09 9 2023-11-24 10: 2023-11-10 10 2023-11-25 11: 2023-11-11 11 2023-11-26 12: 2023-11-12 12 2023-11-27 13: 2023-11-13 13 2023-11-28 14: 2023-11-14 14 2023-11-29 15: 2023-11-15 15 2023-11-30 16: 2023-11-16 16 2023-11-01 17: 2023-11-17 17 2023-11-02 18: 2023-11-18 18 2023-11-03 19: 2023-11-19 19 2023-11-04 20: 2023-11-20 20 2023-11-05 21: 2023-11-21 21 2023-11-06 22: 2023-11-22 22 2023-11-07 23: 2023-11-23 23 2023-11-08 24: 2023-11-24 24 2023-11-09 25: 2023-11-25 25 2023-11-10 26: 2023-11-26 26 2023-11-11 27: 2023-11-27 27 2023-11-12 28: 2023-11-28 46 2023-11-13 29: 2023-11-29 34 2023-11-14 30: 2023-11-30 101 2023-11-15
期望输出(新增b_m1列,对应a_m1匹配a后的b值):
a b a_m1 b_m1 1: 2023-11-01 1 2023-11-16 16 2: 2023-11-02 2 2023-11-17 17 3: 2023-11-03 3 2023-11-18 18 4: 2023-11-04 4 2023-11-19 19 5: 2023-11-05 5 2023-11-20 20 6: 2023-11-06 6 2023-11-21 21 7: 2023-11-07 7 2023-11-22 22 8: 2023-11-08 8 2023-11-23 23 9: 2023-11-09 9 2023-11-24 24 10: 2023-11-10 10 2023-11-25 25 11: 2023-11-11 11 2023-11-26 26 12: 2023-11-12 12 2023-11-27 27 13: 2023-11-13 13 2023-11-28 46 14: 2023-11-14 14 2023-11-29 34 15: 2023-11-15 15 2023-11-30 101 16: 2023-11-16 16 2023-11-01 1 17: 2023-11-17 17 2023-11-02 2 18: 2023-11-18 18 2023-11-03 3 19: 2023-11-19 19 2023-11-04 4 20: 2023-11-20 20 2023-11-05 5 21: 2023-11-21 21 2023-11-06 6 22: 2023-11-22 22 2023-11-07 7 23: 2023-11-23 23 2023-11-08 8 24: 2023-11-24 24 2023-11-09 9 25: 2023-11-25 25 2023-11-10 10 26: 2023-11-26 26 2023-11-11 11 27: 2023-11-27 27 2023-11-12 12 28: 2023-11-28 46 2023-11-13 13 29: 2023-11-29 34 2023-11-14 14 30: 2023-11-30 101 2023-11-15 15
我尝试了以下代码但未得到预期结果:
dt[,b_m1:=dt[a_m1==dt$a]$b,]
解决方案
问题分析
你原有代码的问题在于,dt[a_m1==dt$a]是对整个向量做逐元素比较,返回所有匹配的行,无法实现按当前行a_m1匹配对应a行的映射逻辑,且这种写法效率极低,不适用于大规模数据集。
方法1:data.table内连接(高效推荐)
data.table的连接操作是处理这类映射问题的最优方案,针对大规模数据会做键优化,速度远优于逐行匹配:
# 在原表上直接完成连接更新 dt[dt, on = .(a_m1 = a), b_m1 := i.b]
方法2:使用match函数
如果是简单的一对一映射,也可以用match定位a_m1在a列中的位置,再提取对应b值:
dt[, b_m1 := b[match(a_m1, a)]]
两种方法都能得到预期结果,其中连接方式更适合大规模数据场景。
内容的提问来源于stack exchange,提问作者user3466328
相关产品推荐
相关产品推荐

