備忘ログ

チラシの裏的備忘録&メモ

`ftable`を二次元の`table`にしたい、そして名前も残したい

Rで多次元配列のtableftable()で二次元配列っぽく表現したものをftableから二次元のtableに変換したいと思った。ちょっと調べてみても見つけられなかったので、この方法が妥当かわからなかいがメモしておく。

例として組み込みデータのHairEyeColorを使ってみる。

HairEyeColor
## , , Sex = Male
## 
##        Eye
## Hair    Brown Blue Hazel Green
##   Black    32   11    10     3
##   Brown    53   50    25    15
##   Red      10   10     7     7
##   Blond     3   30     5     8
## 
## , , Sex = Female
## 
##        Eye
## Hair    Brown Blue Hazel Green
##   Black    36    9     5     2
##   Brown    66   34    29    14
##   Red      16    7     7     7
##   Blond     4   64     5     8

ftable()をつかって2次元配列っぽくしてみる。よく見慣れた感じになる。

ftable(HairEyeColor, row.vars = c("Hair", "Sex"))
##              Eye Brown Blue Hazel Green
## Hair  Sex                              
## Black Male          32   11    10     3
##       Female        36    9     5     2
## Brown Male          53   50    25    15
##       Female        66   34    29    14
## Red   Male          10   10     7     7
##       Female        16    7     7     7
## Blond Male           3   30     5     8
##       Female         4   64     5     8

このままas.table()をすると、層化されたtableが出てくる。

as.table(ftable(HairEyeColor, row.vars = c("Hair", "Sex")))
## , , Eye = Brown
## 
##        Sex
## Hair    Male Female
##   Black   32     36
##   Brown   53     66
##   Red     10     16
##   Blond    3      4
## 
## , , Eye = Blue
## 
##        Sex
## Hair    Male Female
##   Black   11      9
##   Brown   50     34
##   Red     10      7
##   Blond   30     64
## 
## , , Eye = Hazel
## 
##        Sex
## Hair    Male Female
##   Black   10      5
##   Brown   25     29
##   Red      7      7
##   Blond    5      5
## 
## , , Eye = Green
## 
##        Sex
## Hair    Male Female
##   Black    3      2
##   Brown   15     14
##   Red      7      7
##   Blond    8      8

これもこれで良いが今回は二次元のクロス集計表のままがよい。

表の形で値だけを取り出したかったら次のようにして取り出せる。

ftable(HairEyeColor, row.vars = c("Hair", "Sex"))[]
##      [,1] [,2] [,3] [,4]
## [1,]   32   11   10    3
## [2,]   36    9    5    2
## [3,]   53   50   25   15
## [4,]   66   34   29   14
## [5,]   10   10    7    7
## [6,]   16    7    7    7
## [7,]    3   30    5    8
## [8,]    4   64    5    8
## attr(,"row.vars")
## attr(,"row.vars")$Hair
## [1] "Black" "Brown" "Red"   "Blond"
## 
## attr(,"row.vars")$Sex
## [1] "Male"   "Female"
## 
## attr(,"col.vars")
## attr(,"col.vars")$Eye
## [1] "Brown" "Blue"  "Hazel" "Green"
# 扱いやすいように`ftable()`で作ったオブジェクトをHair.ftableとおいて作る。
Hair.ftable <- ftable(HairEyeColor, row.vars = c("Hair", "Sex"))
# as.table()でtable化しようとすると名前がアルファベットになってしまう。
as.table(Hair.ftable[])
##    A  B  C  D
## A 32 11 10  3
## B 36  9  5  2
## C 53 50 25 15
## D 66 34 29 14
## E 10 10  7  7
## F 16  7  7  7
## G  3 30  5  8
## H  4 64  5  8

値だけを取り出したかったらこれでも良いが、名前がきえるとちょっと扱いにくい。

名前付き、しかもできればもともとあった名前を組み合わせた名前になっていると嬉しい。そこで、as.matrix()でmatrix化してからas.table()でtable化するとある程度希望が通る。

as.table(as.matrix(Hair.ftable))
##               Eye
## Hair_Sex       Brown Blue Hazel Green
##   Black_Male      32   11    10     3
##   Black_Female    36    9     5     2
##   Brown_Male      53   50    25    15
##   Brown_Female    66   34    29    14
##   Red_Male        10   10     7     7
##   Red_Female      16    7     7     7
##   Blond_Male       3   30     5     8
##   Blond_Female     4   64     5     8
# 当たり前だが、ちゃんとクラスもtableになっている。
class(as.table(as.matrix(Hair.ftable)))
## [1] "table"

名前を任意で調整したかったらもう少し調整が必要になると思う。

as.matrix()as.table()入れ子構造にしているが当然パイプでも繋げられる。