R语言总结(三)

目录

十九:两独立样本非参数检验

 二十:单因素方差分析

二十一:K独立样本非参数 

二十二:秩和检验 

二十三:配对样本T检验

二十四:配对样本非参数检验

二十五:K个相关样本非参数检验(肯德尔系数)


十九:两独立样本非参数检验

 ###两独立样本非参数检验
#1.正态性检验
mydata <- as.data.frame(mydata)
tapply(mydata[,5], 
       mydata[,13],
       shapiro.test)

#2、两独立样本非参数检验
#wilcox.test(被检验变量~分组变量,paired = T/F)#独立:F
res1 <- wilcox.test(mydata$HDL~mydata$代谢综合征,paired = FALSE)#两独立样本非参数检验的p>0.05,意味着两组间无显著差异
#如果p<0.05,则认为差异显著,需要比较两组的中位数
aggregate(x = list(mydata$HDL),
          by = list(mydata$代谢综合征),
          FUN = median)
Z <- qnorm(res1$p.value/2)

 

#多变量的综合演示
#1、正态性检验
k <- NULL
for(i in 2:12){
 k <- tapply(mydata[,i],
           mydata[,13],
              shapiro.test)
   if(k$有$p.value<0.05){
    l <- paste0('第',i,'组有代谢综合征不服从正态分布')
   print(l)}
   else{
     if(k$无$p.value<0.05){
       g <- paste0('第',i,'组无代谢综合征不服从正态分布')
       print(g)}
   }
}

#以上结果清晰显示,所有变量至少都在一组上非正态分布
#因此选择两独立样本非参数检验
#且数据的表达形式均选择中位数(上四分位数~下四分位数)

中位数表达 <- function(x){
  paste0(median(x),
         '(',
         quantile(x,prob = 0.25),
         '~',
         quantile(x,prob = 0.75),
         ')')
}

res2 <- aggregate(x = list(mydata[,2:12]),
          by = list(mydata$代谢综合征),
          FUN = 中位数表达)

res2 <- t(res2)
res2 <- res2[-1,]
colnames(res2) <- c('无','有')

#3、两独立样本非参数检验
p <- NULL
for(i in 2:12){
  pi <- wilcox.test(mydata[,i]~mydata[,13],
              paired = FALSE)
  p <- rbind(p,pi)
}
p <- p[,3]
View(p)

p <- do.call(rbind,p)
colnames(p) <- 'p'
p <- data.frame(p)
p$z <- qnorm(p$p/2)

final <- cbind(res2,round(p[,2],3),round(p[,1],3))
colnames(final) <- c('无','有','z','p')

从以上的检验结果可以清晰得出:

  • 有代谢综合征和无代谢综合征两组在LDL、CHOL、AST三个指标上不存在显著差异,P值全部大于0.05。
  • 有代谢综合征和无代谢综合征两组在BMI上存在显著差异,P<0.001, 更进一步比较中位数得出,有代谢综合征组的BMI显著高于无代谢综合征组。

 二十:单因素方差分析

 #####单因素方差分析
#导入SPSS格式的数据
library(Hmisc)
mydata <- spss.get('NO.24 配套数据.sav',use.value.labels = TRUE)

#1、正态性检验
tapply(mydata[,3], 
       mydata[,2],
       shapiro.test)

 #2、判断组间的方差齐性
#方差齐性检验使用的是car程序包中的leveneTest函数
library(car)
#leveneTest(被检验变量~分组变量)
leveneTest(mydata$胃半排空时间~mydata$分组)


#莱文方差齐性检验得出的p>0.05,则认为组间方差无显著差异

 #3、单因素方差分析
#单因素方差分析使用的函数是oneway.test
res1 <- oneway.test(mydata$胃半排空时间~mydata$分组,
            var.equal = TRUE)#方差齐
res1

#以上单因素方差分析得出p<0.05,
#意味着三组间的胃半排空时间的均值存在着显著差异
#则需要继续进行两两比较

