Rのdata.frameの欠けているデータに0を埋める

Tableauのコミュニティで質問をして、データが欠けているときは事前に0を埋めておく方が良いと教えてもらいました。

欠けているデータがある場合の割合の出し方 |Tableau Support Community

というわけで、Rで欠けているデータに0を埋める方法をメモっておきます。

データフレームから指定した列のデータを取り出してリストを作り、expand.gridで拡張して、元データとマージする、と。

> df <- data.frame(
+     年代    =c(    '10代',     '10代',   '20代',   '20代',         '30代'),
+     性別    =c(      '男',       '女',   '不明',     '男',           '女'),
+     商品名  =c('コーヒー', 'コーヒー', 'パフェ', 'パフェ', 'ホットケーキ'),
+     購入者数=c(        50,         50,        1,       10,             30)
+ )
> df
  年代 性別       商品名 購入者数
1 10代   男     コーヒー       50
2 10代   女     コーヒー       50
3 20代 不明       パフェ        1
4 20代   男       パフェ       10
5 30代   女 ホットケーキ       30
> 
> base_list <- list()
> for (base_name in c('年代', '性別', '商品名')) {
+     base_list[[base_name]] <- unique(df[[base_name]])
+ }
> grid <- expand.grid(base_list)
> new_df <- merge(grid, df, all.x=T)
> new_df[is.na(new_df)] <- 0
> new_df
   年代 性別       商品名 購入者数
1  10代   女     コーヒー       50
2  10代   女       パフェ        0
3  10代   女 ホットケーキ        0
4  10代   男     コーヒー       50
5  10代   男       パフェ        0
6  10代   男 ホットケーキ        0
7  10代 不明     コーヒー        0
8  10代 不明       パフェ        0
9  10代 不明 ホットケーキ        0
10 20代   女     コーヒー        0
11 20代   女       パフェ        0
12 20代   女 ホットケーキ        0
13 20代   男     コーヒー        0
14 20代   男       パフェ       10
15 20代   男 ホットケーキ        0
16 20代 不明     コーヒー        0
17 20代 不明       パフェ        1
18 20代 不明 ホットケーキ        0
19 30代   女     コーヒー        0
20 30代   女       パフェ        0
21 30代   女 ホットケーキ       30
22 30代   男     コーヒー        0
23 30代   男       パフェ        0
24 30代   男 ホットケーキ        0
25 30代 不明     コーヒー        0
26 30代 不明       パフェ        0
27 30代 不明 ホットケーキ        0
> 

この例では元のデータが小さいので全然平気ですが、場合によっては爆発的にデータ量が増えるので注意です。