R - 将 glmnet 与 purrr/tidyr 结合使用

R - Using glmnet with purrr/tidyr

我正在关注此 R Bloggers link 中的代码,以便使用 tidyrpurrr 对我的数据中的组进行 运行 建模。但是,我想在我的嵌套数据上使用 glmnet 而不仅仅是 lm。与 lm 不同,glmnet/cv.glmnetmodel.matrix 作为 x 参数,我需要抽象提供给 model.matrix 的公式是什么阻碍了我。

所以这有效:

library(purrr)
library(tidyr)
library(dplyr)
library(glmnet)

mod_test <- mtcars %>%
  nest(-vs) %>%
  mutate(cv_mod = map(data, ~ cv.glmnet(
    x = model.matrix(data = ., .$mpg ~ .$cyl * .$hp)[,-1],
    y = .$mpg
  )))
mod_test
> mod_test
# A tibble: 2 x 3
     vs               data          cv_mod
  <dbl>             <list>          <list>
1     0 <tibble [18 x 10]> <S3: cv.glmnet>
2     1 <tibble [14 x 10]> <S3: cv.glmnet>

但是当我尝试单独为 model.matrix 创建公式时,它没有。

mod_form <- as.formula(".$mpg ~ .$cyl * .$hp")

mod_test2 <- mtcars %>%
  nest(-vs) %>%
  mutate(cv_mod = map(data, ~ cv.glmnet(
    x = model.matrix(data = ., mod_form)[,-1],
    y = .$mpg
  )))
Error in mutate_impl(.data, dots) : object '.' not found

如果你想要一个 formula/data 框架接口到 glmnet,你可以使用 glmnetUtils。这使得与 tidyverse 的接口更加方便。

install.packages("glmnetUtils")

mod_test <- mtcars %>%
  nest(-vs) %>%
  mutate(cv_mod=map(data, ~ cv.glmnet(mpg ~ cyl + hp, data=.)))

第一部分,为什么Error in mutate_impl(.data, dots) : object '.' not found?以下是我的推理:

参见as.formula手册:

Formulas created with as.formula will use the env argument for their environment.

当您创建mod_test时:根据as.formula(object, env = parent.frame()),它将是<environment: R_GlobalEnv>

接下来,

A formula object has an associated environment, and this environment (rather than the parent environment) is used by model.frame to evaluate variables that are not found in the supplied data argument.

因此,model.matrix 将在 data 中查找类似 .$mpg 的列。显然,这些列的名称类似于 mpg 而不是 .$mpg。然后它将在与公式关联的环境中查找 .$mpg:R_GlobalEnv。全局环境中没有名为 . 的对象。因此报错。

(如果这部分有错误请指正。)


二、解决办法,试试:

mod_form <- mpg ~ cyl * hp
# or
mod_form <- as.formula('mpg ~ cyl * hp')