5

mtcars データ セットの wt に gpm (ガロン/マイル = 1/mpg) のモデルを当てはめるのと同じことをしたいと思います。それは簡単に思えます:

data(mtcars)
library(dplyr)
library(tidyr)
library(broom)
library(ggplot2)
library(scales)

mtcars2 <-
    mtcars %>%
    mutate(gpm = 1 / mpg) %>%
    group_by(cyl, am)

lm1 <-
    mtcars2 %>%
    do(fit = lm(gpm ~ wt, data = .))

これにより、予想どおり、6 行の行単位のデータ フレームが得られます。

このグラフは、6 つのグループがあることを示しています。

p1 <-
    qplot(wt, gpm, data = mtcars2) +
    facet_grid(cyl ~ am) +
    stat_smooth(method='lm',se=FALSE, fullrange = TRUE) +
    scale_x_continuous(limits = c(0,NA)) 

適合した出力を取得するためにaugment()を使用できます。

lm1 %>% augment(fit)

これにより、期待どおり、mtcars2 の各行に 1 つずつ、合計 32 行が得られます。

ここでの課題: newdata を使用して適合出力を取得したいと思います。ここで、wt を cyl/4 だけインクリメントしました。

newdata <-
    mtcars2 %>%
    mutate(
        wt = wt + cyl/4)

これにより、lm1 %>%augment(fit) と同じサイズのデータ​​ フレームが生成されると予想されます: newdata の各行に対して 1 行。

不運にも、

pred1 <-
    lm1 %>%
    augment(
        fit,
        newdata = newdata)

192 行 (= 6 x 32) のデータ フレームが得られ、明らかに各モデルが newdata の各行に適合します。

他の場所を読んで、group_by と行単位のデータ フレームに互換性がないことがわかったので、lm1 はグループ化されておらず、augment はモデルと newdata を関連付けることができません。これを可能にする別のデザインパターンはありますか? 上記の試みのようにシンプルで透過的であればいいのですが、それが機能することがより重要です。

ここに私のsessionInfo()があります:

> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] scales_0.4.0  ggplot2_2.1.0 broom_0.4.1   tidyr_0.6.0   dplyr_0.5.0  

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.7      magrittr_1.5     mnormt_1.5-4     munsell_0.4.3   
 [5] colorspace_1.2-6 lattice_0.20-34  R6_2.1.3         stringr_1.1.0   
 [9] plyr_1.8.4       tools_3.3.1      parallel_3.3.1   grid_3.3.1      
[13] nlme_3.1-128     gtable_0.2.0     psych_1.6.9      DBI_0.5-1       
[17] lazyeval_0.2.0   assertthat_0.1   tibble_1.2       reshape2_1.4.1  
[21] labeling_0.3     stringi_1.1.1    compiler_3.3.1   foreign_0.8-67  

編集:

@aosmith: 私はあなたの 2 番目のオプションを検討してきましたが、気に入っています。ただし、実際のデータで試してみると、mutate コマンドに問題があります。「エラー: 拡張は、クラス リストのデータを処理する方法がわかりません」が返されます。

私の実際のコードは次のようになります。

newdata %>% 
dplyr::select(cyl, am, wt) %>% # wt holds new predictor values
group_by(cyl, am) %>%
nest() %>%
inner_join(regressions, .) %>% 
## looks like yours at this point
mutate(pred = list(augment(fit, newdata = data))) %>% # Error here
unnest(pred)

あなたのもののように見えると言うのは、ID (chr)、attr1 (dbl)、cyl (dbl)、am (chr)、fit (list)、および data (リスト)。cyl、am (dbl)、fit、およびデータがあります。am を dbl に変更しましたが、役に立ちませんでした。

違いは、このサンプルには 3 (ID ... mtcars の行名に似ています) x 2 (cyl) x 2 (am) 単位 (各サンプルには 12 の測定値があります) があるのに対し、mtcars の例には 3 があることです。 (cyl) x 2 (am) セル x セルごとの車の種類の乱数。私の分析では、ID 値を確認する必要がありますが、newdata はすべてのユニットに等しく適用されます。それが役立つ場合は、テストで各車に適用される向かい風の速度と考えてください。それは、クラスリストのデータを処理できないというaugmentの苦情の原因を示唆していますか?

EDIT:IDをnewdata(full = TRUEを使用)とマージすると、最後の問題が解決しました。私は現在、最初に提案されたソリューションを使用しています。

4

1 に答える 1

4

この種の状況では map2、パッケージpurrrを使用しました。map22 つのリストの要素を同時にループします。リストは同じ長さで、同じ順序でなければなりません。

リストの要素は、適用する関数の引数として使用されます (augmentこの場合は )。ここで、2 つのリストは、モデルのリストとデータセットのリストになります (各cyl/am組み合わせに対して 1 つのリスト)。

を使用map2_dfすると、リストではなく data.frame として結果が返されます。

library(purrr)

を使用して予測する data.frames のリストを作成しましたsplit。分割する要素の順序によってリストの順序が決まるので、 と同じ順序になるようにしましたlm1

test_split = split(newdata, list(newdata$am, newdata$cyl)

map2_df(lm1$fit, test_split, ~augment(.x, newdata = .y))

順序をあまり気にしないようにするためにnest、予測データをグループごとに結合し、これを に結合し、ネストを解除するためのリストとしてlm1の結果を返すことができます。augment

newdata %>%
    group_by(cyl, am) %>%
    nest() %>%
    inner_join(lm1, .) %>%
    mutate(pred = list(augment(fit, newdata = data))) %>%
    unnest(pred)
于 2016-10-03T18:29:19.520 に答える