1

我有一个数据集,其中包含许多(因子)变量,前缀为“cat_”。

library(tidyverse)
library(modelr)
library(lazyeval)
library(purrr)

# create the dataset
df_foo = wakefield::r_data_frame(
  n = 100,
  wakefield::r_series(wakefield::r_sample, j = 5, name = "cat"),
  Y = wakefield::normal()
)

我希望能够使用 tidy 框架计算每个因子变量与响应变量的成对 k 折交叉验证回归 R2。

对于如下几个变量,很容易跨折叠计算。

df_foo %>% 
  mutate_at(.funs = funs(as.factor), .cols = vars(starts_with("cat"))) %>% 
  crossv_kfold(k = 10, id = "id") %>% 
  mutate_(
    .dots = setNames(
      list(
        interp(
          quote(
            purrr::map_dbl(train, .f = function(train_data) {
          summary(stats::lm(Y ~ cat_1, data = train_data))$r.squared
        }))),
        interp(
          quote(
            purrr::map_dbl(train, .f = function(train_data) {
          summary(stats::lm(Y ~ cat_2, data = train_data))$r.squared
        })))
      ),
      nm = c("cat_1", "cat_2")
    )
  )

问题:

  • 如何将其推广到任意数量的变量?

  • 为什么我必须明确地为函数使用命名空间访问器purrr::map_dblstats::lm(如果我删除命名空间访问器,上面的逻辑将不起作用)?


编辑:

以下代码获取每个变量的 R2,但不能将其展平为与数据集中变量数相等的列数。

make_r2_variable = function(var_name, train_data) {
  summary(stats::lm(Y ~ var_name, data = train_data))$r.squared
}

make_r2 = function(train_data) {
  summarise_at(
    .tbl =  data.frame(train_data),
    .cols = vars(starts_with("cat_")),
    .funs = funs(make_r2_variable(., train_data = train_data))
  )

}

df_foo = df_foo %>% 
  mutate_at(.funs = funs(as.factor), .cols = vars(starts_with("cat"))) %>% 
  crossv_kfold(k = 10, id = "id") %>% 
  mutate(
    R2 = map(.x = train, .f = make_r2)
  ) 
4

1 回答 1

1

我认为尽可能紧凑的解决方案是:

make_r2_variable = function(var_name, train_data) {
  summary(stats::lm(Y ~ var_name, data = train_data))$r.squared
}

make_r2 = function(train_data) {
  summarise_at(
    .tbl =  data.frame(train_data),
    .cols = vars(starts_with("cat_")),
    .funs = funs(make_r2_variable(., train_data = train_data))
  )

}

df_foo = df_foo %>% 
  mutate_at(.funs = funs(as.factor), .cols = vars(starts_with("cat"))) %>% 
  crossv_kfold(k = 10, id = "id") %>% 
  mutate(
    R2 = map(.x = train, .f = make_r2)
  ) %>% 
  unnest(R2)

这基本上是我在编辑加的解决方案unnest。这基本上改变了S3: resample使用map和在其中mutate_at循环匹配条件的列的列。由于返回 list/1D data.frame,因此需要调用 to unnest

于 2016-10-22T20:49:32.113 回答