如何消除deparse(substitute())输出中的数据框名称?
解决deparse(substitute())输出中去除数据框名称的问题
这个问题其实不用正则表达式就能轻松解决,因为substitute()返回的是一个语言对象(不是字符串),我们可以直接拆解这个对象来提取需要的列名,完全不需要对字符串做替换操作。
基础解决方案(针对df$col场景)
我们可以修改函数,先获取传入参数的原始表达式结构,判断是否是数据框的$调用,然后直接提取列名部分:
foo <- function(x) { # 获取传入参数的原始表达式 expr <- substitute(x) # 判断是否是数据框$列的调用结构 if (is.call(expr) && identical(expr[[1]], quote(`$`))) { # 提取列名部分并转成字符串 var_name <- deparse(expr[[3]]) } else { # 其他情况保持原逻辑 var_name <- deparse(expr) } print(paste('This is called', var_name)) }
测试效果
- 传入向量时:
test <- 1:3 foo(test) # [1] "This is called test"
- 传入数据框列时:
df <- data.frame(ones=c(1,1,1), twos=c(2,2,2)) foo(df$ones) # [1] "This is called ones"
完美得到你想要的结果,完全避开了正则表达式的繁琐处理~
扩展解决方案(覆盖df[[col]]场景)
如果还需要处理df[[colname]]或df[[index]]这类调用,我们可以再扩展函数逻辑:
foo <- function(x) { expr <- substitute(x) var_name <- if (is.call(expr)) { if (identical(expr[[1]], quote(`$`))) { deparse(expr[[3]]) } else if (identical(expr[[1]], quote(`[[`))) { # 处理字符串列名的情况,直接取字符串值;数字索引则保留原表达式 if (is.character(expr[[3]])) { expr[[3]] } else { deparse(expr) } } else { deparse(expr) } } else { deparse(expr) } print(paste('This is called', var_name)) }
扩展测试
- 传入字符串索引的列:
foo(df[["ones"]]) # [1] "This is called ones"
- 传入数字索引的列:
foo(df[[1]]) # [1] "This is called df[[1]]"
这样就能覆盖更多常见的列引用场景啦。
内容的提问来源于stack exchange,提问作者Łukasz Deryło
相关产品推荐
相关产品推荐

