如何将data.table行插值函数改造为支持多输入行的向量式实现
解决多行data.table的年份插值问题
你遇到的问题核心在于原来的函数是针对单行数据设计的,没有考虑到分组处理——因为每一组(也就是每一对iso1和iso2)都需要独立生成自己的年份序列。其实用data.table自带的分组功能就能完美解决,不需要嵌套lapply或者Map,代码会更简洁高效。
修正后的函数
直接利用data.table的by参数按iso1和iso2分组,在每个组内生成从当前年份到stop_year的序列:
require('data.table') interpolate_rows <- function(dt, stop_year = 2008) { # 按iso1和iso2分组,每个组内生成年份序列 dt[, .(year = seq(year, stop_year)), by = .(iso1, iso2)] }
测试验证
用你的测试数据运行:
test_dt <- data.table(iso1 = c('BTN', 'IND', 'BGD'), iso2 = c('AFG', 'AFG', 'AFG'), year = c(2006, 2003, 2006)) bar <- interpolate_rows(test_dt) bar
输出结果完全符合你的预期:
iso1 iso2 year 1: BTN AFG 2006 2: BTN AFG 2007 3: BTN AFG 2008 4: IND AFG 2003 5: IND AFG 2004 6: IND AFG 2005 7: IND AFG 2006 8: IND AFG 2007 9: IND AFG 2008 10: BGD AFG 2006 11: BGD AFG 2007 12: BGD AFG 2008
为什么原来的代码不行?
你提到的year <- as.integer(dt[, .SD, .SDcols = 'year'])这一行,当输入是多行数据时,它会把所有年份变成一个向量,但后续的if (year < stop_year)判断是针对整个向量的,这在R里会触发向量逻辑判断的警告,而且后续的rep和赋值操作也不会按组处理,导致所有行都重复相同的次数,完全不符合需求。
而用by = .(iso1, iso2)分组后,data.table会自动对每个组单独执行seq(year, stop_year),每个组的年份序列都是独立生成的,完美适配多行场景。
内容的提问来源于stack exchange,提问作者FlobbyDsk
相关产品推荐
相关产品推荐

