原文出处:https://www.jianshu.com/p/90ed27810474
在数据被组织成合适的形式后,可以使用图形探索数据,接下来是使用数值描述每个变量的分布,然后则是两两探索所选择变量之间的关系。
本章将评述用于生成基本的描述性统计量和推断统计量的R函数。
本节介绍分析连续型变量中心趋势、变化性和分布性的方法。
使用第1章中Motor Trend杂志的车辆路试(mtcars)数据集。重点关注每加仑汽油行驶英里数(mpg)、马力(hp)和车重(wt)。
> vars <- c("mpg", "hp", "wt")
> head(mtcars[vars])
> > #查看三个变量的数据
mpg hp wt
Mazda RX4 21.0 110 2.620
Mazda RX4 Wag 21.0 110 2.875
Datsun 710 22.8 93 2.320
Hornet 4 Drive 21.4 110 3.215
Hornet Sportabout 18.7 175 3.440
Valiant 18.1 105 3.460
将首先查看所有32中车型的描述性统计量,然后按照变速箱类型(am)和汽缸数(cyl)考察描述性统计量。变速箱类型是以0表示自动档、1表示手动档来编码的二分变量,汽缸数为4、5或6。
在描述性统计量的计算方面,R中的选择非常多。从基础安装中包含的函数开始,然后查看那么些用户贡献包中的扩展函数。
集中安装中,可用summary( )
函数获取描述性统计量。
代码清单7-1 通过summary( )
计算描述性统计量
> #7-1
> summary(mtcars[vars])
mpg hp wt
Min. :10.40 Min. : 52.0 Min. :1.513
1st Qu.:15.43 1st Qu.: 96.5 1st Qu.:2.581
Median :19.20 Median :123.0 Median :3.325
Mean :20.09 Mean :146.7 Mean :3.217
3rd Qu.:22.80 3rd Qu.:180.0 3rd Qu.:3.610
Max. :33.90 Max. :335.0 Max. :5.424
summary( )
函数提供了最小值、最大值、四分位数和数值型变量的均值,以及因子向量和逻辑型向量的频数统计。
第5章中的apply( )
函数或sapply( )
函数计算所选择的任意描述性统计量。对于sapply( )
函数,使用格式为:
sapply(x, FUN, options)
其中x是数据框(或矩阵),FUN为一个任意函数。如果指定了options,它们将被传递给FUN。可以在这里插入的典型函数有mean、sd、var、min、median、length、range和quantile。函数fivenum( )
可返回图基五数总括(即最小值、下四分位数、中位数、上四分位数和最大值)。
代码清单7-2 通过sapply( )
计算描述性统计量
> mystats <- function(x, na.omit=FALSE) { #na.omit为0不移除缺失观测的整行
+ if (na.omit)
+ x <- x[!is.na(x)] #如果存在缺失,则删除单个保留其他有效数据
+ m <- mean(x) #均值
+ n <- length(x) #有效观测数
+ s <- sd(x) #标准差
+ skew <- sum((x-m)^3/s^3)/n #偏度
+ kurt <- sum((x-m)^4/s^4)/n - 3 #峰度
+ return(c(n=n, mean=m, stdev=s, skew=skew, kurtosis=kurt))
+ }
> sapply(mtcars[vars], mystats)
mpg hp wt
n 32.000000 32.0000000 32.00000000 #观测数
mean 20.090625 146.6875000 3.21725000 #均值
stdev 6.026948 68.5628685 0.97845744 #标准差
skew 0.610655 0.7260237 0.42314646 #偏度
kurtosis -0.372766 -0.1355511 -0.02271075 #峰度
样本中的车型,每加仑汽油行驶英里数的平均值为20.1,标准差为6.0。分布呈现右偏(偏度+0.61),并且较正态分布稍平(峰度-0.37)。
如果只希望单纯地忽略缺失值,应当使用:
sapply(mtcars[vars], mystats, na.omit=TRUE)
Himsc包中的describe( )
函数可返回变量和观测的数量、缺失值和唯一值的数目、平均值、分位数,以及五个最大的值和五个最小的值。
代码清单7-3 通过Hmisc包中的describe( )
函数计算描述性统计量
> library(Hmisc)
> describe(mtcars[vars])
mtcars[vars]
3 Variables
32 Observations —————————————————————————– mpg n missing distinct Info Mean Gmd
.05
.10
32
0
25
0.999
20.09
6.796
12.00
14.34
.25
.50
.75
.90
.95
15.43
19.20
22.80
30.09
31.30 lowest :
10.4
13.3
14.3
14.7
15.0, highest:
26.0
27.3
30.4
32.4
33.9 —————————————————————————– hp n missing distinct Info Mean Gmd
.05
.10
32
0
22
0.997
146.7
77.04
63.65
66.00
.25
.50
.75
.90
.95
96.50
123.00
180.00
243.50
253.55 lowest :
52
62
65
66
91, highest:
215
230
245
264
335 —————————————————————————– wt n missing distinct Info Mean Gmd
.05
.10
32
0
29
0.999
3.217
1.089
1.736
1.956
.25
.50
.75
.90
.95
2.581
3.325
3.610
4.048
5.293 lowest :
1.513
1.615
1.835
1.935
2.140, highest:
3.845
4.070
5.250
5.345
5.424 —————————————————————————–
pastecs包中有一个名为stat..desc( )
的函数,可以计算种类繁多的描述性统计量。使用格式为:
stat.desc(x, basic=TRUE, desc=TRUE, norm=FALSE, p=0.95)
其中的x是一个数据框或时间序列。若basic=TRUE
(默认值),则计算其中所有值、空值、缺失值的数量,以及最小值、最大值、值域和综合。若desc=TRUE
(默认值),则计算中位数、平均数、平均数的标准误差,平局数置信度为95%的置信区间、方差、标准差以及变异系数。若norm=TRUE
(非默认),则返回正态分布的统计量,包括偏度和峰度(以及它们的统计显著程度)和Shapiro - Wilk正态检验结果。这里使用了p值来计算平均数的置信区间(默认为0.95)。
代码清单7-4 通过pastecs包中的stat.desc( )
函数计算描述性统计量
> library(pastecs)
> stat.desc(mtcars[vars])
mpg hp wt
nbr.val 32.0000000 32.0000000 32.0000000
nbr.null 0.0000000 0.0000000 0.0000000
nbr.na 0.0000000 0.0000000 0.0000000
min 10.4000000 52.0000000 1.5130000
max 33.9000000 335.0000000 5.4240000
range 23.5000000 283.0000000 3.9110000
sum 642.9000000 4694.0000000 102.9520000
median 19.2000000 123.0000000 3.3250000
mean 20.0906250 146.6875000 3.2172500
SE.mean 1.0654240 12.1203173 0.1729685
CI.mean.0.95 2.1729465 24.7195501 0.3527715
var 36.3241028 4700.8669355 0.9573790
std.dev 6.0269481 68.5628685 0.9784574
coef.var 0.2999881 0.4674077 0.3041285
psych包中的describe( )
函数,可以计算非缺失值的数量、平均数、标准差、中位数、截尾均值、绝对中位差、最小值、最大值、值域、峰度和平均值的标准误差。
代码清单7-5 通过psych包中的describe( )
计算描述性统计量
> library(psych)
> describe(mtcars[vars])
vars n mean sd median trimmed mad min max range skew
mpg 1 32 20.09 6.03 19.20 19.70 5.41 10.40 33.90 23.50 0.61
hp 2 32 146.69 68.56 123.00 141.19 77.10 52.00 335.00 283.00 0.73
wt 3 32 3.22 0.98 3.33 3.15 0.77 1.51 5.42 3.91 0.42
kurtosis se
mpg -0.37 1.07
hp -0.14 12.12
wt -0.02 0.17
psych包和Hmisc包均提供了名为describe( )
的函数。R在调用时优先调用最后载入的程序包中的。如果强制调用,可以使用Hmisc::describe( )
。
在比较多组个体或观测时,关注的焦点经常是各组的描述性统计信息。在R中完整这个任务有托干中方法,以变速箱类型各水平的描述性统计量开始。
在第5章中,介绍了整合数据的方法。可以使用aggregate( )
函数(5.6.2节)来分组获取描述性统计量。
代码清单7-6 使用aggregate( )
分组获取描述性统计量
> aggregate(mtcars[vars], by=list(am=mtcars$am), mean)
am mpg hp wt
1 0 17.14737 160.2632 3.768895
2 1 24.39231 126.8462 2.411000
> aggregate(mtcars[vars], by=list(am=mtcars$am), sd)
am mpg hp wt
1 0 3.833966 53.90820 0.7774001
2 1 6.166504 84.06232 0.6169816
注意list(am=mtcars$am)
的使用。如果使用的是list(mtcars$am)
,则am列被标注为Group.1而不是am。通过这个赋值指定了一个更有帮助的列标签。如果有多个分组变量,可以使用by=list(name1=groupvar1, name2=groupvar2, ... , groupvarN)
这样的语句。
但是,aggregate( )
仅允许在每次调用中使用平均数、标准差这样的单返回值函数。无法一次返回若干个统计量。此时可以使用by( )
函数,格式为:
by(data, INDICES, FUN)
其中data是一个数据框或矩阵,INDICES是一个因子或因子组成的列表,定义了分组,FUN是任意函数。
代码清单7-7 使用by( )
分组计算描述性统计量
> dstats <- function(x)sapply(x, mystats)
> myvars <- c("mpg", "hp", "wt")
> by(mtcars[myvars], mtcars$am, dstats)
mtcars$am: 0
mpg hp wt
n 19.00000000 19.00000000 19.0000000
mean 17.14736842 160.26315789 3.7688947
stdev 3.83396639 53.90819573 0.7774001
skew 0.01395038 -0.01422519 0.9759294
kurtosis -
0.80317826 -
1.20969733
0.1415676 --------------------------------------------------------- mtcars$am:
1 mpg hp wt n
13.00000000
13.0000000
13.0000000 mean
24.39230769
126.8461538
2.4110000 stdev
6.16650381
84.0623243
0.6169816 skew
0.05256118
1.3598859
0.2103128 kurtosis -
1.45535200
0.5634635 -
1.1737358
doBy包和psych包也提供了分组计算描述性统计量的函数。doBy包中的summaryBy( )
函数的使用格式为:
summaryBy(formula, data=dataframe, FUN=function)
其中的formula
接受以下的格式:
var1 + var2 + var3 + ... + varN ~ groupvar1 + groupvar2 + ... + groupvarN
在~
左侧的变量是需要分析的数值型变量,而右侧的变量是类别型的分组变量。function
可为任何内建或用户自编的R函数。
代码清单7-8 使用doBy包中的summaryBu( )
分组计算概述统计量
> library(doBy)
> summaryBy(mpg+hp+wt~am,data=mtcars, FUN=mystats)
am mpg.n mpg.mean mpg.stdev mpg.skew mpg.kurtosis hp.n hp.mean hp.stdev
1 0 19 17.14737 3.833966 0.01395038 -0.8031783 19 160.2632 53.90820
2 1 13 24.39231 6.166504 0.05256118 -1.4553520 13 126.8462 84.06232
hp.skew hp.kurtosis wt.n wt.mean wt.stdev wt.skew wt.kurtosis
1 -0.01422519 -1.2096973 19 3.768895 0.7774001 0.9759294 0.1415676
2 1.35988586 0.5634635 13 2.411000 0.6169816 0.2103128 -1.1737358
psych包中的describeBy( )
函数可计算和describe
相同的描述性统计量,只是按照一个或多个分组变量分层。
代码清单7-9 使用psych包中的describe.by( )`分组计算概述统计量
> library(psych)
> myvars <- c("mpg", "hp", "wt")
> describe.by(mtcars[myvars], mtcars$am)
> #describe.by弃用,请使用descriBy( )
$`0`
vars n mean sd median trimmed mad min max range skew
mpg 1 19 17.15 3.83 17.30 17.12 3.11 10.40 24.40 14.00 0.01
hp 2 19 160.26 53.91 175.00 161.06 77.10 62.00 245.00 183.00 -0.01
wt 3 19 3.77 0.78 3.52 3.75 0.45 2.46 5.42 2.96 0.98
kurtosis se
mpg -0.80 0.88
hp -1.21 12.37
wt 0.14 0.18
$`1`
vars n mean sd median trimmed mad min max range skew
mpg 1 13 24.39 6.17 22.80 24.38 6.67 15.00 33.90 18.90 0.05
hp 2 13 126.85 84.06 109.00 114.73 63.75 52.00 335.00 283.00 1.36
wt 3 13 2.41 0.62 2.32 2.39 0.68 1.51 3.57 2.06 0.21
kurtosis se
mpg -1.46 1.71
hp 0.56 23.31
wt -1.17 0.17
describeBy( )
不允许指定任意函数,适应性较差。若存在多个分组变量,可使用list(groupvar1, groupvar2, ... , groupvarN)
表示它们。但这仅在分组变量交叉口不出现空白单元时有效。
最后,使用5.6.3节中描述的reshape包灵活地按组导出描述性统计量。首先,使用:
dfm <- melt(dataframe, mesure.vars=y, id.vars=g)
融合数据框。其中的dataframe包含这数据,y是一个向量,指明了要进行概述的数值型变量(默认使用所有的变量),而g是由一个或多个分组变量组成的向量。然后使用:
cast(dfm, groupvar1 + groupvar2 + ... + variable ~ . , FUN)
重铸数据。分组变量以+号分隔,这里的variable只取其字面含义,而FUN是一个任意函数。
代码清单7-10 通过reshape包分组计算概述统计量
> library(reshape)
> dstats <- function(x) (c(n=length(x), mean=mean(x), sd=sd(x)))
> #定义函数dstats,求均值,标准差
> dfm <- melt(mtcars, measure.vars=c("mpg", "hp", "wt"), id.vars=c("am", "cyl"))
> #数据融合,按照am,cyl对mpg、hp、wt融合统计
> cast(dfm, am + cyl + variable ~ ., dstats)
> 按照am,cyl分组,对其变量求均值、标准差
am cyl variable n mean sd
1 0 4 mpg 3 22.900000 1.4525839
2 0 4 hp 3 84.666667 19.6553640
3 0 4 wt 3 2.935000 0.4075230
4 0 6 mpg 4 19.125000 1.6317169
5 0 6 hp 4 115.250000 9.1787799
6 0 6 wt 4 3.388750 0.1162164
7 0 8 mpg 12 15.050000 2.7743959
8 0 8 hp 12 194.166667 33.3598379
9 0 8 wt 12 4.104083 0.7683069
10 1 4 mpg 8 28.075000 4.4838599
11 1 4 hp 8 81.875000 22.6554156
12 1 4 wt 8 2.042250 0.4093485
13 1 6 mpg 3 20.566667 0.7505553
14 1 6 hp 3 131.666667 37.5277675
15 1 6 wt 3 2.755000 0.1281601
16 1 8 mpg 2 15.400000 0.5656854
17 1 8 hp 2 299.500000 50.2045815
18 1 8 wt 2 3.370000 0.2828427
> dfm
am cyl variable value
1 1 6 mpg 21.000
2 1 6 mpg 21.000
3 1 4 mpg 22.800
4 0 6 mpg 21.400
分布特征的数值刻画很重要,但不能代替视觉呈现。
类别型变量的频数表和列联表,以及相应的独立性检验、相关性的度量、图形化展示结果的方法。
本节数据来自vcd包中的Arthritis数据集。表示一项风湿性关节炎新疗法的双盲临床实验结果。
数据展示:
> #数据展示
> library(vcd)
载入需要的程辑包:grid
> 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
R中提供了用于创建频数表和列联表的若干方法。部分列于表中:
1. 一维列联表
可以使用table( )
函数生成简单的频数统计表。示例如下:
> mytable <- with(Arthritis, table(Improved))
> #with限定数据框
> mytable
Improved
None Some Marked
42 14 28
> prop.table(mytable)
> #表中条目转化为比例值
Improved
None Some Marked
0.5000000 0.1666667 0.3333333
> prop.table(mytable)*100
> #百分比
Improved
None Some Marked
50.00000 16.66667 33.33333
2. 二维列联表
对于二维列联表,table( )
函数的使用格式为:
mytable <- table(A, B)
其中A是行变量,B是列变量。
xtabs( )
函数还可使用公式风格的输入创建列联表,格式为:
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( )
和prop.table( )
函数分别生成边际频数和比例。行和与行比例可以这样计算:
> margin.table(mytable, 1)
Treatment
Placebo Treated
43 41
> prop.table(mytable, 1)
Improved
Treatment None Some Marked
Placebo 0.6744186 0.1627907 0.1627907
Treated 0.3170732 0.1707317 0.5121951
下标1指代table( )
语句中的第一个变量。
列和与列比例可以这样计算:
> margin.table(mytable, 2)
Improved
None Some Marked
42 14 28
> prop.table(mytable, 2)
Improved
Treatment None Some Marked
Placebo 0.6904762 0.5000000 0.2500000
Treated 0.3095238 0.5000000 0.7500000
这里的下标2指代table( )
语句中的第二个变量。
各单元格比例可用如下语句获取:
> 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
> addmargins(prop.table(mytable))
Improved
Treatment None Some Marked Sum
Placebo 0.34523810 0.08333333 0.08333333 0.51190476
Treated 0.15476190 0.08333333 0.25000000 0.48809524
Sum 0.50000000 0.16666667 0.33333333 1.00000000
> #在使用addmargins( )时,默认为表中所有变量创建边际和
> 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
> #添加列和
注意:table( )
函数默认忽略缺失值(NA)。要在频数统计中将NA视为一个有效的类别,请设定参数useNA="ifany"
。
使用gmodels包中的CrossTable( )
函数是创建二维列联表的第三种方法。CrossTable( )
函数仿照SAS中PROC FREQ或SPSS中CROSSTABS的形式生成二维列联表。
代码清单7-11 使用CrossTable
生成二维列联表
> library(gmodels)
> 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 | |
--------------------|-----------|-----------|-----------|-----------|
CrossTable( )
函数有很多选项,可以计算(行、列、单元格)的百分比,指定小数位数;进行卡方、Fisher和McNemar独立性检验;计算期望和(皮尔逊、标准化、调整的标准化)残差;将缺失值作为一种有效值;进行行和列标题的标注;生成SAS或SPSS风格的输出。相见help(CrossTable)
。
3、多维列联表
table( )
和xlab( )
都可以基于三个或更多的类别型变量生成多维列联表。margin.table( )
、prop.table( )
和addmargins( )
函数可以自然地推广到高于二维的情况。另外,ftable( )
函数可以紧凑地输出多维列联表。
代码清单7.12 多维列联表
> library(vcd)
载入需要的程辑包:grid
> 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(mytable) #ftable输出紧凑表格
Improved None Some Marked
Treatment Sex
Placebo Female 19 7 6
Male 10 0 1
Treated Female 6 5 16
Male 7 2 5
> 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, 3))
Improved
Treatment None Some Marked
Placebo 29 7 7
Treated 13 7 21
> 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(addmargins(prop.table(mytable, c(1, 2)), 3)
+ )
Improved None Some Marked Sum
Treatment Sex
Placebo Female 0.59375000 0.21875000 0.18750000 1.00000000
Male 0.90909091 0.00000000 0.09090909 1.00000000
Treated Female 0.22222222 0.18518519 0.59259259 1.00000000
Male 0.50000000 0.14285714 0.35714286 1.00000000
>
比例将被添加到不在prop.table( )
调用中的下标上(上例中是第三个下标,或Improve)。在最后一个表格中看出,因为那里为第三个下标添加了边际和。
列联表可以展示组成表格的各种变量组合的频数或比例。
R提供了多种检验类别型变量独立性的方法。
1、卡方独立性检验
chisq.test( )
函数可对二维表的行变量进行卡方独立性检验。
代码清单7-13 卡方独立性检验
> library(vcd)
> mytable <- xtabs(~ Treatment + Improved, data = Arthritis)
> chisq.test(mytable)
Pearson's Chi-squared test
data: mytable
X-squared = 13.055, df = 2, p-value = 0.001463
> 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
Warning message:
In chisq.test(mytable) : Chi-squared近似算法有可能不准
第一个计算结果:p<0.01,患者接收的治疗和改善的水平可能存在某种关系;
第二个计算结果:p>0.05,患者性别和改善情况之间互相独立。
2、Fisher精确检验
fisher.test( )
函数可进行FIsher精确检验。Fisher精确检验的厡假设是:边界固定的列联表中行和列是互相独立的。调用格式为:
fisher.test(mytable)
其中mytable为一个二维列联表。
> 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
这里的fisher.test( )
函数可以在任意行列数大于等于2的二维列联表上使用,但不能用于2×2列联表。
3、Cochran-Mantel-Haenszel检验
mentelhaen.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
>
结果表明,患者接收的治疗与得到的改善在性别的每一水平下并不独立(即,分性别来看,用药治疗的患者较接收安慰剂的患者有了更多的改善)。
显著性检验评估了是否存在充分的证据以拒绝变量见相互独立的厡假设。如果可以拒绝原假设,问题转向用以衡量相关性强弱的相关性度量。
vcd包中的assocstats( )
函数可以用来计算二维列联表的phi系数、列联系数和Cramer’s V系数。
代码清单7-14 二维列联表的相关性度量
> 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
总体来说,较大的值意味着较强的相关性。vcd包也提供了一个kappa( )
函数,可以计算混淆矩阵的Cohen’s kappa值以及加权的kappa值。(混淆矩阵可以表示两位评判者对于一系列对象进行分类所得结果的一致程度。)
vcd包中拥有优秀的、用于可视化多维数据集中类别型变量间关系的函数,可以绘制马赛克图和关联图(参见11.4节)。ca包中的对应分析函数允许使用多种几何表示(Nenadic & Greenacre,2007)可视地探索列联表中行和列之间的关系。
拥有一个列联表如何转化为原始数据,提供一个示例:
代码清单7-15 通过table2flat
将表转换为扁平格式
> table2flat <- function(mytable) {
+ df <- as.data.frame(mytable)
+ rows <- dim(df)[1]
+ cols <- dim(df)[2]
+ x <- NULL
+ for (i in 1:rows) {
+ for (j in 1:df$Freq[i]) {
+ row <- df[i, c(1:(cols-1))]
+ x <- rbind(x, row)
+ }
+ }
+ row.names(x) <- c(1:dim(x)[1])
+ return(x)
+ }
此函数可以接收一个R中的表格(行列数任意)并返回一个扁平格式的数据框。也可以使用这个函数输入别处的表格。
以下表为例进行转换输入
代码清单7-16 使用table2flat( )`函数转换已发表的数据
> treatment <- rep(c("Placebo", "Treated"), times=3)
> improved <- rep(c("None", "Some", "Marked"), each=2)
> Freq <- c(29, 13, 7, 17, 7, 21)
> #纵向数据
> mytable <- as.data.frame(cbind(treatment, improved, Freq))
> mydata <- table2flat(mytable)
> head(mydata)
treatment improved
1 Placebo None
2 Placebo None
3 Placebo None
4 Placebo None
5 Treated None
6 Placebo Some
相关系数可以用来描述定量变量之间的关系。相关系数的符号(±)表明关系的方向(正相关或负相关),其值表示关系的强弱程度。
本节使用R基础安装中的state.x77数据集,它提供了美国50个州在1977年的人口、收入、文盲率等数据。此外使用psych包和ggm包。
R可以计算多种相关系数,包括Pearson相关系数、Spearman相关系数、Kendall相关系数、偏相关系数、多分格(polychoric)相关系数和多系列(polyserial)相关系数。
1、Prarson、Spearman和Kendall相关系数
Pearson积差相关系数衡量了两个定量变量之间的线性相关程度。Spearman等级相关系数则衡量分级定序变量之间的相关程度。Kendall’sTau相关系数也是一种非参数的等级相关度量。
cor( )
函数可以计算这三种相关关系,而cov( )
函数可用来计算协方差。两个函数的参数有很多,其中与相关系数的计算有关的参数可以简化为:
cor(x, use= , method= )
use="everything"
和method="pearson"
。代码清单7-17 协方差和相关系数
> states <- state.x77[, 1:6]
> cov(states)
Population Income Illiteracy Life Exp Murder
Population 19931683.7588 571229.7796 292.8679592 -407.8424612 5663.523714
Income 571229.7796 377573.3061 -163.7020408 280.6631837 -521.894286
Illiteracy 292.8680 -163.7020 0.3715306 -0.4815122 1.581776
Life Exp -407.8425 280.6632 -0.4815122 1.8020204 -3.869480
Murder 5663.5237 -521.8943 1.5817755 -3.8694804 13.627465
HS Grad -3551.5096 3076.7690 -3.2354694 6.3126849 -14.549616
HS Grad
Population -3551.509551
Income 3076.768980
Illiteracy -3.235469
Life Exp 6.312685
Murder -14.549616
HS Grad 65.237894
> cor(states)
Population Income Illiteracy Life Exp Murder
Population 1.00000000 0.2082276 0.1076224 -0.06805195 0.3436428
Income 0.20822756 1.0000000 -0.4370752 0.34025534 -0.2300776
Illiteracy 0.10762237 -0.4370752 1.0000000 -0.58847793 0.7029752
Life Exp -0.06805195 0.3402553 -0.5884779 1.00000000 -0.7808458
Murder 0.34364275 -0.2300776 0.7029752 -0.78084575 1.0000000
HS Grad -0.09848975 0.6199323 -0.6571886 0.58221620 -0.4879710
HS Grad
Population -0.09848975
Income 0.61993232
Illiteracy -0.65718861
Life Exp 0.58221620
Murder -0.48797102
HS Grad 1.00000000
> cor(states, method="speraman")
Error in match.arg(method) :
'arg' should be one of “pearson”, “kendall”, “spearman”
> cor(states, method="spearman")
Population Income Illiteracy Life Exp Murder HS Grad
Population 1.0000000 0.1246098 0.3130496 -0.1040171 0.3457401 -0.3833649
Income 0.1246098 1.0000000 -0.3145948 0.3241050 -0.2174623 0.5104809
Illiteracy 0.3130496 -0.3145948 1.0000000 -0.5553735 0.6723592 -0.6545396
Life Exp -0.1040171 0.3241050 -0.5553735 1.0000000 -0.7802406 0.5239410
Murder 0.3457401 -0.2174623 0.6723592 -0.7802406 1.0000000 -0.4367330
HS Grad -0.3833649 0.5104809 -0.6545396 0.5239410 -0.4367330 1.0000000
默认情况下得到结果为方阵(所有变量之间两两计算相关)。可以计算非方形的相关矩阵,示例:
> x <- states[, c("Population", "Income", "Illiteracy", "HS Grad")]
> y <- states[, c("Life Exp", "Murder")]
> cor(x, y)
Life Exp Murder
Population -0.06805195 0.3436428
Income 0.34025534 -0.2300776
Illiteracy -0.58847793 0.7029752
HS Grad 0.58221620 -0.4879710
2、偏相关
偏相关是指在控制一个或多个定量变量时,另外两个定量变量之间的相互关系。ggm包中的pcor( )
函数可计算偏相关系数。函数调用格式为:
pcor(u, S)
其中的u是一个数值向量,前两个值表示要计算相关系数的变量下标,其余的数值为条件变量(即要排除影响的变量)的下标。S为变量的协方差矩阵。示例:
> library(ggm)
> pcor(c(1, 5, 2, 3, 6), cov(states))
[1] 0.3462724
控制收入2、文盲率3和高中毕业率6影响时,人后1和谋杀率5之间的相关系数为0.346。偏相关系数常用语社会科学研究。
3、其他类型的相关
polycor包中的hetcor( )
函数可以计算一种混合的相关矩阵,其中包括数值型变量的Pearson积差相关系数、数值型变量和有序变量之间的多系列相关系数、有序变量之间的多分格相关系数以及二分变量之间的四分相关系数。多系列、多分格和四分相关系数都假设有序变量或二分变量由潜在的正态分布导出。
得到相关系数后,进行统计显著性检验。常用的厡假设为变量间不相关(即总体的相关系数为0)。可以使用cor.test( )
函数对单个的Pearson、Spearman和Kendall相关系数进行检验。简化后的使用格式为:
cor.test(x, y, alternative = , method = )
其中x和y为要检验相关性的变量,alternative则用来指定进行双侧检验或单侧检验(取值为“two.side”、”less”或”greater”),而method用以指定要计算的相关类型(“pearson”、“kendall”或“spearman”)。研究的假设为总体的相关系数小于0时,使用alternative="less"
。在研究的假设为总体的相关系数大于0时,应使用alternative="greater"
。在默认情况下,假设为alternative="two.side"
(总体相关系数不等于0)。
代码清单7-18 检验某种相关系数的显著性
> cor.test(states[, 3], states[, 5])
Pearson's product-moment correlation
data: states[, 3] and states[, 5]
t = 6.8479, df = 48, p-value = 1.258e-08
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.5279280 0.8207295
sample estimates:
cor
0.7029752
cor.tets( )
每次只能检验一种相关关系。但psych包中提供的corr.test( )
函数可以一次做更多的事情。
代码清单7-19 通过corr.test
计算相关矩阵并进行显著性检验
> library(psych)
> corr.test(states, use="complete")
Call:corr.test(x = states, use = "complete")
Correlation matrix
Population Income Illiteracy Life Exp Murder HS Grad
Population 1.00 0.21 0.11 -0.07 0.34 -0.10
Income 0.21 1.00 -0.44 0.34 -0.23 0.62
Illiteracy 0.11 -0.44 1.00 -0.59 0.70 -0.66
Life Exp -0.07 0.34 -0.59 1.00 -0.78 0.58
Murder 0.34 -0.23 0.70 -0.78 1.00 -0.49
HS Grad -0.10 0.62 -0.66 0.58 -0.49 1.00
Sample Size
[1] 50
Probability values (Entries above the diagonal are adjusted for multiple tests.)
Population Income Illiteracy Life Exp Murder HS Grad
Population 0.00 0.59 1.00 1.0 0.10 1
Income 0.15 0.00 0.01 0.1 0.54 0
Illiteracy 0.46 0.00 0.00 0.0 0.00 0
Life Exp 0.64 0.02 0.00 0.0 0.00 0
Murder 0.01 0.11 0.00 0.0 0.00 0
HS Grad 0.50 0.00 0.00 0.0 0.00 0
To see confidence intervals of the correlations, print with the short=FALSE option
>
可以看出人口数量和高中毕业了的相关系数(-0.10)并不显著地不为0(p=0.5)。
在7.4.1节中,介绍了偏相关系数。在多元正态性假设下,ggm包中的pcor.test( )
函数可以用来检验在控制一个或多个额外变量时两个变量之间的独立性。使用格式为:
pcor.test(r, q, n)
其中的r是有pcor( )
函数计算得到的偏相关系数,q为要控制的变量数(以数值表示位置),n为样本大小。
此外,psych包中的t.test( )
函数提供了多种使用的显著性检验方法。
以相关系数表示的二元关系可以通过散点图和散点图矩阵进行可视化,而相关图(correlogram)则为以一种有意义的方式比较大量的相关系数提供了一种独特而强大的方法。图形将在第11章详述。
针对变量为连续型的组间比较,并假设其呈正态分布。
MASS包中的UScrime数据集。包含1960年美国47个州的刑罚制度对犯罪率影响的信息。Prob监禁概率,U1(1424岁男性失业率),U2(3539岁男性失业率)。类别型变量So(该州是否位于南方的知识变量)最为分组变量使用。
一个针对两组的独立样本t检验可以用于检验两个总体的均值相等的假设。假设两组数据独立,并且是从正态总体中抽得。检验的调用格式为:
t.test(y ~ x, data)
其中的y是一个数值型变量,x是一个二分变量。调用格式为:
t.test(y1, y2)
其中的y1和y2为数值型向量(即各组的结果变量)。可选参数data的取值为一个包含了这些变量的矩阵或数据框。
这里的t检验默认假定方差不相等,并使用Welsh的修正自由度。可以添加参数var.equal=TRUE
假的方差相等,并使用合并方差估计。默认的备择假设是双侧的(即均值不想等,但大小的方向不确定)。可以添加参数alternative=“less”
或alternative="greater"
进行有方向的检验。
在下列代码中,我们使用了一个假设方差不等的双侧检验,比较南方和非南方各州的监禁概率:
> library(MASS)
> t.test(Prob ~ So, data=UScrime)
Welch Two Sample t-test
data: Prob by So
t = -3.8954, df = 24.925, p-value = 0.0006506
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-0.03852569 -0.01187439
sample estimates:
mean in group 0 mean in group 1
0.03851265 0.06371269
>
厡假设南方各州和非南方各州拥有相同监禁概率拒绝,p<0.001。
在两组的观测之间相关时,获得的是一个非独立组设计(dependent groups design)。前-后测设计(pre-post design)或重复测量设计(repeated measures design)同样也会产生非独立的组。
非独立样本的t检验假定组间的差异呈正态分布。
> library(MASS)
> sapply(UScrime[c("U1", "U2")], function(x) (c(mean=mean(x), sd=sd(x))))
U1 U2
mean 95.46809 33.97872
sd 18.02878 8.44545
> with(UScrime, t.test(U1, U2, paired=TRUE))
Paired t-test
data: U1 and U2
t = 32.407, df = 46, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
57.67003 65.30870
sample estimates:
mean of the differences
61.48936
>
差异的均值(61.5)足够大,可以保证拒绝年长和年轻男性的平均失业率相同的假设。年轻男性的失业率更高。
如果在对于两个组之间进行比较,在假设数据从正态总体中独立抽样得到时,可以使用方差分析(ANOVA)。ANOVA是一套覆盖了许多实验设计和准实验设计的综合方法。见第9章。
数据无法满足t检验或ANOVA的参数假设,可以转而使用非参数方法。
若两组数据独立,可以使用Wilcoxon秩和检验(更为人知的名字是Mann - Whitney U检验)来评估观测是否是从相同的概率分布中抽得的(即,在一个总体中获得更高得分的概率是否比另一个总体要大)。调用格式为:
wilcox.test(y ~ x, data)
其中的y是数值型变量,x是一个二分变量。调用格式或为:
wilcox.test(y1, y2)
y1和y2为各组的结果变量。可选参数data是包含变量的矩阵或数据框。默认进行一个双侧检验。可以添加参数exact
进行精确检验。指定alternative="less"
或alternative="greater"
进行有方向的检验。
使用Mann - Whitney U检验回答上节关于监禁率的问题,将得到如下结果:
> with(UScrime, by(Prob, So, median))
So: 0
So: 1
[1] 0.055552
> wilcox.test(Prob ~ So, data=UScrime)
Wilcoxon rank sum test
data: Prob by So
W = 81, p-value = 8.488e-05
alternative hypothesis: true location shift is not equal to 0
>
Wilcoxon符号秩检验是非独立样本t检验的一种非参数替代方法。适用于两组成对数据和无法保证正态性假设的情境。调用格式与Mann - Whitney U检验完全相同,不过还可以添加参数paired=TRUE
。
> sapply(UScrime[c("U1", "U2")], median)
U1 U2
92 34
> with(UScrime, wilcox.test(U1, U2, paired=TRUE))
Wilcoxon signed rank test with continuity correction
data: U1 and U2
V = 1128, p-value = 2.464e-09
alternative hypothesis: true location shift is not equal to 0
Warning message:
In wilcox.test.default(U1, U2, paired = TRUE) :
cannot compute exact p-value with ties
>
本例中,含参的t检验和与其作用相同的非参数检验得到了相同的结论。当t检验和假设合理时,参数检验的功效更强(更容易发现存在的差异)。而非参数检验在假设非常不合理时(如对于等级有序数据)更适用。
比较的组数多余两个时,需转寻他法。如果要比较美国四个地区的文盲率,这成为单向设计,可以使用参数或非参数的方法来解决。
如果无法满足ANOVA设计的假设,那么可以使用非参数方法评估组间的差异。如果各组独立,则Kruskal-Wallis检验将是一种实用的方法。如果各组不独立,那么Friedman检验更合适。
Kruskal-Wallis检验的调用格式为:
kruskal.test(y ~ A, data)
其中的y是一个数值型结果变量,A是一个拥有两个或更多水平的分组变量(grouping variable)。(若有两个水平,则与Mann-Whitney U检验等价)而Friedman检验的调用格式为:
friedman.test(y ~ A | B, data)
y是数值型结果变量,A是一个分组变量,B是一个用以认定匹配观测的区组变量(blocking variable)。
利用Kruskal - Wallis检验回答文盲率的问题。
> states <- as.data.frame(cbind(state.region, state.x77))
> head(states)
state.region Population Income Illiteracy Life Exp Murder HS Grad Frost
Alabama 2 3615 3624 2.1 69.05 15.1 41.3 20
Alaska 4 365 6315 1.5 69.31 11.3 66.7 152
Arizona 4 2212 4530 1.8 70.55 7.8 58.1 15
Arkansas 2 2110 3378 1.9 70.66 10.1 39.9 65
California 4 21198 5114 1.1 71.71 10.3 62.6 20
Colorado 4 2541 4884 0.7 72.06 6.8 63.9 166
Area
Alabama 50708
Alaska 566432
Arizona 113417
Arkansas 51945
California 156361
Colorado 103766
> kruskal.test(Illiteracy ~ state.region, data=states)
Kruskal-Wallis rank sum test
data: Illiteracy by state.region
Kruskal-Wallis chi-squared = 22.672, df = 3, p-value = 4.726e-05
>
显著性检验的结果意味这美国四个地区的文盲率各不相同。(p<0.001)
可以拒绝不存在差异的原假设,但并不知道哪些地区显著与其他地区不同。
可以使用Mann - Whitney U检验每次比较两组数据。
npmc包还提供了所需要的非参数多组比较程序。
安装npmc包,包中的npmc( )
函数接收的输入为一个两列的数据框,其中一列名为var(因变量),另一列名为class(分组变量)。
代码清单7-20 非参数多组比较
此处npmc包已无法在现有版本的R中应用
> install.packages("npmc")
--- 在此連線階段时请选用CRAN的鏡子 ---
Warning message:
package ‘npmc’ is not available (for R version 3.3.2)
在7.4和7.5节中,介绍进行组间比较的统计方法。使用视觉直观地检查组间差异,同样是全面的数据分析策略中的一个重要部分。R中提供了许多比较组间数据的图形方法,包括6.5节中的箱线图(简单箱线图、含凹槽的箱线图、小提琴图)、6.4.1节中叠加的核密度图,以及第9章中的评估检验假定的图形方法。