R语言用deparse、substitute提取省略号参数名兼容list传参
R语言获取省略号参数名兼容list传入的实现方法
问题背景
需要实现R函数中对省略号...传入参数名的正确提取,要求同时兼容两种传参模式:
- 参数直接作为省略号入参传入
- 参数被打包进
list()结构后整体传入
原有实现仅支持直接传参场景,代码如下:
foo <- function(...) { sapply(substitute(...()), deparse) }
直接传参时运行正常:
a <- 1:3 b <- 2:6 foo(a, b) # 运行结果: "a" "b"
传入打包为list的参数时无法正确拆分提取:
foo(list(a, b)) # 运行结果: "list(a, b)"
实现方案
核心逻辑是先捕获省略号传入的所有未求值表达式,判断每个顶层表达式是否为list()调用:如果是则拆开list结构,提取内部所有参数的表达式做文本解析;非list结构的参数直接做解析即可。
修改后的完整函数代码:
foo <- function(...) { # 捕获省略号中所有未求值的原始表达式,不做自动展开 dots <- match.call(expand.dots = FALSE)$`...` res <- character(0) for (expr in dots) { # 判断当前传入项是否为list调用 if (is.call(expr) && identical(expr[[1]], as.name("list"))) { # 跳过list本身的函数符号,提取内部所有参数做解析 inner_args <- as.list(expr)[-1] res <- c(res, vapply(inner_args, deparse, FUN.VALUE = character(1))) } else { # 普通直接传入的参数直接解析 res <- c(res, deparse(expr)) } } res }
效果验证
- 直接传参场景:
a <- 1:3 b <- 2:6 foo(a, b) # 返回: [1] "a" "b"
- list打包传参场景:
foo(list(a, b)) # 返回: [1] "a" "b"
- 混合传参场景同样兼容:
c <- 4:8 foo(a, list(b), c) # 返回: [1] "a" "b" "c"
若需要保留list内的命名参数属性,只需要在拼接结果时同步保留
inner_args的names属性即可,可根据实际业务需求调整。
内容的提问来源于stack exchange,提问作者stschn
相关产品推荐
相关产品推荐

