2016-12-02 10 views
3

私はpurrrパラダイムが新しく、苦労しています。モデルの要約を抽出し、新しい列として保存します。

私は、データフレームをネストし、ネストされたデータに対して線形モデルを実行し、各画像からいくつかの係数を抽出し、各画像ごとに要約を生成するまで、いくつかの情報源に従っています。私がしたい最後のことは、(私が達成しようとしているものの中で最も単純な部分であると思っていただろう)要約から "r.squared"を抽出することですが、何らかの理由で私は構文を得ることができません右。

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

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
     sum = map(fit, ~summary)) 

、ここでは失敗しr.squaredを抽出する私の試みです:

はここで働く私が持っているもののMWEだ

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
     sum = map(fit, ~summary), 
     rsq = map_dbl(sum, "r.squared")) 
Error in eval(substitute(expr), envir, enclos) : 
    `x` must be a vector (not a closure) 

これがされRStudioサイトで与えられた例とは表面的に似ています:

mtcars %>% 
    split(.$cyl) %>% 
    map(~ lm(mpg ~ wt, data = .x)) %>% 
    map(summary) %>% 
    map_dbl("r.squared") 

これはうまくいきましたが、私はr.squaredの値を新しい列に入れたいので(mutate文)、問題の回避の代わりにコードが機能しない理由を理解したいと思います。

EDIT:

ここで私は下のソリューションを使用しに来た作業溶液だ:

mtcars %>% 
     nest(-cyl) %>% 
     mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
      summary = map(fit, glance), 
      r_sq = map_dbl(summary, "r.squared")) 

EDIT 2:

だから、それは実際に含めることからバグがあることが判明しますsummary = map(fit、〜summary)行にチルダキーの値を入力します。私の推測では、オブジェクトは、ネストであり、サマリー自体によって返されるオブジェクトではない関数になります。 。誰かがチャイムを希望する場合は、この上の正式な答えを大好きだ

を明確にするため、元のコードのこのバージョンでは正常に動作します:

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
     summary = map(fit, summary), 
     r_sq = map_dbl(summary, "r.squared")) 

答えて

3

、あなたはbroomパッケージからmapglanceとともにunnestを使用したいと思います。

library(tidyr) 
library(dplyr) 
library(broom) 

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .))) %>% 
    unnest(map(fit, glance)) 

あなただけのR二乗より多くを得るだろうし、そこからあなたが必要としないものを削除するにはselectを使用することができます。

あなたはリストの列にネストされたモデルの要約を維持したい場合:

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
     summary = map(fit, glance)) 

あなただけのネストされたフレームから単一の値を抽出したい場合は、単に実際の値(にmapを使用する必要があると私が最初に示唆したように[[またはextract2ではありません。

mtcars %>% 
    nest(-cyl) %>% 
    mutate(fit = map(data, ~lm(mpg ~ wt, data = .)), 
     summary = map(fit, glance), 
     r_sq = map_dbl(summary, "r.squared")) 
+0

これは私がやりたがっているようですが、なぜコードがこのように構築されたのか混乱しています。なぜ私はあなたがデータをアンネストしたのか分かりません。できるかどうか説明できますか? 答えをありがとう! – niklz

+1

'unnest'を使うと、リストの列からデータフレームを取り出し、使用可能なすべての列を親データフレームに広げます。ネストされたままにすることはできますが、r-squaredカラムは直接アクセスできません。私は 'unnest'なしでコードを持つように答えを更新します。 –

+0

マップ(fit、〜glance)ステートメントの結果が不必要なので、混乱している入れ子になっていないと思った。 この方法は、要約を含む合計列を作成する必要性を回避します。私が理解すれば; 2番目のバージョンのcoeffs列には同じ情報が含まれています(ただし、別の形式でも同じです)。 私は「r.squared」を集計列から抽出する方法はありませんか?ちょうど私がネストされたリストを持っているところで再びこの壁に当たっているのを見て、そこからただ一つの要素を取り出そうと思っています。 – niklz

4

私はあなたが達成したいもののために考えて、あなたbroomパッケージからglance()機能を使用したほうが良いです:

library(broom) 
library(dplyr) 
mtcars %>% 
    group_by(cyl) %>% 
    do(glance(lm(mpg ~ wt, data = .))) %>% 
    select(cyl, r.squared) 
# cyl r.squared 
# <dbl>  <dbl> 
#1  4 0.5086326 
#2  6 0.4645102 
#3  8 0.4229655 
+0

これは望ましい出力を得ますが、私は本当に私が持っている現在のパイプで動作する実装を見つけたいと思います。私は方法があると確信しており、それは正しい構文を得ることのちょうど場合です。 お返事ありがとうございました – niklz

1

ここでは、より良い方法がなければならないことは、パイプと私の試みです:

mtcars %>% 
    split(.$cyl) %>% 
    map(~ lm(mpg ~ wt, data = .x)) %>% 
    map(summary) %>% 
    map_dbl("r.squared") %>% 
    list() %>% 
    as.data.frame(col.names = "r.squared") %>% 
    add_rownames(var = "cyl") 

# # A tibble: 3 × 2 
#  cyl r.squared 
# <chr>  <dbl> 
# 1  4 0.5086326 
# 2  6 0.4645102 
# 3  8 0.4229655 

注:警告の下に表示される場合があります。

警告メッセージ:代わりにtibble :: rownames_to_column()を使用してください。あなたの現在のパイプ内に収まるように

+0

ありがとうございました。本当に良い方法があります。 OP – niklz

+0

@ zx8754で私の編集をチェックしてください。この例で 'map_dbl(" r.squared ")'が動作している理由を熟知しています。 '' r.squared''は関数ではないので、この抽出はどのようにして正確に行われ、適用されるのですか?明確にできますか? :) –