R语言开发中如何检测函数参数是否为按位置而非名称调用
R包可选参数按位置传参检测实现问题
我正在维护一款以单个函数为核心的R包,该函数包含少量必填参数和大量可选参数。
随着函数迭代成熟,可选参数的顺序会发生调整,因此按位置传参会引发破坏性变更。
我希望当这些可选参数被按位置而非名称调用时,抛出警告或者错误(暂时未确定哪种更合适)。
以下是演示预期效果的伪代码:
crosstable = function(data, cols=NULL, ..., by=NULL, opt1=FALSE, opt2=FALSE, opt3=FALSE){ warn_if_unnamed(by) stop_if_unnamed(opt1) stop_if_unnamed(opt2) stop_if_unnamed(opt3) doStuff(data, cols, by, opt1, opt2, opt3) } crosstable(mtcars, c(cyl, am), by=vs, opt3=TRUE) # 正常运行 crosstable(mtcars, c(cyl, am), by=vs, TRUE) # 报错,因为未来`opt1`可能调整为`opt56` crosstable(mtcars, c(cyl, am), vs, opt2=TRUE) # 警告:`by`参数位置不会变动,但显式指定名称可读性更好
请问我该如何实现这一功能?
后续更新
我最终实现了该功能,但该实现配合管道使用时会失效:
warn_if_unnamed <- function(argname){ .call = sys.call(-1) f = get(as.character(.call[[1]]), mode="function", sys.frame(-2)) mc = names(as.list(match.call(definition=f, call=.call))) sc = names(as.list(.call)) if(argname %in% mc && !argname %in% sc){ warning(argname," 是按位置而非名称传入的") } } myfun = function(x, y=NULL, opt1=FALSE, opt2=FALSE, opt3=FALSE){ warn_if_unnamed("opt1") warn_if_unnamed("opt2") warn_if_unnamed("opt3") invisible() } myfun(1, 2) myfun(1, 2, T, opt2=1) #> Warning in warn_if_unnamed("opt1"): opt1 是按位置而非名称传入的 myfun(1, 2, opt1=T, 1, opt3) #> Warning in warn_if_unnamed("opt2"): opt2 是按位置而非名称传入的 #> Warning in warn_if_unnamed("opt3"): opt3 是按位置而非名称传入的 myfun(1, 2, opt2=T, 1, opt3) #> Warning in warn_if_unnamed("opt1"): opt1 是按位置而非名称传入的 #> Warning in warn_if_unnamed("opt1"): opt3 是按位置而非名称传入的
2021-10-20使用reprex包(v2.0.1)创建
后续我可能会重构代码,将多条警告合并为一条。
注:最后一行输出看起来是reprex()的bug。
内容的提问来源于stack exchange,提问作者Dan Chaltiel
相关产品推荐
相关产品推荐

