PIB - 20190405: GNU R - クロス集計とゼロ要素

Tips

grep 等でフィルタリングした factor を table() でクロス集計する場合、factor のまま table() に突っ込むと出現頻度ゼロの物もカウントされる。
出現頻度ゼロの物を除いてクロス集計したい場合は、as.character() 等で一旦 factor を解いてから table() に突っ込む必要がある。

例:
x = factor(c("alpha", "bravo"))
x
x[grep("alpha",x)]
table(x[grep("alpha",x)])
table(as.character(x[grep("alpha",x)]))
> x = factor(c("alpha", "bravo"))
> x
[1] alpha bravo
Levels: alpha bravo
> x[grep("alpha",x)]
[1] alpha
Levels: alpha bravo
> table(x[grep("alpha",x)])

alpha bravo 
    1     0 
> table(as.character(x[grep("alpha",x)]))

alpha 
    1 

dplyr 使ってパイプしたほうが読み易いかも
library("dplyr")
x = factor(c("alpha", "bravo"))
x
x[grep("alpha",x)]
x[grep("alpha",x)] %>% table()
x[grep("alpha",x)] %>% as.character() %>% table()
> library("dplyr")
> x = factor(c("alpha", "bravo"))
> x
[1] alpha bravo
Levels: alpha bravo
> x[grep("alpha",x)]
[1] alpha
Levels: alpha bravo
> x[grep("alpha",x)] %>% table()
.
alpha bravo 
    1     0 
> x[grep("alpha",x)] %>% as.character() %>% table()
.
alpha 
    1 

複数系列ある場合は、as.charcter() の代わりに以下のような関数を用いると良いだろう。
(function(df){for(k in names(df)){df[,k]=as.character(df[,k])};df})
as.charcter 突っ込んだ sapply() をパイプ(%>%)で使うとこれと同じことがもっと簡単に出来る。
sapply(as.character)