171

plyr の理解を dplyr に移そうとしていますが、複数の列でグループ化する方法がわかりません。

# make data with weird column names that can't be hard coded
data = data.frame(
  asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
  a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
  value = rnorm(100)
)

# get the columns we want to average within
columns = names(data)[-3]

# plyr - works
ddply(data, columns, summarize, value=mean(value))

# dplyr - raises error
data %.%
  group_by(columns) %.%
  summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds

plyr の例を dplyr 風の構文に変換するには何が欠けていますか?

編集 2017 : Dplyr が更新されたため、より簡単なソリューションが利用可能になりました。現在選択されている回答を参照してください。

4

10 に答える 10

27

の列の文字列指定は、名前がアンダースコアで終わる関数dplyrのバリアントを通じてサポートされるようになりました。dplyrたとえば、関数に対応して、group_by文字group_by_列引数を取る関数があります。このビネットは、これらの関数の構文を詳細に説明しています。

.dots次のスニペットは、@sharoz が最初に提起した問題をきれいに解決します (引数を書き出す必要があることに注意してください)。

# Given data and columns from the OP

data %>%
    group_by_(.dots = columns) %>%
    summarise(Value = mean(value))

(現在、dplyr は%>%演算子を使用しており、%.%非推奨であることに注意してください)。

于 2014-10-31T04:55:53.383 に答える
17

dplyr が文字列引数を完全にサポートするまでは、おそらく次の要点が役に立ちます。

https://gist.github.com/skranz/9681509

文字列引数を使用する s_group_by、s_mutate、s_filter などのラッパー関数が多数含まれています。それらを通常の dplyr 関数と組み合わせることができます。例えば

cols = c("cyl","gear")
mtcars %.%
  s_group_by(cols) %.%  
  s_summarise("avdisp=mean(disp), max(disp)") %.%
  arrange(avdisp)
于 2014-03-21T08:04:42.697 に答える
17

dplyr 1.0.0 からの across() による更新

上記のすべての回答はまだ機能しており、.dots 引数を使用したソリューションは興味深いものです。

しかし、覚えやすいソリューションを探している場合は、新しいソリューションがacross()役に立ちます。Hadley Wickham によって 2020-04-03 に公開され、 で使用でき、mutate()またはのsummarise()ようなスコープ付きバリアントを置き換えることができます。とりわけ、面倒な非標準評価 (NSE) を、 などの引用/非引用に非常にエレガントに置き換えます。_at_all!!! rlang::syms()

したがって、ソリューションacrossは非常に読みやすいように見えます。

data %>%
  group_by(across(all_of(columns))) %>%
  summarize(Value = mean(value))
于 2021-02-18T03:47:01.907 に答える
4
data = data.frame(
  my.a = sample(LETTERS[1:3], 100, replace=TRUE),
  my.b = sample(LETTERS[1:3], 100, replace=TRUE),
  value = rnorm(100)
)

group_by(data,newcol=paste(my.a,my.b,sep="_")) %>% summarise(Value=mean(value))
于 2014-10-24T16:53:22.850 に答える