在本节中我们将着眼于类别型变量的频数表和列联表,以及相应的独立性检验,相关性度量。
在本节中我们除了使用基础安装中的函数,还将连带使用vcd包和gmodels包中的函数。
本节使用的数据时来自包vcd中的Arthritis数据集,这是一个关于风湿性关节炎新疗法的双盲实验结果
> library(vcd)
载入需要的程辑包:grid
Warning message:
程辑包‘vcd’是用R版本3.6.1 来建造的
> head(Arthritis)
ID Treatment Sex Age Improved
1 57 Treated Male 27 Some
2 46 Treated Male 29 None
3 77 Treated Male 30 None
4 17 Treated Male 32 Marked
5 36 Treated Male 46 Marked
6 23 Treated Male 58 Marked
>
1,生成频数表
R中提供了用于创建频数表和列联表的若干方法,方法如下
table(var1,var2,var3,…,varN) 使用N个类别型变量创建一个N维列联表
注意table()函数默认忽略缺失值的,要在频数统计中将NA视为一个有效的类别,可以使用参数useNA=“ifany”
xtabs(formula,data) 根据一个公式和一个矩阵或数据框创建一个N维列联表,效果和table()一样只是格式不一样
prop.tabe(table,margins) 对表格进行分数话处理,
margins设置是行分数话还是列分数话,如果是行分数话的话就是行中的每个数值都是table中每行中的数值占这一行总和的比值,这一行的总和为1
margin.table(table,margins) 依margins定义的边际列表计算各条目的和,就和Excel中的行总计或者列总计一样
addmargins(table,margins) 将概述边margins(默认是求和结果)放入表中,就像excel中的行总计和列总计放入在原来表格中的效果(不止是总计其他总结性函数也可以)
ftable(table) 创建一个紧凑的“平铺”式列表
一维列联表
> #使用table()函数生成简单的频数统计表示例如下
> mytable <- table(Arthritis$Improved)
> mytable
None Some Marked
42 14 28
> #使用prop.table()将这些频数转化为比例值
> #注意一维列联表不用指定margins(行或者列)
> prop.table(mytable)
None Some Marked
0.5000000 0.1666667 0.3333333
> #使用prop.table()*100转化为百分比话
> prop.table(mytable)*100
None Some Marked
50.00000 16.66667 33.33333
二维列联表
对于二维列联表,table()函数的使用格式为
mytable <- table(A,B)
其中A是行变量,B是列变量
xlabs()函数还可以使用公式风格的输入创建列联表。其格式为
mytable <- xtabs(~A + B,data=mydata)
mydata是一个矩阵或数据框,要进行交叉分类的变量应出现在公式的右侧,做某个变量写在公式的右侧,则其为一个频数向量(这句没有明白啥意思)
> #例子
> mytable <- xtabs(~Treatment + Improved, data=Arthritis)
> mytable
Improved
Treatment None Some Marked
Placebo 29 7 7
Treated 13 7 21
> #使用margin.table()函数生成边际频数
> #行汇总
> margin.table(mytable,margin = 1)
Treatment
Placebo Treated
43 41
> #列汇总
> margin.table(mytable,margin = 2)
Improved
None Some Marked
42 14 28
> #对于margin.table当不指定margin时,它会得到表格中所有数值总和
> margin.table(mytable)
[1] 84
> #使用prop.table()函数生成比例
> #行比例
> prop.table(mytable,margin = 1)
Improved
Treatment None Some Marked
Placebo 0.6744186 0.1627907 0.1627907
Treated 0.3170732 0.1707317 0.5121951
> #列比例
> prop.table(mytable,margin = 2)
Improved
Treatment None Some Marked
Placebo 0.6904762 0.5000000 0.2500000
Treated 0.3095238 0.5000000 0.7500000
> #对于prop.table当不指定margin时,它会得到表格中所有数值总和的占比
> prop.table(mytable)
Improved
Treatment None Some Marked
Placebo 0.34523810 0.08333333 0.08333333
Treated 0.15476190 0.08333333 0.25000000
> #使用addmargins()函数为表格添加边际和,在默认情况下是为表中所有的变量创建边际和,但是也可以指定只生成列或者行边际和
> addmargins(mytable)
Improved
Treatment None Some Marked Sum
Placebo 29 7 7 43
Treated 13 7 21 41
Sum 42 14 28 84
> #也可以只生成行或者列的边际和
> #当指定参数为1时生成列的边际和,指定为2时才生成行的边际行,与正常的1代表行2代表列相反
> #生成列边际和
> addmargins(mytable,1)
Improved
Treatment None Some Marked
Placebo 29 7 7
Treated 13 7 21
Sum 42 14 28
> #生成行边际和
> addmargins(mytable,2)
Improved
Treatment None Some Marked Sum
Placebo 29 7 7 43
Treated 13 7 21 41
> #addmargins与prop.table()联合使用
> addmargins(prop.table(mytable,1),2)
Improved
Treatment None Some Marked Sum
Placebo 0.6744186 0.1627907 0.1627907 1.0000000
Treated 0.3170732 0.1707317 0.5121951 1.0000000
> addmargins(prop.table(mytable,2),1)
Improved
Treatment None Some Marked
Placebo 0.6904762 0.5000000 0.2500000
Treated 0.3095238 0.5000000 0.7500000
Sum 1.0000000 1.0000000 1.0000000
> #addmargins()函数不仅仅只能生成边际和,也可以使用参数FUN指定地生成想要的其他结果比如平均值,方差等
> #生成边际平均值
> addmargins(mytable,FUN=mean)
Margins computed over dimensions
in the following order:
1: Treatment
2: Improved
Improved
Treatment None Some Marked mean
Placebo 29.00000 7.00000 7.00000 14.33333
Treated 13.00000 7.00000 21.00000 13.66667
mean 21.00000 7.00000 14.00000 14.00000
> #生成边际标准差
> addmargins(mytable,FUN=sd)
Margins computed over dimensions
in the following order:
1: Treatment
2: Improved
Improved
Treatment None Some Marked sd
Placebo 29.000000 7.000000 7.000000 12.701706
Treated 13.000000 7.000000 21.000000 7.023769
sd 11.313708 0.000000 9.899495 6.164414
>
使用gmodels包中的CrossTable()函数创建二维列联表
使用CrossTable不仅生成二维列联表,表中还会显示行列单元格的百分比,行列的边际和等,还可以通过参数指定生成各种列联表可以生成的值
> library(gmodels)
Warning message:
程辑包‘gmodels’是用R版本3.6.1 来建造的
> CrossTable(Arthritis$Treatment,Arthritis$Improved)
Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 84
| Arthritis$Improved
Arthritis$Treatment | None | Some | Marked | Row Total |
--------------------|-----------|-----------|-----------|-----------|
Placebo | 29 | 7 | 7 | 43 |
| 2.616 | 0.004 | 3.752 | |
| 0.674 | 0.163 | 0.163 | 0.512 |
| 0.690 | 0.500 | 0.250 | |
| 0.345 | 0.083 | 0.083 | |
--------------------|-----------|-----------|-----------|-----------|
Treated | 13 | 7 | 21 | 41 |
| 2.744 | 0.004 | 3.935 | |
| 0.317 | 0.171 | 0.512 | 0.488 |
| 0.310 | 0.500 | 0.750 | |
| 0.155 | 0.083 | 0.250 | |
--------------------|-----------|-----------|-----------|-----------|
Column Total | 42 | 14 | 28 | 84 |
| 0.500 | 0.167 | 0.333 | |
--------------------|-----------|-----------|-----------|-----------|
>
多维列联表
table()和xtabs都可以基于三个或更多的类别型变量生成多维列联表
margin.table(),prop.table()和addmargin()函数可以自然地推广到高于二维的情况
ftable()函数可以以一种紧凑而吸引人的方式输出多维列联表
> mytable <- xtabs(~Treatment + Sex + Improved, data=Arthritis)
> mytable
, , Improved = None
Sex
Treatment Female Male
Placebo 19 10
Treated 6 7
, , Improved = Some
Sex
Treatment Female Male
Placebo 7 0
Treated 5 2
, , Improved = Marked
Sex
Treatment Female Male
Placebo 6 1
Treated 16 5
> #使用ftable()函数生成紧凑的多维列表
> ftable(mytable)
Improved None Some Marked
Treatment Sex
Placebo Female 19 7 6
Male 10 0 1
Treated Female 6 5 16
Male 7 2 5
> #由于使用公式~Treatement+Sex+Improve创建了这个表,所有Treatment 需要通过下标1来引用,sex通过下标2来引用,Improve通过下标3来引用
> #边际频数
> #生成的边际频数指定的1,2,3所出的结果和xtabs中这三列出现的位置一致,指定1就是第一个出现的Treatment的频数
> margin.table(mytable)
[1] 84
> margin.table(mytable,1)
Treatment
Placebo Treated
43 41
> margin.table(mytable,2)
Sex
Female Male
59 25
> margin.table(mytable,3)
Improved
None Some Marked
42 14 28
> margin.table(mytable,c(1,2))
Sex
Treatment Female Male
Placebo 32 11
Treated 27 14
> ftable(prop.table(mytable,c(1,2)))
Improved None Some Marked
Treatment Sex
Placebo Female 0.59375000 0.21875000 0.18750000
Male 0.90909091 0.00000000 0.09090909
Treated Female 0.22222222 0.18518519 0.59259259
Male 0.50000000 0.14285714 0.35714286
> ftable(prop.table(mytable,c(1,3)))
Improved None Some Marked
Treatment Sex
Placebo Female 0.6551724 1.0000000 0.8571429
Male 0.3448276 0.0000000 0.1428571
Treated Female 0.4615385 0.7142857 0.7619048
Male 0.5384615 0.2857143 0.2380952
>
2,独立性检验
R提供了多种检验类别型变量独立性的方法。本节描述的三种检验分别为卡方独立性检验,Fisher精确检验和Cochran-Mantel-Haenszel检验
2.1卡方独立性检验
使用chisq.test()函数对二维表的行变量和列变量进行卡方独立性检验。
例子
> library(vcd)
载入需要的程辑包:grid
Warning message:
程辑包‘vcd’是用R版本3.6.1 来建造的
> mytable <- xtabs(~Treatment+Improved,data=Arthritis)
> #这里的P值表示从总体中抽取额样本行变量和列变量是相互独立的概率
> chisq.test(mytable)
Pearson's Chi-squared test
data: mytable
X-squared = 13.055, df = 2, p-value = 0.001463
> #患者的治疗和改善的水平存在存在着某种关系(p < 0.01)
> mytable <- xtabs(~Improved + Sex, data = Arthritis)
> chisq.test(mytable)
Pearson's Chi-squared test
data: mytable
X-squared = 4.8407, df = 2, p-value = 0.08889
2.2Fisher精确检验
在样本较小时,需要使用Fisher精确检验来完成独立性实验。
使用fisher.test()函数进行Fisher精确检验。Fisher精确检验的原假设是:边界固定的列联表中行和列是相互独立的。
需要注意的是fisher.test()函数不能用于2*2的列联表
例子
> mytable <- xtabs(~Treatment+Improved,data=Arthritis)
> fisher.test(mytable)
Fisher's Exact Test for Count Data
data: mytable
p-value = 0.001393
alternative hypothesis: two.sided
>
2.3 Cochran-Mantel-Haenszel检验
mantelhaen.test()函数可以用来进行Cochran-Mantel-Haenszel卡方检验,
其原假设是,两个名义变量在第三个变量的每一层中都是条件独立的
例子
> #检验治疗情况和改善情况在性别的每一水平下是否独立。此假设不存在三阶交互作用
> mytable <- xtabs(~Treatment +Improved+ Sex , data=Arthritis)
> mantelhaen.test(mytable)
Cochran-Mantel-Haenszel test
data: mytable
Cochran-Mantel-Haenszel M^2 = 14.632, df = 2, p-value = 0.0006647
结果表明,患者接受的治疗与得到的改善在性别的每一水平下并不独立
2.4,相关性的度量
vcd包中的assocstats()函数可以用来计算二维列联表的phi系数,列联系数和Cramer’sV系数
library(vcd)
> mytable <- xtabs(~Treatment+Improved,data=Arthritis)
> assocstats(mytable)
X^2 df P(> X^2)
Likelihood Ratio 13.530 2 0.0011536
Pearson 13.055 2 0.0014626
Phi-Coefficient : NA
Contingency Coeff.: 0.367
Cramer's V : 0.394
> mytable
Improved
Treatment None Some Marked
Placebo 29 7 7
Treated 13 7 21
小节总结:
对于分类变量使用table()函数为频数表和列联表,
xtabs()函数和table()函数功能相同只是格式不同,
prop.table()对表格进行分数化处理,
margin.table()对表格进行汇总计算列或者行或者所有数值的和,
addmargins()像表格添加汇总项一般是各行或列的和也可以是均值等其他汇总方式。
ftable()函数使得创建一个紧凑的平铺式的列表。
对于表格进行独立性检验可以使用函数chisq.test(),fisher.test(),mantelhaen.test(),三种函数进行独立性检验。
当检验两个分类变量不独立时可以进行计算其相关性。vcd包中的assocstats()函数可以计算相关性