在R的data.table中通过关联其他表的函数新增列失败求助
问题描述
我有一个data.table,想通过以下方式新增一列:
big_table[, ("new_column") := some_function(col1, col2, …)]
自定义函数some_function用于从另一个小表small_table中按条件匹配并提取动态列,单独调用这个函数时正常,但给big_table新增列时失败。
第一种写法报错:
Error in `big_table[, ("new_column") := some_function(col1 : Supplied 588 items to be assigned to 116588 items of column 'new_column'. If you wish to 'recycle' the RHS please use rep() to make this intent clear to readers of your code.
第二种写法报错:
Error in .subset2(x, i, exact = exact) : recursive indexing failed at level 2
推测是动态列查找导致的问题,请求修复。以下是简化示例:
# 参考表:code对应不同年龄段的数值 supplement <- data.table(code = c("male", "female"), child = c(1, 2), adult = c(3, 4)) # 主表:A列包含code前缀,B列是年龄段 DT <- data.table(A = c("male1", "male2", "male3", "female1", "female2"), B = c("child", "child", "adult", "adult", "child")) # 期望得到的结果 desired_result <- data.table(A = c("male1", "male2", "male3", "female1", "female2"), B = c("child", "child", "adult", "adult", "child"), sup = c("1", "1", "3", "4", "2"))
解决方案
方法1:转长表+连接(推荐,data.table原生高效写法)
核心思路是先把宽格式的supplement转成长格式,再和主表通过匹配字段连接,这是data.table最擅长的批量操作,效率远高于逐行处理:
library(data.table) # 将supplement转长表,统一匹配字段 supplement_long <- melt(supplement, id.vars = "code", variable.name = "B", value.name = "sup") # 从DT$A中提取code前缀(如"male1"提取为"male") DT[, code := sub("\\d+$", "", A)] # 按code和B列连接,批量赋值sup列 DT[supplement_long, sup := i.sup, on = .(code, B)] # 可选:删除临时生成的code列 DT[, code := NULL]
方法2:修复自定义函数(支持向量输入)
如果一定要用自定义函数,需让函数支持向量输入,避免因返回结果长度不匹配报错。可以用mapply或Vectorize实现逐元素处理:
# 定义处理单个元素的函数 get_sup <- function(a, b) { code <- sub("\\d+$", "", a) supplement[code == code, get(b)] } # 用mapply逐行调用函数赋值 DT[, sup := mapply(get_sup, A, B)] # 或者用Vectorize包装函数,直接向量调用 vec_get_sup <- Vectorize(get_sup) DT[, sup := vec_get_sup(A, B)]
方法3:逐行处理(适合理解,大表不推荐)
通过by = .I实现逐行运算,适合小表调试,大表性能不如连接方法:
DT[, sup := { code <- sub("\\d+$", "", A) supplement[code == code, get(B)] }, by = .I]
错误原因解析
- 第一个错误:自定义函数未处理向量输入,返回结果长度(588)远小于主表行数(116588),导致赋值时长度不匹配。
- 第二个错误:动态列查找(如
get(b))时,b是向量而非单个值,直接调用会触发递归索引失败。
内容的提问来源于stack exchange,提问作者scenario
相关产品推荐
相关产品推荐

