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

标签 r variadic-functions lm

<分区>

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

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

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

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 被分配给 ...-list 的第一个元素,它是空的。

谁能详细说明这种方法失败的原因?特别是,如果 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) 
}

这行得通,但我仍然想知道如果 ... 中的参数是向量或列表,是否没有办法绕过 do.call

最佳答案

我想不出像 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 )。 eval正在评估 mfparent.frame() .由于 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是包含模拟数据的数据框;和 env是您的全局环境。 ( env 之前在 model.frame.default 的主体中定义为 environment(formula) ,这确实是您的全局环境,因为这是您定义 formula 的地方。)

eval正在评估 extrasdataenv作为外壳。 此处 会抛出错误,因为数据框 data和您的全局环境 env不是 ..n 的有效上下文.符号 ..1仅在带有 ... 的函数的框架中有效作为正式论证。

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

All of weights, subset and offset are evaluated in the same way as variables in formula, that is first in data and then in the environment of formula.

weights时没有问题在 outer_function 中被赋予常量值(即,不是绑定(bind)在环境中的变量的名称,不是函数调用)打电话,因为在那种情况下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))

不要。

关于r - 在 R 中的 stats::lm 中使用可变参数(点-点-点),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70712180/

相关文章:

r - 从 R 中的 lm 中提取变量以使用预测

r - 向量化 R 中的双循环

r - 根据以 ocr'd 图像结尾的段落将字符串拆分为列

c++ - 使用可变函数/宏简化工作

c++ - 为什么我不能将模板函数指针传递给可变参数函数?

r - group_by() 中 mutate() 中的 lm()

r - 改变 R 中的重要性符号

r - 如何在行中搜索相等的变量(以智能方式)并将相应的行存储为子集?

r - 如何使用 dplyr 为函数传递单行

c - 如何在终端中与我刚刚编写的 C 程序进行交互