web-dev-qa-db-ja.com

読みやすい方法で明瞭なdplyrカウントを取得する

私はdplyrを使用して初めてです。グループ内の個別の値を計算する必要があります。表の例を次に示します。

data=data.frame(aa=c(1,2,3,4,NA), bb=c('a', 'b', 'a', 'c', 'c'))

私は次のようなことができることを知っています:

by_bb<-group_by(data, bb, add = TRUE)
summarise(by_bb, mean(aa, na.rm=TRUE), max(aa), sum(!is.na(aa)), length(aa))

しかし、一意の要素の数が必要な場合はどうすればよいですか?

できます:

  > summarise(by_bb,length(unique(unlist(aa))))

  bb length(unique(unlist(aa)))
1  a                          2
2  b                          1
3  c                          2

そして、私ができるNAを除外したい場合:

> summarise(by_bb,length(unique(unlist(aa[!is.na(aa)]))))

  bb length(unique(unlist(aa[!is.na(aa)])))
1  a                                      2
2  b                                      1
3  c                                      1

しかし、それは私にとってはほとんど読めないです。この種の要約を行うより良い方法はありますか?

46
GabyLP

このオプションはどうですか:

data %>%                    # take the data.frame "data"
  filter(!is.na(aa)) %>%    # Using "data", filter out all rows with NAs in aa 
  group_by(bb) %>%          # Then, with the filtered data, group it by "bb"
  summarise(Unique_Elements = n_distinct(aa))   # Now summarise with unique elements per group

#Source: local data frame [3 x 2]
#
#  bb Unique_Elements
#1  a               2
#2  b               1
#3  c               1

filterを使用して、aaがNAである行をフィルターで除外し、列bbでデータをグループ化し、列aaで一意の要素の数をグループ化して集計しますof bb

ご覧のように、dplyrを使用するときにコマンドを「パイプ」または「チェーン」するために使用できるパイプ演算子%>%を使用しています。これは、より自然であるため、読みやすいコードを書くのに役立ちます。コードを左から記述し、上から下に記述します(コードの例のように)深く内側から入れ子にしないでください。

編集:

あなたの質問の最初の部分で、あなたは書いた:

私は次のようなことができることを知っています:

by_bb<-group_by(data, bb, add = TRUE)
summarise(by_bb, mean(aa, na.rm=TRUE), max(aa), sum(!is.na(aa)), length(aa))

これを行う別のオプションがあります(複数の関数を同じ列に適用する):

data %>%
  filter(!is.na(aa)) %>%
  group_by(bb) %>%
  summarise_each(funs(mean, max, sum, n_distinct), aa)

#Source: local data frame [3 x 5]
#
#  bb mean max sum n_distinct
#1  a    2   3   4          2
#2  b    2   2   2          1
#3  c    4   4   4          1
99