You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:15:04