基于Effdt合并R data.table:事务表与域表合并技术问询
解决data.table按生效日期匹配部门名称的问题
我明白你要解决的是根据交易日期匹配对应生效的部门名称的问题——因为部门表dtDepartments里同一个部门代码有多个生效日期的名称,需要找到交易发生时(PaymentDT)最新的、已经生效的部门名称。下面是两种高效的data.table解决方案:
方法一:非等值连接+分组取最新记录
这种方法逻辑直观,适合理解匹配过程:
- 先准备数据(如果你的因子类型的
Department有匹配问题,可以先转成字符型):
library(data.table) dtDistributions <- data.table(PayeeName = c("Bob", "Tracy", "Tom"), Department = factor(c("H229000", "H135000", "H047800")), Amount = c(5, 34, 87), PaymentDT = as.Date(c("2016-01-01", "2015-01-01", "2015-01-01"))) dtDepartments <- data.table(Department = factor(c("H229000", "H229000", "H229000", "H135000", "H047800")), EffDT = as.Date(c("2019-01-01", "2012-01-01", "1901-01-01", "1901-01-01", "1901-01-01")), Descr = c("Final Name","Modified Name","Original Name","Payables","Postal")) # 可选:将因子类型的Department转为字符型,避免匹配时的因子水平问题 dtDistributions[, Department := as.character(Department)] dtDepartments[, Department := as.character(Department)]
- 执行非等值连接,筛选出所有生效日期早于/等于交易日期的部门记录,再分组取每个交易对应的最新生效记录:
result <- dtDistributions[dtDepartments, on = .(Department, PaymentDT >= EffDT), .(PayeeName, Department, PaymentDT = x.PaymentDT, Amount, EffDT, Descr), allow.cartesian = TRUE][ # 按交易主体和交易日期分组,取生效日期最晚的那条记录 , .SD[which.max(EffDT)], by = .(PayeeName, PaymentDT) ][ # 保留需要的列,并重命名部门名称列 , .(PayeeName, DepartmentName = Descr, PaymentDT, Amount) ]
方法二:滚动连接(更简洁高效)
data.table的滚动连接专门处理这种“找最近匹配值”的场景,代码更简洁:
- 先对部门表按
Department和EffDT排序(滚动连接依赖有序的键):
setorder(dtDepartments, Department, EffDT)
- 执行滚动连接,自动匹配每个交易日期对应的最新生效部门名称:
result <- dtDistributions[dtDepartments, on = .(Department, PaymentDT = EffDT), roll = TRUE, # 表示取不大于PaymentDT的最大EffDT对应的记录 .(PayeeName, DepartmentName = Descr, PaymentDT = x.PaymentDT, Amount)]
最终结果
两种方法都会得到你需要的数据集:
PayeeName DepartmentName PaymentDT Amount 1: Bob Modified Name 2016-01-01 5 2: Tracy Payables 2015-01-01 34 3: Tom Postal 2015-01-01 87
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

