須通り
Sudo Masaaki official site
For the reinstatement of
population ecology.

ホーム | 統計 Top | Rにおける分割表の基本的な扱い方

目次

Rで取り扱うための二次元の分割表データを作成する

手入力の場合は、とりあえずmatrix()関数で行列を作ればいい。

> example22 <- matrix( c(67,128, 155,180), nrow=2, byrow=T) ##2×2分割表のテストデータ作成
> example22 ##表示してみう
      [,1] [,2]
[1,]    67  128
[2.]   155  180

> example24 <- matrix( c(67,128,3,22, 155,180,9,49), nrow=2, byrow=T) ##2×4分割表のテストデータ作成
> example24 ##表示してみう
     [,1] [,2] [,3] [,4]
[1,]   67  128    3   22
[2,]  155  180    9   49
 
> example42 <- matrix( c(67,128,3,22, 155,180,9,49), nrow=4, byrow=T) ##4×2分割表のテストデータ作成
> example42 ##表示してみう
     [,1] [,2]
[1,]   67  128
[2,]    3   22
[3,]  155  180
[4,]    9   49

##2×4のときとは区切り位置が変わっていることに注意
    

いっぽう、既存のデータフレームを集計して分割表を作る(クロス集計)場合には、xtab()関数が使える。まず、データフレームの各行が1つのデータ点を表す事例から。これは例えばアンケート結果の集計で、各回答者の答えを順次書き連ねて長い表を作成したような場合に該当する。

##テスト用のデータフレームを作成
> prefecture    <- c( rep("Saitama",30), rep("Gunma",25) )
> sex <- c( rep("F",18), rep("M",12), rep("F",10), rep("M",15) )
> test.frame <- data.frame(PREF=prefecture, SEX=sex)

> head(test.frame) ##データフレームの冒頭を試しに表示してみう(head関数:デフォルトではデータ行の1行目から6行目まで)
     PREF SEX
1 Saitama   F
2 Saitama   F
3 Saitama   F
4 Saitama   F
5 Saitama   F
6 Saitama   F

> xtabs(~PREF+SEX, data=test.frame) ##クロス集計を行う。
         SEX
PREF       F  M
  Gunma   10 15
  Saitama 18 12
    

なお関数の()内であるが、~PREF+SEXというのが集計の形を表す式(フォーミュラ)である。チルダ~は方程式における等号のようなもので、~以降の部分が式の右辺となり、集計基準となる変数(カテゴリ変数)が記される。左辺はこの場合、空白である(ゆえに、データの度数=条件に当てはまるデータ行の数として集計される)。

データフレームとxtab()関数を用いたクロス集計のやり方は、上に挙げたもの以外にもう1つある。

別の方法でテストデータ作成
> prefecture <- c( rep("Saitama",4), rep("Gunma",4) )
> sex <- c("F", "F", "M", "M" )
> month <- c("July","August")
> frequency <- c(10,8,2,10,4,6,7,8) ##各カテゴリに当てはまるデータ点数(頻度)を直接打ち込んでやる

> (test.frame2 <- data.frame(PREF=prefecture, SEX=sex,MONTH=month, FREQ=frequency) )
     PREF SEX  MONTH FREQ
1 Saitama   F   July   10
2 Saitama   F August    8
3 Saitama   M   July    2
4 Saitama   M August   10
5   Gunma   F   July    4
6   Gunma   F August    6
7   Gunma   M   July    7
8   Gunma   M August    8

> xtabs(~PREF+SEX, data=test.frame2) ##左辺を指定せずにクロス集計を行う。
         SEX
PREF      F M
  Gunma   2 2
  Saitama 2 2
  
> xtabs(FREQ~PREF+SEX, data=test.frame2) ##左辺を指定してクロス集計を行う。
         SEX
PREF       F  M
  Gunma   10 15
  Saitama 18 12
    

