読者です 読者をやめる 読者になる 読者になる

Knowledge As Practice

JAIST(東京)でサービス経営の研究をしている社会人大学院生の研究・勉強メモ(統計分析多め)。

dplyr と tidyr でクロス集計表をつくる group_by() & tally() 編

ノンプログラマーのためのR入門 統計分析

ゴールデンウィークはRと格闘してました。前回と今回はその記録です。


前回とはちょっと違った方法で、クロス集計表を作ってみます。結果は同じです。今回は group_by() を使って列をグループ化する、という作業が1つ増えています。検索すると、今回の方法が主流のようです。前回はこちら↓

■必要なパッケージ
dplyr
tidyr

■使う関数
group_by
tally
spread

■扱うデータ
haisya01.txt(前回と同じデータです)

まずデータの確認と編集用データの作成から。来院動機っていうのは、治療のために歯医者さんに行ったのか、それとも定期検診なのか、別の理由なのかを示しています。

> df <- haisya01.txt
> head(df)
  user_id 性別 年齢 来院動機 費用負担       来院経路
1       1 男性   48     治療     保険   ホームページ
2       2 男性   55     治療     保険   ホームページ
3       3 男性   55     治療     保険 友達・知人紹介
4       4 男性   57     治療     保険         その他
5       5 男性   47     治療     自費         その他
6       6 女性   27     治療     保険         その他

 クロス集計したいのは性別と来院動機です。性別ごとに来院動機の数を知りたいと思うので、集計します。下ごしらえとして、性別と来院動機をグループ化します。それを df2 に入れて確認。

> df2 <- group_by(df, 性別, 来院動機)
> df2
Source: local data frame [500 x 6]
Groups: 性別, 来院動機

   user_id 性別 年齢 来院動機 費用負担         来院経路
1        1 男性   48     治療     保険     ホームページ
2        2 男性   55     治療     保険     ホームページ
3        3 男性   55     治療     保険   友達・知人紹介
4        4 男性   57     治療     保険           その他
5        5 男性   47     治療     自費           その他
6        6 女性   27     治療     保険           その他
7        7 女性   33     治療     保険         家族紹介
8        8 男性   50     検診     保険           その他
9        9 男性   44     治療     保険         家族紹介
10      10 女性   43     検診     保険 建物・看板を見て
..     ...   ..   ..      ...      ...              ...

 「Groups: 性別, 来院動機」という表示が出てきました。どうやらうまくいったようです。では、集計。集計するときに使うのは、tally() という関数です。count() とは違って「tally(データ名)」でいいです。

> df3 <- tally(df2)
> df3
Source: local data frame [6 x 3]
Groups: 性別

  性別 来院動機   n
1 女性   その他   9
2 女性     検診 131
3 女性     治療 152
4 男性   その他   8
5 男性     検診  77
6 男性     治療 123

 前回の count(df2, 性別, 来院動機) と同じ結果が出てきました。あとは spread() を使って来院動機ごとに n の数値を並び替えて、df4 に入れます。

> df4 <- spread(df3, 来院動機, n)
> df4
Source: local data frame [2 x 4]

  性別 その他 検診 治療
1 女性      9  131  152
2 男性      8   77  123

 むむ、やっぱり昇順に並んでいる。前回は select() で日本語の引数を使ったのだダメだったのかもしれない。禁断の添字を使ってみます。1列目、4列目、3列目、2列目の順で並び替えて、df5 に格納。

> df5 <- df4[, c(1,4,3,2)]
> df5
Source: local data frame [2 x 4]

  性別 治療 検診 その他
1 女性  152  131      9
2 男性  123   77      8

 無事、文字化けせずにすみました。添字を使ってしまったのはちょっと悔しいです。Rのせいかな? Rstudio なのかな? select() のせいかな? まあいいや。クリティカルではないし。

以上、tally() を使ったクロス集計表の作り方でした。んー、自分的には count() が好きかも。グループ化も勝手にやってくれますし。

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。