#4、两两比较(基于方差齐)
#两两比较需要用到的程序包是PMCMRplus
#PMCMRplus程序包既可以实现方差齐的两两比较
#也可以实现方差不齐的两两比较
library(PMCMRplus)(基于方差齐)
#lsdTest(被检验变量~分组)
mul <- lsdTest(mydata$胃半排空时间~mydata$分组)

mul$p.value

#校正(不太懂)
padj <- p.adjust(mul$p.value,method = 'bonferroni')

padj 

#溃疡样型和动力障碍样型、非特异样型之间的胃半排空存在显著差异
#而动力障碍和非特异性型之间无显著差异,p>0.05.
 

#溃疡样型和动力障碍样型、非特异样型之间的胃半排空存在显著差异
#而动力障碍和非特异性型之间无显著差异,p>0.05.
#更进一步结合均值
aggregate(x = list(mydata[,3]),
          by = list(mydata[,2]),
          FUN = mean)


#得出溃疡样型的胃半排空时间显著高于动力障碍样型

#多变量的单因素方差
#1、正态性检验
for(i in 3:8){
  print(colnames(mydata)[i])
  print(tapply(mydata[,i],
               mydata[,2],
               shapiro.test))
}
#比较三组间在这"胃半排空时间"、"餐后2小时残留率"、"NO"
#三个变量的差异,可以选择单因素方差分析

#2、描述性统计分析
均值标准差 <- function(x){
  paste0(round(mean(x),2),'±',round(sd(x),2))
}

res2 <- aggregate(x = list(mydata[,3:5]),
                  by = list(mydata[,2]),
                  FUN = 均值标准差)
res2 <- t(res2)
res2 <- res2[-1,]
colnames(res2) <- c('溃疡样型','动力障碍样型','非特异性型')

 

#3、方差齐性检验
for(i in 3:5){
  print(colnames(mydata)[i])
  print(leveneTest(mydata[,i]~mydata$分组))
}
#这 "胃半排空时间"、"NO"方差齐
#"餐后2小时残留率"方差不齐

#莱文方差齐性检验得出的p>0.05,则认为组间方差无显著差异

#4、单因素方差分析
a <- oneway.test(mydata$胃半排空时间~mydata$分组,
            var.equal = TRUE)

a$statistic
b <- oneway.test(mydata$NO~mydata$分组,
            var.equal = TRUE)
c <- oneway.test(mydata$餐后2小时残留率~mydata$分组,
                 var.equal = FALSE)

r1 <- rbind(a$statistic,b$statistic,c$statistic)

r2 <- rbind(a$p.value,b$p.value,c$p.value)

final <- cbind(res2,r1,r2)
colnames(final)[5] <- 'p'

#以上单因素方差(齐)分析得出p<0.05,
#意味着三组间的胃半排空时间的均值存在着显著差异
#则需要继续进行两两比较

#5、两两比较
#lsd是方差齐的两两比较
res5 <- lsdTest(mydata$NO~mydata$分组)
res5
#校正(不太懂)
padj2 <- p.adjust(res5$p.value,method = 'bonferroni')
padj2


#方差不齐的两两比较是Tamhane T2两两比较
tamhaneT2Test(mydata$餐后2小时残留率~mydata$分组)

 

二十一:K独立样本非参数 

 

######K独立样本非参数检验
#1、导入SPSS格式的数据
library(Hmisc)
mydata <- spss.get('NO.25 配套数据.sav',use.value.labels = TRUE)


#2、正态性检验
tapply(mydata$SS,
       mydata$分组, 
       shapiro.test)

#3、K独立样本非参数检验
#K独立样本非参数检验使用的函数是kruskal.test()
#kruskal.test()
kruskal.test(mydata$SS~mydata$分组)
#以上检验得出p=0.025<0.05,意味着三组间SS存在显著差异

#得出了显著差异结论之后,还需要继续进行两两比较
#得出具体每两组之间的差异

