【问题标题】:control scoping of arguments supplied to lm() from whithin a function called by lapply控制从 lapply 调用的函数中提供给 lm() 的参数的范围
【发布时间】:2021-05-17 23:51:41
【问题描述】:

我有一个函数,它获取一个数据集,提取不同的变量,然后从这些变量中建立线性模型(它期望最后一列中的响应)。我希望调用这些模型的 data 参数使用全局环境中的对象,以便我可以使用此函数之外的其他函数来操作它们。以下给出了提供单个数据集时的预期行为。

make_mods <- function(dataset) {
  make_mod <- function(x){
    response <- names(dataset)[length(dataset)]
    form <- paste0(response, " ~ ", x)
    form <- as.formula(form)
    bquote( lm(.(form), data = .(d_sub)) ) # Unevaluated to show output
  }
  d_sub <- substitute(dataset)
  vars <- names(dataset)[-length(dataset)]
  mods <- lapply(vars, make_mod)
  return(mods)
}

# Make some different datasets
ex1 <- ex2 <- ex3 <- mtcars[c(3,4,6,1)] 
new_data <- function(x) {
  x + rnorm(length(x), mean = 0, sd = sd(x))
}
ex2[-length(ex2)] <- lapply(ex2[-length(ex2)], new_data)
ex3[-length(ex3)] <- lapply(ex3[-length(ex3)], new_data)

make_mods(ex1)

我也希望能够在lapply中使用这个功能

# List of datasets for testing function with lapply
ex_l <- mget(c("ex1", "ex2", "ex3"))
lapply(ex_l, make_mods)

但是这里的模型调用最终看起来像这样:lm(mpg ~ disp, data = X[[i]]),当然,这个模型调用不会在默认环境中评估(实际函数会评估函数中的模型调用)。所需的输出是一个模型列表列表,如下所示:lm(mpg ~ disp, data = ex_l[["ex1"]]),即它们具有引用全局环境中数据帧的 data 参数的有效调用。

我已经尝试过将名称传递给lapply 以及从lapply 调用make_mods 的不同包装函数,但它似乎是我的函数,使用substitute 只会在从全局环境调用时给出预期的行为.我是使用范围和环境的新手。 如何让我的函数在从全局环境传递数据帧时以及从 lapply 内传递数据帧时提供所需的 lm 调用

【问题讨论】:

    标签: r lm scoping


    【解决方案1】:

    我唯一能想到的就是在我的 make mods 函数中添加一个 if 语句来测试输入是否是调用。如果是调用,它期望调用全局环境中的数据集。

    make_mods <- function(dataset) {
      make_mod <- function(x){
        response <- names(dataset)[length(dataset)]
        form <- paste0(response, " ~ ", x)
        form <- as.formula(form)
        bquote( lm(.(form), data = .(d_sub)) )
      }
      if(is.call(dataset)) {
        d_sub <- dataset
        dataset <- eval(dataset)
      } else {
        d_sub <- substitute(dataset)
      }
      vars <- names(dataset)[-length(dataset)]
      mods <- lapply(vars, make_mod)
      return(mods)
    }
    

    然后我可以像这样使用lapply

    out <- lapply(names(ex_l), function(x){
            g <- bquote(ex_l[[.(x)]])
            make_mods(g)
        })
    
    names(out) <- names(ex_l)
    

    这给了我这个:

    $ex1
    $ex1[[1]]
    lm(mpg ~ disp, data = ex_l[["ex1"]])
    
    $ex1[[2]]
    lm(mpg ~ hp, data = ex_l[["ex1"]])  
    
    $ex1[[3]]
    lm(mpg ~ wt, data = ex_l[["ex1"]])
    
    <<output truncated>>
    

    也许不是一个优雅的解决方案,但它正在工作。

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多