查看原文
其他

R笔记:正态分布的检验

vacleon 统计浆糊 2023-09-26

正态分布的检验方法有很多,我们在<<正态分布与方差齐性的检验方法与SPSS操作>>做过介绍,本文介绍的R软件的检验。每种方法在R中都有很多程序包可以实现。

示例采用<<完全随机资料设计的方差分析>>的数据,是安慰剂组和3个剂量组药物的降脂疗效。

从SPSS中载入数据,采用函数spss.get{Hmisc}。spss.get(file, lowernames=FALSE, datevars = NULL,use.value.labels = TRUE, to.data.frame = TRUE,max.value.labels = Inf, force.single=TRUE,allow=NULL, charfactor=FALSE, reencode = NA).

SPSS数据载入命令清单:

##数据载入

library(Hmisc)  #载入Hmisc程序包,非默认,需要先运行install.packages("Hmisc")进行安装,会同时安装lattice、survival、Formula、ggplot2等相关程序包

library(lattice)  #载入lattice程序包

library(survival)  #载入suivival程序包

library(Formula)  #载入Formula程序包

library(ggplot2)  #载入ggplot2程序包

normt<- spss.get("D:/Temp/ANOVA.sav")  #新建对象normt,赋值为SPSS文件ANOVA的数据

##按分析组新建分析对象

placebo<-normt[1:30,-1]  #新建对象placebo,赋值为文件normt的第1到30行,除第1列外的其他列数据(本例只有2列,所以实际上就是第2列)

NG2.4g<-normt[31:60,2]  #新建对象NG2.4g,赋值为文件normt的第31到60行、第2列的数据

NG4.8g<-normt[61:90,2]  #新建对象NG4.8g,赋值为文件normt的第61到90行、第2列的数据

NG7.2g<-normt[91:120,-1]  #新建对象NG7.2g,赋值为文件normt的第91到120行、第2列的数据

(1)Shapiro-Wilk W检验。shapiro.test{stats}:shapiro.test(x),Performs the Shapiro-Wilk test of normality. the number of non-missing values must be between 3 and 5000,还要注意检测的变量x是数值型向量。

接上述数据载入后的命令,清单如下:

##Shapiro-Wilk W检验

library(stats)  #载入stats程序包

shapiro.test(placebo)

shapiro.test(NG2.4g)

shapiro.test(NG4.8g)

shapiro.test(NG7.2g)

结果如下:4个组P均>0.05,数据均呈正态分布。

上面的思路很简单,先对每个组建一个对象,然后对每个组进行检验,虽然有些啰嗦但是很好理解。有没有函数直接可以分组计算呢?当然!只要你能想到就一定有这样的方法,我们一直说R里面最牛逼的就是它的程序包和函数,多得让人无所适从不知道选哪个!比如有个基础应用函by {base}:Apply a Function to a Data Frame Split by Factors,应用格式为by(data, INDICES, FUN, ..., simplify = TRUE),具体解释可通过help("by")查询,该函数可以按照INDICES将要分析的data数据分割成几个数据框,然后对每个数据框应用FUN函数的功能。如此,本例就变得很简单,在数据载入后,执行以下命令:

##分组计算正态性

library(stats)  #载入stats程序包 

group<-normt[,1]   #新建对象,赋值为第1列数据

ldlc<-normt[,2]  #新建对象,赋值为第2列数据

by(ldlc,group,shapiro.test)  #对ldlc按group分组,分别进行Shapiro-Wilk W检验后输出结果

你甚至都不需要去重新定义数值型向量group和ldlc,而是直接利用记号$来完成,$可以用来选用某个指定数据框中的特定变量

library(stats) 

by(normt$LDL.C,normt$Group,shapiro.test)  #normt$LDL.C表示数据框normt中的变量LDL.C,normt$Group表示数据框normt中的变量Group

有三点需要说明以下:

①shapiro.test检测的是数值型向量(a numeric vector of data values),normt["LDL.C"]生成的是数据框,直接进行shapiro.test会报错,当然你可以先把它转换为矩阵(as.matrix()),然后再转换为向量(as.vector()),但这种办法实际上有点复杂。aa<-normt["LDL.C"]

bb<-as.matrix(aa)