先ほどはデータフレーム内の各行が個別のデータを表すものとして扱われたが、今度はデータフレーム内の変数FREQとして、予め頻度の値が格納されている。これをxtab()関数のフォーミュラの左辺に指定することによっても、クロス集計を実施できる。

いずれにせよ、xtab()関数が生成する2次元の行列データ(なお右辺カテゴリを3つ以上指定した場合は3次元、4次元、…n次元の配列になる)は、分析用の関数に別途ネストしたり適切なオブジェクト名に代入したりすれば、分割表として簡単に扱うことが出来る。

二次元分割表の独立性検定を行う

有意差の有無を知りたいだけなら、現代のコンピュータ環境ではFisherの正確確率検定を実施するのが無難である。計算には関数fisher.test()を使い、引数として行列形式の分割表データを指定する。

> example22 ##2×2分割表のテストデータ
      [,1] [,2]
[1,]    67  128
[2.]   155  180

> fisher.test(example22)

        Fisher's Exact Test for Count Data

data:  example22 
p-value = 0.008121
alternative hypothesis: true odds ratio is not equal to 1 
95 percent confidence interval:
 0.4141758 0.8894265 
sample estimates:
odds ratio 
 0.6084424 
 
##以下の書き方でも同様に計算できる
fisher.test( matrix( c(67,128, 155,180), nrow=2, byrow=T))
    

この手法は階乗計算を含むため、コンピュータの普及以前にはカイ二乗検定などの代替手段が用いられていた。また意外に知られていないが、2×2より大きな分割表についても直接確率を計算することができる。

> example24  ##2×4分割表のテストデータ
     [,1] [,2] [,3] [,4]
[1,]   67  128    3   22
[2,]  155  180    9   49

> fisher.test(example24)

        Fisher's Exact Test for Count Data

data:  example24 
p-value = 0.03342
alternative hypothesis: two.sided 

実のところfisher.test()は可愛い顔してえげつないマシンパワーを要する関数なので、以下のような場合には入念にヘルプを参照されたい(バッファ不足で演算が止まることがあり、設定を弄ると回避できる)。

  • 2×2より大きな分割表で、しかも各セルのデータ(i.e. 度数)が大きい
  • パソコンが古い

三次元以上の分割表を扱う

上で述べたクロス集計の手順において、xtabs()関数の右辺のカテゴリを3つ以上指定する、あるいは高次元の配列データを手作業で作成してやることにより、曲がりなりにも三次元以上の分割表をRで作成することは可能だ。

##テストデータ作成(上で用いたものと同じです)
> prefecture <- c( rep("Saitama",4), rep("Gunma",4) )
> sex <- c("F", "F", "M", "M" )
> month <- c("July","August")
> frequency <- c(10,8,2,10,4,6,7,8)
> (test.frame2 <- data.frame(PREF=prefecture, SEX=sex,MONTH=month, FREQ=frequency) )
     PREF SEX  MONTH FREQ
1 Saitama   F   July   10
2 Saitama   F August    8
3 Saitama   M   July    2
4 Saitama   M August   10
5   Gunma   F   July    4
6   Gunma   F August    6
7   Gunma   M   July    7
8   Gunma   M August    8
  
> xtabs(FREQ~PREF+SEX, data=test.frame2) ##二次元のクロス集計を行う(前掲)
         SEX
PREF       F  M
  Gunma   10 15
  Saitama 18 12

> xtabs(FREQ~MONTH+SEX+PREF, data=test.frame2) ##三次元のクロス集計を行う
, , PREF = Gunma

        SEX
MONTH     F  M
  August  6  8
  July    4  7

, , PREF = Saitama

        SEX
MONTH     F  M
  August  8 10
  July   10  2
    

ただし実用的な観点で言うと三次元分割表の解釈は煩雑であり、四次元以上の分割表に至っては最早、人間が直感的に理解できる代物ではない。そのような解析デザインを使わずともよい簡便な研究計画を練るのが最善策であり、次善としては(目的変数を明確にした上で)一般化線形モデル等の使用を考慮すべきであろう。