如何检测R语言调用函数中缺失的指定参数?
问题分析与解决方案
1. 最初实现不符合预期的原因
你最初的find_missing_args用rlang::enquos(...)捕获参数,再用rlang::is_missing检查。但is_missing判断的是捕获到的quosure对象本身是否缺失,而非上层函数调用时对应的参数是否未传入。即使上层函数没传z,enquos仍能捕获到符号z对应的quosure(并非缺失对象),所以返回FALSE。
2. 更新实现报错的原因
当你的func包含参数c时,在func内部调用c("x","y","z")会触发歧义:R的作用域规则中,函数参数的优先级高于全局环境的内置函数,因此c会被解析为func的参数c(而非base::c函数),而这个参数未被传入,所以报错。
3. 正确实现方案
推荐用传递符号而非字符串向量的方式,既避免函数名冲突,又能精准检测指定参数:
library(rlang) find_missing_args <- function(...) { # 提取要检测的参数的符号名称 check_args <- ensyms(...) |> lapply(as.character) |> unlist() # 获取上层函数的调用参数名 caller_call <- caller_call(n = 1) supplied_args <- call_args_names(caller_call) # 返回未被传入的参数 setdiff(check_args, supplied_args) } # 测试用例1:参数不含c func1 <- function(x, y, z, a, b, d) { find_missing_args(x, y, z) } func1(x = 1, y = 2) # 输出:[1] "z" # 测试用例2:参数含c(无报错) func2 <- function(x, y, z, a, b, c) { find_missing_args(x, y, z) } func2(x = 1, y = 2) # 输出:[1] "z"
如果坚持要传递参数名字符串,需明确指定base::c来避免歧义:
find_missing_args <- function(args) { supplied <- rlang::call_args_names(rlang::caller_call(n = 1)) setdiff(args, supplied) } func3 <- function(x, y, z, a, b, c) { find_missing_args(base::c("x","y","z")) } func3(x = 1, y = 2) # 输出:[1] "z"
内容的提问来源于stack exchange,提问作者Dylan Russell
相关产品推荐
相关产品推荐