#4、两两比较
#K独立样本非参数检验的两两比较会用到wmc函数
source('wmc.txt')
wmc(mydata$SS~mydata$分组,data = mydata,
    method = 'holm',sort = FALSE)

#以上两两比较得出动力障碍样型和溃疡样型
#之间的SS存在显著差异。
#为了更进一步得出具体什么差异,哪组高:
#哪组低?
#还需要继续比较中位数。

#5、计算中位数
#非参数检验的数据为非正态数据
#因此数据的表达形式是:中位数(下四分位数~上四分位数)
aggregate(x = list(mydata$SS),
          by = list(mydata$分组),
          FUN = median)
#最终结论是:动力障碍样型显著低于溃疡样型

######多个变量一起进行K独立样本非参数检验
#1、正态性
for(i in 6:8){
  print(colnames(mydata)[i])
  print(tapply(mydata[,i],
               mydata$分组,
               shapiro.test))
}
#任意一组非正态,选择K独立
#基于以上结果,选择K独立样本非参数检验比较三组的差异

#2、首先进行描述性统计分许
#中位数(上四分位数~下四分位数)

中位数描述 <- function(x){
  paste0(round(median(x),2),
         '(',
         round(quantile(x,prob = 0.25),2),
         '~',
         round(quantile(x,prob = 0.75),2),
         ')')
}

res1 <- aggregate(x = list(mydata[,6:8]),
          by = list(mydata$分组),
          FUN = 中位数描述)
res1 <- t(res1)

res1 <- res1[-1,]
colnames(res1) <- c('溃疡样型','动力障碍样型','非特异性型 ')

#3、K独立样本非参数检验
k <- NULL
for(i in 6:8){
  print(colnames(mydata)[i])
  print(kruskal.test(mydata[,i]~mydata$分组))
  l <- kruskal.test(mydata[,i]~mydata$分组)
  k <- rbind(k,l)
}

#提取k中的KW卡方 

chip <- NULL
for(i in 1:3){
  c <- k[i,1]
  chip <- rbind(chip,c)
}

#提取k中的p 

p <- NULL
for(i in 1:3){
  pp <- as.numeric(k[i,3]) 
  p <- rbind(p,pp)
}

# 将列表转换为向量
values <- unlist(chip)
numbers <- as.numeric(gsub("Kruskal-Wallis chi-squared = ", "", values))
print(numbers)

res1 <- cbind(res1,round(numbers,3))
res1 <- cbind(res1,round(p,6))
colnames(res1)[4] <- 'KW卡方'
colnames(res1)[5] <- 'P'

小知识:提取list列表中的数值

在以上列表的chip中,第一列第一行样式为:c(`Kruskal-Wallis chi-squared` = 7.90805836623058),现在想要提取里面的数值。

方法:

# 将列表转换为向量

values <- unlist(chip)

  1. unlist(k)会合并列表中的所有向量元素到一个单一的向量中。
  2. 当合并后的向量有元素名称时(例如Kruskal-Wallis chi-squared = 7.90805836623058),这些名称可以很容易地通过names()函数来获取。
  3. 一旦我们有了这些名称,我们可以利用字符串处理函数(例如gsub())来提取和操作这些名称中的特定部分,如你所需的数值。

如果我们不将列表转换为向量,我们可能需要用更复杂的方式遍历列表的每个元素,并对每个元素单独执行提取操作,这会使代码变得更复杂和冗长。通过将列表转换为向量,我们简化了数据处理的流程。

# 使用正则表达式提取数值