ldlc<-as.vector(bb)

group<-as.vector(as.matrix(normt["Group"]))

by(ldlc,group,shapiro.test) 


by(as.vector(as.matrix(normt["LDL.C"])),as.vector(as.matrix(normt["Group"])),shapiro.test) 

②我觉得是spss.get{Hmisc}的一个Bug,其在读入SPSS文件是把变量名中的“_”读成了“.”,本例中把LDL_C读成了LDL.C,这使得在使用变量名时找不到变量。
③作为初学者,我们翻来覆去的用多种方法只是为了更好地了解R的用法。
(2)Kolmogorov-Smirnov检验。lillie.test {nortest}:lillie.test(x),Performs the Lilliefors (Kolmogorov-Smirnov) test for the composite hypothesis of normality, 样本量需要大于4,同样注意该函数检测的也是数值型向量(a numeric vector of data values)。

接上述数据载入后按分析组新建分析对象命令后,清单如下:

library(nortest)  #载入nortest程序包

lillie.test(placebo)

lillie.test(NG2.4g)

lillie.test(NG4.8g)

lillie.test(NG7.2g)

同样的,可以使用以下命令进行分组检验:

library(nortest) 

by(normt$LDL.C,normt$Group,lillie.test) 

程序包nortest除了提供lillie.test函数来检验正态性,还有ad.test(Anderson-Darling test), cvm.test(Cramer-von Mises test), pearson.test(Pearson chi-square test), sf.test(Shapiro-Francia test for performing further tests for normality. 

命令演示如下:

ad.test(placebo)  #Anderson-Darling test法检验placebo组的正态性

cvm.test(NG2.4g)  #Cramer-von Mises test法检验NG2.4g组的正态性

pearson.test(NG4.8g)  #Pearson chi-square test法检验NG4.8g组的正态性

sf.test(NG7.2g)  #Shapiro-Francia test法检验NG7.2g组的正态性

(3)概率图(P-P图)、分位图(Q-Q图)、正态分位图

很多程序包都可以绘制这些图,如pp_plot{qrmtools}可绘制正态概率图,qq_plot{qrmtools}qqnorm {stats}可绘制Q-Q图,qqPlot {car}可绘制正态分位图。

命令演示如下:

library(stats)  #载入程序包stats

qqnorm(placebo)  #绘制placebo组的Q-Q图

qqline(placebo, col = 2)  #向Q-Q图中添加参考直线,直线颜色为2

library(car)  #载入程序包car

qqPlot(NG7.2g)  #绘制NG7.2g组数据的正态分位图

结果如下:左为placebo组的Q-Q图,右图为NG7.2g的正态分位数图。结果数据点均在直线附近,数据呈正态。

补充说明:$、attach()/detach()、with()

以上的数据分了4个组,我们使用4个对象分别表示4个组,如果我们的数据没有组,想检测一下某个变量的数据是不是正态分布,应该怎么选择要分析的对象呢?一个简单的想法是新建1个对象赋值全部的数据,如下:

ldlc<-normt[1:120,-1]   #新建对象ldlc,赋值为文件normt的第1到120行、第2列的数据

library(stats)  #载入程序包stats

shapiro.test(ldlc)  #对ldlc进行Shapiro-Wilk正态性检验

还有一种方法就是使用记号$或者函数attach()或者函数with()

library(stats)  #载入程序包stats

shapiro.test(normt$LDL.C)  #normt$LDL.C表示数据框normt中的变量LDL.C


library(stats)  #载入程序包stats

attach(normt)  #在数据框normt作为操作目录

shapiro.test(LDL.C)  #在normt路径中的LDL.C进行Shapiro-Wilk正态性检验

detach(normt)  #detach将数据框normt作从搜索路径中移除


with(normt,{

library(stats)

shapiro.test(LDL.C)

})   #使用程序包stats中的shapiro.test函数对数据框normt中的变量LDL.C进行正态性检验

with函数表达式里{}中的命令语句只针对数据框normt执行,如果只有一条命令,可以不用{},如本例也可以用以下语句来表达:

library(stats)  #载入程序包stats

with(normt,shapiro.test(LDL.C))  #使用shapiro.test函数对数据框normt中的变量LDL.C进行正态性检验

END


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存