如何替换 lm() 对象内的调用?

How to replace call inside an lm() object?

miceadds::lm.cluster() 中,调用以这种方式表示 stats::lm(formula = formula, data = data),我想用实际公式替换它。

例如,函数调用存储在 lm() 对象中

fit <- lm(Sepal.Length ~ Petal.Length, iris)
> fit$call
lm(formula = Sepal.Length ~ Petal.Length, data = iris)

我正在尝试用 call() 更改它,但到目前为止没有成功。

fit$call <- call("lm(formula = Sepal.Length ~ Petal.Length, data = iris, foo = NULL)")
> fit$call
`lm(formula = Sepal.Length ~ Petal.Length, data = iris, foo = NULL)`()

有这些``和末尾的()。虽然 class() 产生 call,但它仍然与 lm(formula = Sepal.Length ~ Petal.Length, data = iris, foo = NULL).

不同

我也尝试了 formula()reformulate() 但失败了。

我该怎么做?

这样就可以了,但我们仍然很好奇为什么...

您遇到的问题是 call 没有像您提供的那样进行完整的函数调用;相反,只需将函数名称作为第一个参数,然后是您要使用的参数,引用您不想评估的任何内容。

> fit$call <- call("lm", Sepal.Length ~ Petal.Length, 
                   data=quote("iris"), foo=NULL)
> fit

Call:
lm(Sepal.Length ~ Petal.Length, data = "iris", foo = NULL)

Coefficients:
 (Intercept)  Petal.Length  
      4.3066        0.4089  

这可能是 miceadds 应该做的,尽管 do.call 可以实际执行它;如果是这样,它会根据需要记录通话。参见 一例。

您可以创建自己的函数来调用 lm.cluster 并执行您想要的操作,请参见下面的示例。研究了一下,修复lm.cluster会很棘手,至少对于data块,formula块会很容易修复。对于数据,它更难处理,因为函数可能会传递一个表达式而不是对象的名称。

lm.special <- function(formula, data, ... ) {
  lm(formula=formula, data=data, ...)
}

lm.special2 <- function(formula, data.name) {
  cl <- call("lm.special", formula=formula, data=as.name(data.name))
  out <- eval(cl)
  out$call <- cl
  out
}

> lm(Sepal.Length ~ Petal.Length, iris)

Call:
lm(formula = Sepal.Length ~ Petal.Length, data = iris)

Coefficients:
 (Intercept)  Petal.Length  
      4.3066        0.4089  

> lm.special(Sepal.Length ~ Petal.Length, iris)

Call:
lm(formula = formula, data = data)

Coefficients:
 (Intercept)  Petal.Length  
      4.3066        0.4089  

> lm.special2(Sepal.Length ~ Petal.Length, "iris")

Call:
lm.special(formula = Sepal.Length ~ Petal.Length, data = iris)

Coefficients:
 (Intercept)  Petal.Length  
      4.3066        0.4089  

如果您只想更换特定组件,例如公式:

fit$call$formula <- quote(foo ~ bar)

如果您想以编程方式生成 foo ~ bar 而不是在脚本中对其进行硬编码,事情会变得更糟...