在R中的stats:lm中使用变量参数(点-点-点)



假设我们有一个函数调用stats::lm,并将公式和数据帧作为参数。我们想要传递给stats::lm的其他参数可以使用变量参数提供:

outer_function <- function(formula, data, ...) {
z <- stats::lm(formula = formula, data = data, ...)
return(z)
}

现在假设我们想要使用这个函数,并提供一个将传递给stats::lm的附加参数(weights(。

data <- data.frame(replicate(5, rnorm(100)))
weights <- replicate(100, 1)
formula <- X1 ~ X2 + X3
outer_function(formula = formula, data = data, weights = weights)

这在stats::lm中产生以下错误:

Error in eval(extras, data, env) : 
..1 used in an incorrect context, no ... to look in

调试对stats::lm的调用时,我看到参数weights正确地传递给了stats::lm,但后来用于函数求值的match.call()

stats::lm(formula = formula, data = data, weights = ..1)

使得weights被分配了...-列表的第一个元素,该元素是空的。

有人能详细说明这种方法失败的原因吗?特别地,如果weights是标量(比如5(,则不会出现问题,并且match.call()将是

stats::lm(formula = formula, data = data, weights = 5)

目前,我正在为我的功能使用以下解决方案:

outer_function <- function(formula, data, ...) {
args <- list(formula = formula, data = data, ...)
z <- do.call(stats::lm, args)
return(z) 
}

这是有效的,但我仍然想知道在CCD_ 15中的自变量是向量或列表的情况下,是否没有办法绕过CCD_。

我想不出有什么解决方案能像do.call那样安全简洁。我已经调试到lm调用中,可以解释发生了什么。

lm的正文中,您可以找到语句

mf <- eval(mf, parent.frame())

在分配的右侧,mf是呼叫

stats::model.frame(formula = formula, data = data, weights = ..1, 
drop.unused.levels = TRUE)

parent.frame()outer_function调用的帧(换言之outer_function的评估环境(。CCD_ 23正在对CCD_ 25中的CCD_。由于S3调度,parent.frame()中最终评估的是调用

stats::model.frame.default(formula = formula, data = data, weights = ..1, 
drop.unused.levels = TRUE)

model.frame.default的正文中,您可以找到语句

extras <- eval(extras, data, env)

分配的右侧,extras是调用

list(weights = ..1)

指定mf中与model.frame.default的形式参数...匹配的参数(在本例中仅为weights,因为model.frame.default具有名为formuladatadrop.unused.levels形式参数(;data是包含您的模拟数据的数据帧;CCD_ 38是您的全局环境。(envmodel.frame.default的前面被定义为environment(formula),这确实是您的全局环境,因为这就是您定义formula的地方。(

eval正在以env作为外壳来评估data中的extras。此处抛出一个错误,因为数据帧data和全局环境env不是..n的有效上下文。符号..1仅在以...作为形式自变量的函数的帧中有效。

你可能已经从?lm中推断出了这个问题,其中指出:

所有weightssubsetoffset的评估方式与formula中的变量相同,即首先在data中,然后在formula的环境中。

outer_function调用中为weights给定常量值(即,而不是环境中绑定的变量的名称,not函数调用(时没有问题,因为在这种情况下,match.call不会替换符号..n。因此

outer_function(formula = formula, data = data, weights = 5)

有效(好吧,抛出了一个不同的错误(,但

weights <- 5
outer_function(formula = formula, data = data, weights = weights)

outer_function(formula = formula, data = data, weights = rep(1, 100))

不要。

最新更新