You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

R语言中如何隐式传递函数调用栈的所有参数?

更简洁的参数传递方案:用match.call()

这问题问得太实用了——谁都不想每次修改函数参数时,还要同步更新内部的函数调用语句对吧?其实R里有个比environment()更靠谱、更简洁的方法,完全不用显式指定参数,还能避免内部变量的干扰。

先回顾下你的场景代码:

f2 <- function(...) { print(list(...)) }
f1 <- function(x, y = 1, ...) { z <- 20; f2(x, y, ...) }
f1(5, k = 6)

你想实现的是:不管f1的参数怎么调整,都能自动把所有参数(包括默认参数)传给f2,不用手动写x, y, ...

最优解决方案

直接用match.call()获取当前函数的调用参数,去掉函数名后传给do.call(f2, ...)就行:

f1 <- function(x, y = 1, ...) {
  z <- 20
  # 捕获调用参数,移除函数名后转成列表
  call_args <- as.list(match.call())[-1]
  do.call(f2, call_args)
}

测试一下f1(5, k = 6),输出和原代码完全一致:

[[1]]
[1] 5

$y
[1] 1

$k
[1] 6

而且如果以后你给f1加新参数(比如f1 <- function(x, y=1, a=3, ...)),完全不用修改f2的调用语句,新参数会自动被传递过去。

为什么这个方法更好?

和你之前用environment()的方法比,它有两个核心优势:

  1. 不会混入内部变量as.list(environment())如果在函数内部定义变量(比如z <-20)之后调用,会把z也包含进去,导致错误传递给f2——你必须把它放在函数开头才能避免。而match.call()只捕获调用时传入的参数,完全不管函数内部定义的变量,安全得多。
  2. 自动补全默认参数:它会把f1中没显式传入的默认参数(比如例子里的y=1)自动补全到参数列表里,和原代码的行为完全一致。如果用sys.call()的话,只会保留显式传入的参数,默认参数不会被传递,这不符合你的需求。

内容的提问来源于stack exchange,提问作者Andrei

火山引擎 最新活动