基于lookup表匹配键并插值填充data.table新列的高效实现
高效实现大规模data.table分组插值填充新列
需求说明
在R语言中处理超大规模data.table,该表包含若干键列;另有一个lookup表,包含相同键列及额外变量。需要基于相同键值从lookup表中选取子集,通过公共变量插值为原data.table填充新列。
简化示例
library(data.table) data <- data.table(A = c("A","A","A","B","B","B","C","C","C"), B = c(1,1,1,1,1,1,2,2,2), C = rep(c(0.15, 0.22, 0.3),3)) data # A B C # 1: A 1 0.15 # 2: A 1 0.22 # 3: A 1 0.30 # 4: B 1 0.15 # 5: B 1 0.22 # 6: B 1 0.30 # 7: C 2 0.15 # 8: C 2 0.22 # 9: C 2 0.30 look <- data.table(A = c("A","A","A","B","B","B","C","C","C"), B = c(1,1,1,1,1,1,2,2,2), C = rep(c(0.1, 0.2, 0.3),3), D = c(10, 20, 30, 11,22,33,12,24,36)) look # A B C D # 1: A 1 0.1 10 # 2: A 1 0.2 20 # 3: A 1 0.3 30 # 4: B 1 0.1 11 # 5: B 1 0.2 22 # 6: B 1 0.3 33 # 7: C 2 0.1 12 # 8: C 2 0.2 24 # 9: C 2 0.3 36
具体需求:匹配A、B列后,利用look$C和look$D,基于data$C插值生成data$D新列。
当前低效实现
采用for循环,针对每个A、B匹配组合从look中提取子集,生成插值函数后填充数据:
f <- approxfun(c(0.1, 0.2, 0.3), c(10, 20, 30) ) f(c(0.15, 0.22, 0.3)) ## 处理后data.table如下 data # A B C D # 1: A 1 0.15 15 # 2: A 1 0.22 22 # 3: A 1 0.30 30 # 4: B 1 0.15 # 5: B 1 0.22 # 6: B 1 0.30 # 7: C 2 0.15 # 8: C 2 0.22 # 9: C 2 0.30
但实际数据规模为nrow(DATA) > 6000000,nrow(look) > 20000,且需填充3个新列,当前循环已运行超一天,急需更高效的实现方案。尝试过data.table或dplyr优化,但未找到合适方法。
背景说明
在该研究领域,通常会将观测数据与参考模拟值结合使用。可为每个观测值或某一范围值运行模型,观测数据与模型间部分公共变量可能完全匹配,或需从模拟值中插值获取近似值。
本次处理的是30年分辨率为1分钟的数据集,有效观测数据超600万条;当前模拟值为月气候态数据,超27000条,未来模拟值规模会更大、时间步长更精细,匹配与插值将成为分析的主要瓶颈。
解决方案反馈
@thothal提供的方法与原迭代方法结果完全一致,执行时间从约2小时缩短至数秒;dplyr方法未得到预期结果,可能因数据复杂或实现有误。感谢所有建议,为这类问题提供了实用思路。
内容的提问来源于stack exchange,提问作者ThanasisN
相关产品推荐
相关产品推荐

