二変数の分割表(クロス表)

 調査結果の報告においては,高度な分析をするだけではなく,収集した情報の基本的な集計結果を示す事も重要になる。しかしRでは,度数分布表(単純集計表などとも呼ばれる)や分割表(連関表,クロス表)について,必要最低限の結果を出力するコマンドが基本で,色々な情報を纏めて提示する為には自分で少し手を加える必要がある。
 以下では,学部学生の演習レヴェルであると便利だと思われる作表方法を紹介する。

模擬データの作成

 以下は,二つの変数(5件法と4件法,NA混じり)を発生させて,それを(敢えて)データ・フレイムにしている。何故敢えてデータ・フレイムにしているかと言えば,通常社会調査データはcsvファイルでデータを作成し,それをデータ・フレイムとしてRに読み込んで分析するので,それに近い状態を再現する為である。

n <- 125
q01 <- sample(c(1, 2, 3, 4, 5, NA), size=n, replace=T, prob=c(.25, .15, .20, .20, .15, .05))
q02 <- sample(c(1, 2, 3, 4, NA), size=n, replace=T, prob=c(.30, .20, .20, .25, .05))
d01 <- data.frame(q01, q02)

 それぞれの変数にアクセスする為には,d01$q01,d01$q02とする事になる。

二つのカテゴリカル変数の分割表(クロス表)

 社会学でクロス表と呼ぶ事の多い分割表(連関表; contingency table)は二つのカテゴリカル変数の集計表であるが,これを作成するRの関数も table( ) である。table( ) に二つの変数を引数で与えると二変数の分割表になる。一変数の場合と同じく,useNA=オプションを指定しないとNAを除外した表になる。
 table( ) で作成した分割表は表の本体だけであるが,集計結果を示す場合には,行周辺度数・列周辺度数なども併せて表示する。table( ) で作成された分割表が t01 と云うオブジェクトに格納されているとすると,周辺度数を付加した表は,addmargins( ) 関数にt01を引数として与えれば作成される。
 大抵の場合,度数ではなく相対度数の表も作成したい。関数は一変数の時と同じ prop.table( ) 関数である。何もオプションを付けないと全体%の表になり,margin=1 と云うオプションを付けると行%の表になる。margin=2 では列%の表である。
 以上を例示する。オブジェクト名は適当であり,自由に付けてよい。

table(d01$q01, d01$q02)
   
     1  2  3  4
  1 12  5  7 13
  2  8  2  0  3
  3  8  2 10  2
  4 10  6  6  6
  5  3  1  4  6
table(d01$q01, d01$q02, useNA="ifany")
      
        1  2  3  4 <NA>
  1    12  5  7 13    0
  2     8  2  0  3    0
  3     8  2 10  2    0
  4    10  6  6  6    1
  5     3  1  4  6    3
  <NA>  4  1  1  0    1
prop.table(table(d01$q01, d01$q02), margin=1)
   
             1          2          3          4
  1 0.32432432 0.13513514 0.18918919 0.35135135
  2 0.61538462 0.15384615 0.00000000 0.23076923
  3 0.36363636 0.09090909 0.45454545 0.09090909
  4 0.35714286 0.21428571 0.21428571 0.21428571
  5 0.21428571 0.07142857 0.28571429 0.42857143
prop.table(table(d01$q01, d01$q02), margin=2)
   
             1          2          3          4
  1 0.29268293 0.31250000 0.25925926 0.43333333
  2 0.19512195 0.12500000 0.00000000 0.10000000
  3 0.19512195 0.12500000 0.37037037 0.06666667
  4 0.24390244 0.37500000 0.22222222 0.20000000
  5 0.07317073 0.06250000 0.14814815 0.20000000
prop.table(table(d01$q01, d01$q02))
   
             1          2          3          4
  1 0.10526316 0.04385965 0.06140351 0.11403509
  2 0.07017544 0.01754386 0.00000000 0.02631579
  3 0.07017544 0.01754386 0.08771930 0.01754386
  4 0.08771930 0.05263158 0.05263158 0.05263158
  5 0.02631579 0.00877193 0.03508772 0.05263158
addmargins(table(d01$q01, d01$q02))
     
        1   2   3   4 Sum
  1    12   5   7  13  37
  2     8   2   0   3  13
  3     8   2  10   2  22
  4    10   6   6   6  28
  5     3   1   4   6  14
  Sum  41  16  27  30 114

 with( ) と round( ) を使い,適宜オブジェクト保存してもう少し見易くしよう。  

t01 <- with(d01, table(q01, q02)); t01
   q02
q01  1  2  3  4
  1 12  5  7 13
  2  8  2  0  3
  3  8  2 10  2
  4 10  6  6  6
  5  3  1  4  6
t01T <- with(d01, table(q01, q02, useNA="ifany")); t01T
      q02
q01     1  2  3  4 <NA>
  1    12  5  7 13    0
  2     8  2  0  3    0
  3     8  2 10  2    0
  4    10  6  6  6    1
  5     3  1  4  6    3
  <NA>  4  1  1  0    1