numbers <- as.numeric(gsub("Kruskal-Wallis chi-squared = ", "", values))

  1. gsub("Kruskal-Wallis chi-squared = ", "", values):

    gsub() 是一个用于字符串替换的函数。在这个函数中:

    • 第一个参数 "Kruskal-Wallis chi-squared = " 是想要从字符串中替换掉的模式。
    • 第二个参数 "" 是你想要将模式替换成的内容。在这里,我们想要将前面提到的模式替换为一个空字符串,也就是删除它。
    • 第三个参数 values 是包含字符串的向量,这是我们想要执行替换操作的数据。

    因此,这部分的代码的功能是:从 values 中的每一个字符串元素中删除 "Kruskal-Wallis chi-squared = " 这部分内容。

  2. as.numeric(...):

    这是一个转换函数,用于将数据转换为数字格式。在这里,由于使用 gsub() 后我们得到的是一个字符串向量(具体来说,是不再包含“Kruskal-Wallis chi-squared = ”的数字字符串),我们需要将这些数字字符串转换为实际的数值格式。

综上,整行代码的目的是从 values 向量中删除 “Kruskal-Wallis chi-squared = ” 这部分内容,并将得到的数字字符串转换为数值格式。

> print(numbers)
[1] 11.732550  7.417471  7.908058

 #4、两两比较
for(i in 6:8){
  print(colnames(mydata)[i])
  print(wmc(mydata[,i]~mydata$分组,data = mydata,
            method = 'holm',sort = FALSE))
}

  

 #黄色部分存在显著差异

二十二:秩和检验 

 #1、比较不同婚姻状况的学历差异
table(mydata$婚姻状况)
#使用K独立样本秩和检验
kruskal.test(mydata$文化~mydata$婚姻状况)
#如果存在显著差异,则继续计算中位数
#分组计算中位数aggregate
#aggregate()

#2、比较男和女在学历等级上的差异
#两组秩和检验,两独立样本的秩和检验
#mydata$文化为factor类型,需要转化成数值型
table(mydata$文化)#从数量高到低进行修改
library(do)
mydata$文化新 <- mydata$文化
mydata$文化新 <- Replace(mydata$文化新,
                      from = '文盲',
                      to = 1)
mydata$文化新 <- Replace(mydata$文化新,
                      from = '小学',
                      to = 2)
mydata$文化新 <- Replace(mydata$文化新,
                      from = '初中',
                      to = 3)
mydata$文化新 <- Replace(mydata$文化新,
                      from = '高中',
                      to = 4)
mydata$文化新 <- Replace(mydata$文化新,
                      from = '本科',
                      to = 5)
mydata$文化新 <- Replace(mydata$文化新,
                      from = '研究生及以上',
                      to = 6)
table(mydata$文化新)
mydata$文化新 <- as.numeric(mydata$文化新)
wilcox.test(mydata$文化新~mydata$性别) 

#得出了存在显著差异的结论后,还需要继续比较中位数

aggregate(x=list(mydata$文化新),
          by = list(mydata$性别),
          FUN = quantile)
#得出男性学历高于女性

二十三:配对样本T检验

 ###配对样本T检验
#1、导入数据
library(Hmisc)
mydata <- spss.get('NO.27 配套数据.sav',use.value.labels = TRUE)

mydata$差值 <- mydata$空腹血糖.治疗前-mydata$空腹血糖.治疗后
apply(mydata[,2:4],2, shapiro.test)

 #通过了正态性检验,因此比较前后的
#空腹血糖差异选择的统计学方法是
#配对样本T检验
t.test(mydata$空腹血糖.治疗前, 
       mydata$空腹血糖.治疗后,
       paired = TRUE)

#得出前后差异显著

 #3、描述性统计分析
source('均值标准差函数.txt')
res <- apply(mydata[,2:3], 2, 均值标准差函数)
res <- data.frame(res)

二十四:配对样本非参数检验

 

 #1、比较前后疼痛评分的差异
#1、正态性检验
apply(mydata[,2:3],2,shapiro.test)

 #评分均为非正态,因此选择独立样本非参数检验


#1.2 配对样本非参数检验
res1 <- wilcox.test(mydata$疼痛评分.治疗前,
            mydata$疼痛评分.治疗后,
            paired = TRUE)
res1$p.value
Z <- qnorm(res1$p.value/2)  #-5.711195

 #存在显著差异

