控制从 lapply 调用的函数中提供给 lm() 的参数范围

问题描述

我有一个函数,它接受一个数据集,提取不同的变量,然后从这些变量中建立线性模型(它期望最后一列中的响应)。我希望这些模型调用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 和用于从 make_mods 调用 lapply 的不同包装函数,但似乎我的函数,在使用 substitute 时只给出从全局环境调用时的预期行为。我不熟悉范围界定和环境。 如何让我的函数在从全局环境传递数据帧和从 lm 内部传递数据帧时发出所需的 lapply 调用

解决方法

我唯一能想到的就是在我的 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>>

也许不是一个优雅的解决方案,但它确实有效。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...