度数とクロス集計
カテゴリカル変数のクロス集計表 (分割表) 、独立性の検定、連関、グラフ化について説明する。
度数表をつくる
度数表 (frequency table, 分割表/contingency table 、クロス集計表/cross-tab ともいう) を作成する方法はいくつかある。以下にその例を示す。また、青木先生のfrequency 関数も便利。
table 関数
table( ) 関数で度数表が作成できる。割合を算出したいときはe prop.table( ) 関数, 合計欄には margin.table( ) 関数が使える。
# 2元の度数表
mytable <- table(gear=mtcars$gear, carb=mtcars$carb) # "gear=..."としないと名前のない表になるので見づらい。
mytable
# 集計欄
margin.table(mytable, 1) # 行の合計
margin.table(mytable, 2) # 列の合計)
# 表に集計行を追加
addmargins(mytable)
# パーセンテージ
prop.table(mytable) # セルのパーセンテージ
prop.table(mytable, 1) # 行のパーセンテージ
prop.table(mytable, 2) # 列のパーセンテージ
# パーセンテージ (+ 合計欄) の関数
cprp <- function(x, p=1) {
xn <- addmargins(x)
cp <- t(t(xn)/xn[nrow(xn),]*p)[-nrow(xn), -ncol(xn)]
rp <- (xn/xn[, ncol(xn)]*p)[-nrow(xn), -ncol(xn)]
pt <- prop.table(x)
return(list(adm=xn, cp=cp, rp=rp, pt=pt))
}
cprp(mytable)
table( ) 関数は3元以上の集計表も作成できる。ただし、この場合は ftable( ) 関数を使って"flat"な表を作ったほうが見やすい。
# 3元の集計表
attach(mtcars)
mytable <- table(am, gear, carb)
mytable
ftable(mytable)
table 関数は欠損値を除いて集計する。 NAを含めたいときはtable関数の中でexclude=NULLと指定する。
x <- c(1,1,2,2,NA)
fx <- factor(c("a", "a", "b", "b", NA))
x
fx
table(x) # NAは表示されない。
table(fx)
table(x, exclude=NULL) # NAも集計される
table(fx, exclude=NULL)
nfx <- factor(fx, exclude=NULL)
levels(nfx) # 新しい因子変数を作るとNAが水準として認識される。
度数が0の項目を集計する(集計する項目を特定する)には、levelsオプションを指定してfactor変数にする。
x <- factor(1:2, levels=1:3)
y <- factor(c(1,3), levels=1:3)
xy <- data.frame(x,y)
table(xy)
# levelsを指定しない場合度数0がカウントされない。
x <- factor(1:2)
y <- factor(c(1,3))
xy <- data.frame(x,y)
table(xy)
xtabs関数
xtabs( ) 関数は数式形式で記述し、クロス集計表を作成する。
# 3元の集計表
mytable <- xtabs(~gear+carb+am, data=mtcars)
mytable # amで分割し、gearを行に、carbを列にする
ftable(mytable) # 見やすく表示
summary(mytable) # 独立性のカイ二乗検定
数式左辺に数値変数を記述すると、その変数は度数を表すものとして解釈され、集計が行われる。集計表をさらに計算するときなどに使う。
# 例示用データ
cls <- sample(c("red", "blue", "yellow"), 20, replace=T)
freq <- sample(1:5, 20, replace=T)
data.frame(cls, freq)
# これだと"red", "blue", "yellow" と "1", "2", .. "5" のクロス集計になる
xtabs(~freq+cls)
# こうするとfreqを度数として解釈し、合計を出す。
xtabs(freq~cls)
aggregate(freq, list(cls), sum) # つまりこれと同じ。
Crosstable 関数
gmodels パッケージのCrossTable( ) 関数はいろいろオプションが選べて便利。出力が昔のSASっぽい。
# 2元のクロス集計
library(gmodels)
CrossTable(mtcars$gear, mtcars$carb)
# 中身を見てみる
CTres <- CrossTable(mtcars$gear, mtcars$carb)
CTres # リストになってる
cprp(table(mtcars$gear, mtcars$carb)) # これと同じだった。やはり自分が欲しい関数はどっかでだれかが作っているのだ。
オプションで行列パーセントの表示を選べる。また、カイ二乗検定、フィッシャーの正確確率検定、マクネマー検定を実行できる。残差も出力できる。欠損値をケースに含めることもできる。詳しくはhelp(CrossTable) 。
独立性の検定
カイ二乗検定
2元の分割表はchisq.test( ) 関数で独立性の検定を行うことができる。デフォルトのp値は近似カイ二乗分布に基づくものである。オプションでモンテカルロシミュレーションでのp値を求めることができる。
# 心理統計学の基礎 p186
x <- c(12,10,4,14)
tx <- as.table(matrix(x, nr=2, dimnames=list(A=c("aru", "nai"), B=c("aru", "nai"))))
chires <- chisq.test(tx, correct=F) # 教科書と同じ結果、補正なし
chires$expected # 期待度数
str(chires) # その他の計算されるもの
chisq.test(tx) # デフォルト
chisq.test(tx, simulate.p.value=T) # モンテカルロシミュレーションでのp値
Fisher の直接確率検定
fisher.test(x) 関数で行う。x には2元のクロス集計表をオブジェクトとしてあたえる。
fisher.test(tx)
# spssの実行例。UCLAのサイトから
library(foreign)
dat <- read.spss("http://www.ats.ucla.edu/stat/spss/webbooks/reg/hsb2.sav", to.data.frame=T)
names(dat) <- tolower(names(dat))
tb <- table(dat$schtyp, dat$female)
tb
fisher.test(tb)
Mantel-Haenszel 検定
mantelhaen.test(x) 関数を用いる。xには3元のクロス集計表を与える。このうち、2つの要因の独立性を検定する。
# spssの実行例と一致。 uclaのサイトから。
tb <-array(c(
8,21, 2,35,
11,10, 2,13,
4, 7, 1,22,
19, 7, 2, 4),
dim = c(2,2,4),
dimnames = list(cat=1:0, iccpr=1:0, area=1:4))
tb
mantelhaen.test(tb)
対数線型モデル
MASSパッケージの loglm( )関数で実行できる。以下の例は立命館大学のspssのものから。結果は一致する。
# データの準備。3元のクロス集計表
tb <-array(c(
42,23,79,65,32,17,
4,11,12,41,8,24),
dim = c(2,3,2),
dimnames = list(
fault=c("low", "high"),
moral=c("high", "neutral", "low"),
verdict=c("guilty", "not guilty")))
tb
# 対数線形モデルの実行
library(MASS)
# 交互作用をすべて含むモデル
fit1 <- loglm(~fault+moral+verdict+fault*moral+fault*verdict+moral*verdict, data=tb)
fit1
# fault*verdictを除外したモデル
fit2 <- loglm(~fault+moral+verdict+fault*moral+moral*verdict, data=tb)
fit2
# 両モデルの比較
anova(fit1, fit2)
モザイクプロットの例および対数線形モデルの解説:Visualizing Loglinear Models
glmを使った例:analyzing loglinear models
連関
vcdパッケージのassocstats(tb) 関数を使うとファイ係数 (Phi-Coefficient) , 一致係数 (Contingency Coeff) 、クラメールの連関係数 (Cramer's V) がわかる。参考:
また、kappa(tb)関数でCohenのカッパ係数、重みづきカッパ係数がわかる。
参考:
名義尺度間の相関
Measures of Association in Crosstab Tables
# 心理統計学の基礎 p186
x <- c(12,10,4,14)
tb <- as.table(matrix(x, nr=2, dimnames=list(A=c("aru", "nai"), B=c("aru", "nai"))))
library(vcd)
assocstats(tb)
kappa(tb)
結果の視覚化
1次元のデータであれば 棒グラフや and 円グラフを使う。
複数のカテゴリカルデータの場合は vcd パッケージが利用できる (モザイクや連関プロット) 。
対応分析を行うca パッケージも使える。
集計表の変換
データの準備。3元のクロス集計表
tb <-array(c(
42,23,79,65,32,17,
4,11,12,41,8,24),
dim = c(2,3,2),
dimnames = list(
fault=c("low", "high"),
moral=c("high", "neutral", "low"),
verdict=c("guilty", "not guilty")))
tb
# フラットな表にする
ftable(tb)
data.frame(ftable(tb))
data.frame(tb) # 見づらい
# 元のデータを生成する。
x <- data.frame(ftable(tb))
x2 <- data.frame( lapply (x, function(i) rep(i, x[,"Freq"]))[-4])
x2
table(x2) # tbと同じ