#1.3 制作表格
source('中位数函数.txt')
res2 <- apply(mydata[,2:3], 2, 中位数描述)
res2 <- data.frame(res2)

#2、比较严重程度的差异
#严重程度变量属于有序等级变量
#因此,不需要进行正态性检验

#因为是等级变量,直接采用秩和检验
res3 <- wilcox.test(mydata$严重程度.治疗前,
                    mydata$严重程度.治疗后,
                    paired = TRUE)
Z2 <- qnorm(res3$p.value/2)
Z2
res4 <- apply(mydata[,4:5], 2, 中位数描述)
res4 <- data.frame(res4)

res2 <- t(res2)
res4 <- t(res4)
final <- rbind(res2, res4)

Zval <- c(Z, Z2)
Zval
Pval <- c(res1$p.value, res3$p.value)
final <- cbind(final, Zval, Pval)
write.csv(final,'final.csv')

从以上的分析结果可以清晰得出:

  1. 治疗后,疼痛评分显著下降,从原来的42显著降到26,P<0.05;
  2. 治疗后,严重程度显著下降,从原来的中重度显著降到中度,P<0.05

 二十五:K个相关样本非参数检验(肯德尔系数)

   

####K个相关样本非参检验
#1、friedman.test()(差异显著)
#比较三个状态下的连续型变量的差异
#1.1 正态性检验
apply(mydata1[,2:4],2,shapiro.test)

 #其中任意一个非正态,
#则选择K个相关样本非参检验中的friedman检验

#1.2friedman检验对数据的要求并整理
#firedman检验要求数据必须是矩阵matrix
mal <- as.matrix(mydata1[,2:4])
#此时矩阵为114个元素,混为一起,所以要告诉软件分成38组,每组三个
dimnames(mal) <- list(1:38,c('术前','术后一周','术后四周'))

#1.3 firedman检验
friedman.test(mal)
#得出P<0.05, 意味着三个状态存在显著差异,因此,
#还需要继续进行两两比较,确定具体哪两个状态之间存在显著差异

#1.4 事后多重比较
#PMCRplus程序包是专门用于两两比较的程序包
library(PMCMRplus)
frdAllPairsNemenyiTest(mal,p.adjust = 'bondferroni')

#1.5 表格制作
source('中位数函数.txt')
res1 <- apply(mal,2,中位数描述)
res1 <- data.frame(res1)
res2 <- friedman.test(mal)
res1$chiq <- c(res2$statistic,'NA','NA')
res1$p <- c(res2$p.value,'NA','NA')
write.csv(res1,'res1.csv') 

    

 #2、friedman.test()(差异不显著的情况)
#更进一步进行Kendall协同系数检验
ma2 <- as.matrix(mydata2[,2:5])
dimnames(ma2) <- list(1:50,c('评委1','评委2','评委3','评委4'))

#2.1 首先进行差异比较
friedman.test(ma2)
#得出P=0.26>0.05,意味着4个评委的结果差异不显著
#即4个评委的结果一致。

#接下来,需要选择Kendall协同系数检验计算一致程度
#Kendall协同系数检验需要用到irr程序包中的kendall函数
library(irr)
kendall(ma2)


#kendall's W检验得出P<0.05,意味着四个评委的结论显著一致
#一致程度为0.846,说明四个评委给出的评价结果一致程度较高。

#3、Cochran's Q检验
#Cochran's Q检验用到的是DescTools程序包中的CochranQ函数
library(DescTools)
#CochranQTest()也是要求矩阵matrix形式的数据
ma3 <- as.matrix(mydata3[,2:5])
dimnames(ma3) <- list(1:57,
                      c('评委1','评委2','评委3','评委4'))
CochranQTest(ma3)
#得出P=0.601>0.05意味着4个评委的结论不存在显著差异。

 #假设,存在显著差异,怎么进行事后多重比较?
#两两比较:配对卡方
choose(4,2)

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值