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列を変更します。これは list/1D を返すため、 への呼び出しが必要です。mapmutate_atdata.frameunnest

于 2016-10-22T20:49:32.113 に答える