通过将表达式传递给 "subset" 来更新回归对象

update regression objects by passing an expression to "subset"

我有很多 lm() 创建的回归对象。每一个都是根据不同的数据构建的 frame,这些不同的data frame有不同的维度。但是每个数据框都包含逻辑变量 xyz。在某些情况下,我想更新每个回归对象,使 subset 参数为 x。在其他情况下,我想更新每个回归对象,使 subset 参数为 y。在其他情况下,我想更新每个回归对象,使 subset 参数为 z。执行此操作的有效方法是什么?

这是低效的方式:

# Set only one of these three variables to be TRUE
subsetX <- TRUE
subsetY <- FALSE
subsetZ <- FALSE

# Now update the regressions.
if (subsetX) {
  update(lm1, subset = x)
  update(lm2, subset = x)
  [...]
} else if (subsetY) {
  update(lm1, subset = y)
  update(lm2, subset = y)
  [...]
} else if (subsetZ) {
  update(lm1, subset = z)
  update(lm2, subset = z)
  [...]
}

这种方法效率低下,因为更新回归的三个代码块之间存在大量重复。我宁愿做类似

的事情
subsetVar <- dplyr::case_when(
  subsetX ~ expression(x),
  subsetY ~ expression(y),
  subsetZ ~ expression(z))
update(lm1, subset = substitute(subsetVar))
update(lm2, subset = substitute(subsetVar))
[...]

也就是说,我想为每一个最多写一个update()命令 回归对象,同时仍然根据 逻辑(布尔)变量,如 subsetXsubsetY。这可能吗? 上面的代码不起作用;当我尝试时,我收到一条 Error in xj[i] : invalid subscript type 'symbol' 错误消息。

我搜索了其他 Stack Overflow 问题,但没有找到任何直接说明这个问题的内容。

这里有一种方法可以通过一个简单的函数让您的工作流程更轻松一些,并使用 purrr::map2 为它提供您想要的模型和子集列表

library(purrr)
set.seed(2020)
mtcars$x <- sample(c(TRUE, FALSE), 32, replace = TRUE)
mtcars$y <- sample(c(TRUE, FALSE), 32, replace = TRUE)
mtcars$z <- sample(c(TRUE, FALSE), 32, replace = TRUE)

lm1 <- lm(mpg ~ hp, mtcars)


subset_lm_by <- function(model, subset = NULL) {
  if (subset == "x") {
    update(model, subset = x)
  } else if (subset == "y") {
    update(model, subset = y)
  } else if (subset == "z") {
    update(model, subset = z)
  } else {
#    cat('I only accept x, y or z!')
  }
}

models <- list(lm1, lm1, lm1, lm1)
subsets <- list("x", "y", "z", "nonsense")

purrr::map2(.x = models, 
            .y = subsets, 
            ~ subset_lm_by(model = .x, subset = .y))
#> [[1]]
#> 
#> Call:
#> lm(formula = mpg ~ hp, data = mtcars, subset = x)
#> 
#> Coefficients:
#> (Intercept)           hp  
#>    31.21178     -0.08098  
#> 
#> 
#> [[2]]
#> 
#> Call:
#> lm(formula = mpg ~ hp, data = mtcars, subset = y)
#> 
#> Coefficients:
#> (Intercept)           hp  
#>    32.83501     -0.07294  
#> 
#> 
#> [[3]]
#> 
#> Call:
#> lm(formula = mpg ~ hp, data = mtcars, subset = z)
#> 
#> Coefficients:
#> (Intercept)           hp  
#>    32.53554     -0.08688  
#> 
#> 
#> [[4]]
#> NULL