動機
ダミー変数を作りたいけど、dfの一つのカラムにカンマ区切りでデータが入ってしまっていてそのままdummiesパッケージを使うことができなかったので作成しました。
実装
該当のデータdfはこんな感じです。
X_name:データ名, X_data:1セルにカンマ区切りで入っているカテゴリ名
> df
X_name X_data
1 place_A T
2 place_B I,C,E
3 place_C G,O,D
4 place_D P,O,T
5 place_E D,O,G
6 place_F C,A,T
7 place_G G,U,N,D,A,M
8 place_H O
9 place_I I,N,F
10 place_J A,I
...
16 place_P U,R,B,A,N
17 place_Q G,A,R,D,E
18 place_R H,O,R,N
19 place_S S,E,I,K,O
20 place_T F,I,S,H
21 place_U D,E,C,K
22 place_V G,L
23 place_W H,E,L,P
24 place_X M,E
25 place_Y S
26 place_Z O,S
このままだとどうにも扱えないので、splitstackshapeパッケージという、一つのセルにデータが格納されているときに剥がしてくれるありがたいパッケージがあるので使います。
library(tidyverse)
library(dummies)
library(splitstackshape)
df.filtered <- df %>%
cSplit("X_data", ",", direction = "long") # ,区切りのデータを剥がして縦に格納
処理後のデータはこんな感じです。
> df.filtered
X_name X_data
1: place_A T
2: place_B I
3: place_B C
4: place_B E
5: place_C G
6: place_C O
7: place_C D
8: place_D P
9: place_D O
10: place_D T
...
74: place_V G
75: place_V L
76: place_W H
77: place_W E
78: place_W L
79: place_W P
80: place_X M
81: place_X E
82: place_Y S
83: place_Z O
84: place_Z S
このdf.filteredをdummiesパッケージを利用してダミー変数にします。そしてそのダミー変数データフレームをX_dataに対してグルーピングし、足し合わせることで欲しい結果を得ることができます。
df.dummy <- df.filtered %>%
select(c('X_data')) %>%
dummy.data.frame() %>% # ダミー変数を作成
data.frame(X_name = df.filtered$X_name, .) %>%
group_by(X_name) %>% # X_nameでグルーピング
summarise_each(funs(sum)) #それぞれのcolumnに対してsumする
生成物
df.dummy
# A tibble: 26 x 22
X_name X_data.A X_data.B X_data.C X_data.D X_data.E X_data.F X_data.G X_data.H X_data.I
<fct> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 place_A 0 0 0 0 0 0 0 0 0
2 place_B 0 0 1 0 1 0 0 0 1
3 place_C 0 0 0 1 0 0 1 0 0
4 place_D 0 0 0 0 0 0 0 0 0
5 place_E 0 0 0 1 0 0 1 0 0
6 place_F 1 0 1 0 0 0 0 0 0
7 place_G 1 0 0 1 0 0 1 0 0
8 place_H 0 0 0 0 0 0 0 0 0
9 place_I 0 0 0 0 0 1 0 0 1
10 place_J 1 0 0 0 0 0 0 0 1
おわりに
もっとマシな実装があったら教えてください。