【问题标题】:How to properly write a wrapper for lm() with dots only? (Error ..3 used in an incorrect context)如何正确地用点为 lm() 编写包装器? (错误 ..3 在不正确的上下文中使用)
【发布时间】:2021-09-06 02:41:12
【问题描述】:

我正在尝试为lm() 构建一个带有点... 的包装器,但取得了部分成功。它仅适用于前两个 formula=data= 参数。但是对于随后的每个参数,它似乎都不起作用并引发错误。

我对函数中lm() 的结果所做的不是问题的原因。它似乎只与使用点有关。所以我能够在这个 MWE 中找出问题:

lm_fun <- function(...) {
  lm(...)
  # <some other stuff>
}

lm_fun(formula=mpg ~ hp, data=mtcars)
## works fine

mtcars$w <- runif(nrow(mtcars))  ## adding weights
lm_fun(formula=mpg ~ hp, data=mtcars, weights=w)
# Error in eval(substitute(subset), data, env) : 
#   ..3 used in an incorrect context, no ... to look in

lm_fun(formula=mpg ~ hp, data=mtcars, subset=am == 1)
# Error in eval(substitute(subset), data, env) : 
#   ..3 used in an incorrect context, no ... to look in

lm_fun(formula=mpg ~ hp, data=mtcars, subset=am == 1, weights=w)
# Error in eval(extras, data, env) : 
#   ..4 used in an incorrect context, no ... to look in

这似乎是与that question 不同的问题,因为我在函数调用中提供了完整的参数集,并且没有在函数中添加任何内容。

我错过了什么吗?这种行为的原因是什么,我怎样才能让它正常工作?

编辑

@user63230 提供了一个nice workaround below。但是,它不适用于 lapply,这对我的需求很重要。

lm_fun2 <- function(...) eval(substitute(lm(...)))

fo <- c(mpg ~ hp, mpg ~ am)

lapply(fo, lm_fun, data=mtcars)
# works

lapply(fo, lm_fun2, data=mtcars)
# Error in stats::model.frame(formula = X[[i]], data = mtcars, drop.unused.levels = TRUE) : 
#   object 'X' not found 

【问题讨论】:

    标签: function syntax arguments lm


    【解决方案1】:

    我认为问题在于搜索w等的环境,因此如果将其包装在eval(substitute(中,则以下示例有效:

    lm_fun <- function(...) {
      result <- eval(substitute(lm(...)))
      result
    }
    lm_fun(formula = mpg ~ hp, data = mtcars)
    # Call:
    # lm(formula = mpg ~ hp, data = mtcars)
    
    # Coefficients:
    # (Intercept)           hp  
    #    30.09886     -0.06823 
    
    lm_fun(formula = mpg ~ hp, data = mtcars, weights = w)
    # Call:
    # lm(formula = mpg ~ hp, data = mtcars, weights = w)
    
    # Coefficients:
    # (Intercept)           hp  
    #    31.41313     -0.07391  
    
    lm_fun(formula = mpg ~ hp, data = mtcars, weights = w, na.action = na.omit)
    # Call:
    # lm(formula = mpg ~ hp, data = mtcars, weights = w, na.action = na.omit)
    
    # Coefficients:
    # (Intercept)           hp  
    #    31.41313     -0.07391 
    
    lm_fun(formula = mpg ~ hp, data = mtcars, weights = w, na.action = na.omit, 
      singular.ok = F)
    # Call:
    # lm(formula = mpg ~ hp, data = mtcars, weights = w, na.action = na.omit, 
    #     singular.ok = F)
    
    # Coefficients:
    # (Intercept)           hp  
    #    31.41313     -0.07391 
    
    lm_fun(formula=mpg ~ hp, data=mtcars, subset=am == 1, weights=w)
    # Call:
    # lm(formula = mpg ~ hp, data = mtcars, subset = am == 1, weights = w)
    
    # Coefficients:
    # (Intercept)           hp  
    #    32.96650     -0.07072
    

    也见here。该公式自动与df 关联,但weights 可能在df 之外。

    【讨论】:

    • 问题可能性质不同,我记得我也试过lm_fun(formula=mpg ~ hp, data=mtcars, weights=mtcars$w),但错误仍然存​​在。无论 +1,您的解决方案似乎都可以很好地作为一种解决方法。
    • 但是这对eval(substitute(来说效果不佳:fo &lt;- c(mpg ~ hp, mpg ~ am);lapply(fo, lm_fun, data=mtcars)
    • 有趣。尽管我无法做到(并且忽略了我上面的方法),但我认为解决方案是在经典的list 中捕获... 中的经典R way,然后在@987654336 中以某种方式取消它@。这个question 遵循类似的思考过程,尽管角度略有不同(他们正在删除一个元素,但您想取消列出这些元素)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2014-03-14
    • 2018-04-29
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多