54

ddply の代わりに dplyr の使用を開始したいのですが、それがどのように機能するかを理解できません (ドキュメントを読みました)。

たとえば、何かを mutate() しようとすると、「group_by」関数が想定どおりに機能しないのはなぜですか?

mtcars を見る:

図書館(車)

「cyl」と「gear」でグループ化された mtcars の要約である data.frame を作成するとします。

df1 <- mtcars %.%
            group_by(cyl, gear) %.%
            summarise(
                newvar = sum(wt)
            )

次に、このデータフレームをさらに要約したいとします。ddply を使用すると簡単ですが、dplyr を使用しようとすると、実際には「グループ化」されません。

df2 <- df1 %.%
            group_by(cyl) %.%
            mutate(
                newvar2 = newvar + 5
            )

グループ化されていない出力が得られます。

  cyl gear newvar newvar2
1   6    3  6.675  11.675
2   4    4 19.025  24.025
3   6    4 12.375  17.375
4   6    5  2.770   7.770
5   4    3  2.465   7.465
6   8    3 49.249  54.249
7   4    5  3.653   8.653
8   8    5  6.740  11.740

構文に何か問題がありますか?


編集:

これを plyr と ddply で行う場合:

df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))

次に、2 番目の df を取得します。

df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)

しかし、summarise() 関数で sum(newvar) + 5 を使用した同じアプローチは、dplyr では機能しません...

4

5 に答える 5

43

ディコアの答えをさらに一歩進めます-ハドリーが言うように、「要約はグループ化の単一のレイヤーを剥がします」。貼った逆順でグルーピングが剥がれるのでそのまま使えます

mtcars %>%
 group_by(cyl, gear) %>%
 summarise(newvar = sum(wt)) %>%
 summarise(newvar2 = sum(newvar) + 5)

2行目で使用すると、これは別の答えになることに注意してくださいgroup_by(gear, cyl)

そして、最初の試行を機能させるには:

df1 <- mtcars %>%
 group_by(cyl, gear) %>%
 summarise(newvar = sum(wt))

df2 <- df1 %>%
 group_by(cyl) %>%
 summarise(newvar2 = sum(newvar)+5)
于 2014-02-09T07:01:23.517 に答える
11

plyrコードを代わりにdplyrusingに変換すると、同じ結果が得られます。summarisemutate

library(plyr)
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
df2
##   cyl newvar2
## 1   4  30.143
## 2   6  26.820
## 3   8  60.989

detach(package:plyr)    
library(dplyr)
mtcars %.%
    group_by(cyl, gear) %.%
    summarise(newvar = sum(wt)) %.%
    group_by(cyl) %.%
    summarise(newvar2 = sum(newvar) + 5)
##   cyl newvar2
## 1   4  30.143
## 2   8  60.989
## 3   6  26.820

編集

summarise最後のグループ ( ) を削除するのでgear、2 番目のグループをスキップできますgroup_by(以下の @hadley のコメントを参照してください)。

library(dplyr)
mtcars %.%
    group_by(cyl, gear) %.%
    summarise(newvar = sum(wt)) %.%
    summarise(newvar2 = sum(newvar) + 5)
##   cyl newvar2
## 1   4  30.143
## 2   8  60.989
## 3   6  26.820
于 2014-02-09T00:28:31.127 に答える
6

デタッチplyrは、必要に応じて関数を使用できるように問題を解決する 1 つの方法です... しかし、コード内の他のタスクを完了する ためにdplyr他の関数が必要な場合はどうすればよいでしょうか?plyr

(この例では、dplyrplyrライブラリの両方が読み込まれています)

単純な data.frame があり、valueさまざまなレベルでグループ化されたときに、変数 のグループごとの合計を計算したいとします。gname

> dx<-data.frame(gname=c(1,1,1,2,2,2,3,3,3), value = c(2,2,2,4,4,4,5,6,7))
> dx
  gname value
1     1     2
2     1     2
3     1     2
4     2     4
5     2     4
6     2     4
7     3     5
8     3     6
9     3     7

dplyrしかし、グループ化された合計を生成すると思われるものを使用しようとすると、次のようになります。

dx %>% group_by(gname) %>% mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname

  gname value mysum
1     1     2    36
2     1     2    36
3     1     2    36
4     2     4    36
5     2     4    36
6     2     4    36
7     3     5    36
8     3     6    36
9     3     7    36

望ましい答えは得られません。おそらく、 と の間の and または 関数の何らかの相互作用またはオーバーロードがgroup_by原因mutateです。を切り離すこともできますが、別の方法として、とのバージョンを一意に呼び出すこともできます。dplyrplyrplyrdplyrgroup_bymutate

dx %>% dplyr::group_by(gname) %>% dplyr::mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname

  gname value mysum
1     1     2     6
2     1     2     6
3     1     2     6
4     2     4    12
5     2     4    12
6     2     4    12
7     3     5    18
8     3     6    18
9     3     7    18

これで期待どおりに動作することがわかりました。

于 2015-02-27T02:14:41.463 に答える
5

dplyr は、例で期待どおりに機能しています。指定したように、Mutate は、newvar2 を作成するときに、newvar の各値に 5 を追加するだけです。これは、グループ化してもしなくても同じように見えます。ただし、グループごとに異なるものを指定すると、異なるものになります。例えば:

df1 %.%
            group_by(cyl) %.%
            mutate(
                newvar2 = newvar + mean(cyl)
            )
于 2014-02-09T00:16:31.260 に答える