R自定义函数作用于data.table列时结果异常且报长度警告如何解决
问题根源
你编写的my.fun是标量函数,仅支持输入单个数值:
- 函数内
while循环的判断条件、if分支判断逻辑都默认输入是长度为1的数值 - 你调用
lapply(.SD, my.fun)时,传入的是V1/V2整列(长度>1的向量),导致条件判断接收多值,触发「条件长度大于1,仅第一个元素会被使用」的警告,仅第一个元素的逻辑生效,最终结果异常。
仅有1行的DT2能正常运行,就是因为传入的列长度为1,刚好匹配标量函数的输入要求。
解决方案
两种方案都可以解决问题,运行后所有表的输出结果都会和列表测试结果一致,警告也会消失。
方案1:无需修改原函数,调用时逐元素处理
调整data.table的赋值语法,对列的每个元素单独调用my.fun:
DT1[, (newcols) := lapply(.SD, function(col) sapply(col, my.fun)), .SDcols = cols] DT2[, (newcols) := lapply(.SD, function(col) sapply(col, my.fun)), .SDcols = cols] DT3[, (newcols) := lapply(.SD, function(col) sapply(col, my.fun)), .SDcols = cols]
方案2:将原函数改造为向量友好型
用Vectorize直接包装原函数,让它原生支持向量输入:
# 包装为向量化函数 my.fun_vec <- Vectorize(my.fun) # 直接调用即可 DT1[, (newcols) := lapply(.SD, my.fun_vec), .SDcols = cols] DT2[, (newcols) := lapply(.SD, my.fun_vec), .SDcols = cols] DT3[, (newcols) := lapply(.SD, my.fun_vec), .SDcols = cols]
内容的提问来源于stack exchange,提问作者Discus23
相关产品推荐
相关产品推荐

