R语言data.table中...参数求值上下文错误问题求解
自定义多参数拼接函数在data.table中上下文求值异常问题
问题背景
我正在编写一个用于拼接参数的函数,规则为:若参数求值过程中触发错误则返回空字符串。
首先实现的双参数版本逻辑非常简单,运行符合预期:
paste_clean_ab <- function(a,b){ a <- tryCatch(a, error = function(cond) {warning(cond); return(NULL);}) b <- tryCatch(b, error = function(cond) {warning(cond); return(NULL);}) if (is.null(a) | is.null(b)) return(''); return(paste0(a,b)) }
双参数版本测试效果
paste_clean_ab('A', 'B') # "AB" var1='VAR1' paste_clean_ab('A=', var1) # "A=VAR1" paste_clean_ab('A ', non_existing_variable) # "" # Warning message: # In doTryCatch(return(expr), name, parentenv, handler) : # object 'non_existing_variable' not found # 支持向量化运算 paste_clean_ab(letters[1:5], var1) # "aVAR1" "bVAR1" "cVAR1" "dVAR1" "eVAR1"
该双参数版本在data.table环境中也可以正常运行:
require(data.table) data(iris) dt.iris <- data.table(iris) dt.iris[,Label1:=paste_clean_ab('Species: ',as.character(Species))] dt.iris[,Label2:=paste_clean_ab('Species: ',non_existing_variable)] # Warning message: # In doTryCatch(return(expr), name, parentenv, handler) : # object 'non_existing_variable' not found
多参数版本实现与存在的问题
我尝试将函数扩展为支持任意数量参数的版本,当前实现代码如下:
paste_clean <- function(...){ arglistS <- as.list(substitute(list(...))) ret <- '' for (arg in arglistS){ argVal <- tryCatch(eval(arg), error = function(cond) {warning(cond); return(NULL);}) # 跳过解析list(...)得到的第一个元素 if (isTRUE(attr(argVal, 'class')=='result') & class(arg)=='name') next; # R 4.1版本适配 if (identical(argVal, .Primitive('list'))) next; # R 4.2+版本适配 if (is.null(argVal)) return('') ret <- paste0(ret,argVal); } return(ret) }
该版本在调用全局环境普通变量时运行正常:
paste_clean('A','B','C') # "ABC" var1='VAR1' var2='VAR2' paste_clean('A=',var1, '; B=',var2) # "A=VAR1; B=VAR2" paste_clean('A=',non_existing_variable,var2) # "" # Warning message: # In eval(arg) : object 'non_existing_variable' not found dt.iris[,Label3:=paste_clean('var1: ',var1)] # 输出列值为"var1: VAR1"
但该版本无法正确识别data.table中的列,执行如下代码时会触发找不到对象的错误:
dt.iris[,Label4:=paste_clean('Species: ', Species)] # Warning message: # In eval(arg) : object 'Species' not found
待解决问题
需要如何修改tryCatch()相关的求值逻辑,才能让传入的参数在正确的上下文环境(比如data.table的计算环境)中完成求值?
内容的提问来源于stack exchange,提问作者Vasily A
相关产品推荐
相关产品推荐