pr01 <- prop.table(t01, margin=1); round(pr01*100, 1)
   q02
q01    1    2    3    4
  1 32.4 13.5 18.9 35.1
  2 61.5 15.4  0.0 23.1
  3 36.4  9.1 45.5  9.1
  4 35.7 21.4 21.4 21.4
  5 21.4  7.1 28.6 42.9
pc01 <- prop.table(t01, margin=2); round(pc01*100, 1)
   q02
q01    1    2    3    4
  1 29.3 31.2 25.9 43.3
  2 19.5 12.5  0.0 10.0
  3 19.5 12.5 37.0  6.7
  4 24.4 37.5 22.2 20.0
  5  7.3  6.2 14.8 20.0
ps01 <- prop.table(t01); round(ps01*100, 1)
   q02
q01    1    2    3    4
  1 10.5  4.4  6.1 11.4
  2  7.0  1.8  0.0  2.6
  3  7.0  1.8  8.8  1.8
  4  8.8  5.3  5.3  5.3
  5  2.6  0.9  3.5  5.3
t01m <- addmargins(t01); t01m
     q02
q01     1   2   3   4 Sum
  1    12   5   7  13  37
  2     8   2   0   3  13
  3     8   2  10   2  22
  4    10   6   6   6  28
  5     3   1   4   6  14
  Sum  41  16  27  30 114

集計表の項目ラベル

 SPSSでは変数に変数ラベル,値に値ラベルを定義する事が出来,出力を見易くする事が出来るが,Rはこの点については余り親切ではない。もっとも特に値ラベルについては,実体としての数値が何であるかが分からなくなって却って初心者が間違える場合もあるので,うまく付けないと(或いは適切に表示オプションを設定しないと)便利ではなくなる。
 いずれにせよRでも出力を分かり易くする方法は知っておいた方が良いので,ここでは分割表にラベルを付ける単純な方法を紹介する。
 まずは模擬データを生成する。

n <- 125
sex <- sample(c(1, 2, 3), size=n, replace=T, prob=c(.45, .50, .05))
school <- sample(c(9, 12, 14, 16, 18), size=n, replace=T, prob=c(.10, .30, .10, .35, .15))

d02 <- data.frame(ID = 1:n, sex, school)
head(d02)

このデータで,性別の度数分布表や,性別と教育年数の分割表を作成すると次の様になる。

with(d01, table(sex))
sex
 1  2  3 
49 71  5 
with(d01, table(sex, school))
   school
sex  9 12 14 16 18
  1  5 15  4 17  8
  2  6 23  8 22 12
  3  1  2  2  0  0

SPSSの様な変数ラベルや値ラベルがついていないので,これだけでは分りにくい。
まずは,性別の度数分布表をオブジェクトに格納して,値ラベル(value label)を付けてみよう。

t10 <- with(d01, table(sex))
rownames(t10) <- c("1 男性", "2 女性", "3 その他")

t10
sex
  1 男性   2 女性 3 その他 
      49       71        5 

 これで情報が読み取り易くなったが,依然として変数ラベル(variable label)は付いていない。変数ラベルを付けるには次の様にする。    

names(dimnames(t10)) <- "性別 sex"
t10
性別 sex
  1 男性   2 女性 3 その他 
      49       71        5 

 これと同様にして,分割表の行と列にもラベルを付けよう。  

t11 <- with(d01, table(sex, school))
rownames(t11) <- c("1 男性", "2 女性", "3 その他")
colnames(t11) <- c("1 中学", "2 高校", "3 短大", "4 四大", "5 院")
names(dimnames(t11)) <- c("性別 sex", "最終学歴 school")

t11
          最終学歴 school
性別 sex   1 中学 2 高校 3 短大 4 四大 5 院
  1 男性        5     15      4     17    8
  2 女性        6     23      8     22   12
  3 その他      1      2      2      0    0

 変数そのものにラベルを貼り付けるのとは違って集計表の行や列に名前を付けているだけなので,正直このやり方ではいちいち非常に面倒であり,SPSS的な変数ラベル,値ラベルを使いたいと思う事も多いだろう。しかしそこは逆に,常に値とラベルの対応に注意させられる事で,ラベルに惑わされて実態としての値(数字)を取り違え,処理や解釈を誤ると云うリスクがなくなると前向きに考えておこう(実際初心者がSPSSを使う場合にこのリスクは小さくない)。Rで変数ラベル,値ラベルを使用可能にする工夫も幾つか開発されているようが,ここでは極力追加アプリケイションや追加パッケイジをインストールしなくて済む方法を紹介しようとしているので,割愛する。

分割表をそのまま図示する

分割表をグラフ表示するには,伝統的な帯グラフよりはモザイク・プロットの方が良い。
そうでなければ横に並べた棒グラフだろう。
断っておくがこれは全くの架空のデータである。

mosaicplot(t11, col=terrain.colors(dim(t11)[2]))

barplot(t(t11), beside = T, col=terrain.colors(dim(t11)[2]), legend=T)

mosaicplot(t11, shade=T)