1

我想运行一系列 kruskal.tests,然后是 kruskal 很重要的 dunn_test。然后打印显着的 dunn_tests 的结果。

library(rstatix)
library(purrr)

iris<- iris

for(i in 1:4){
  a<- colnames(iris)
  anova<- map(names(iris)[1:4], ~ kruskal.test(reformulate('Species', response=.x), data=iris))
  post<- dunn_test(iris, as.formula(paste(a[i], a[5], sep="~")), p.adjust.method= "bonferroni")
  
  if(any(post$p.adj < 0.05 & anova[[i]]$p.value < 0.05)){
    print(a)
    print(setNames(post, a))
  }
}

我想知道当同一变量的 kruskal 测试很重要时,我如何才能只打印重要的 dunntests。

我意识到这不会给我我正在寻找的结果,因为 post 和 anova 项目是两个独立的对象,这只是我最初的想法。使用anova[[i]]$p.value也会导致下标越界错误。

4

2 回答 2

2

这是一种使用函数来获得所需的事后结果的方法。它的工作原理类似于循环。我看你很熟悉,as.formula我认为这是最好的方法。我对 Kruskal-Wallis 检验和 Dunn 检验使用了相同的公式。该函数只使用您要测试的列名并从中创建公式。如果您想在任何一个比较显着的情况下返回所有事后测试,则any只需进行少量更改即可。输出want通过至少一个重要的成对比较捕获所有事后测试。

除了您的代码之外,创建与 R 中的函数具有相同名称的对象名称不是很好的做法。它是 Ranova中的基本函数,因此您不希望将结果也命名为 anova。您还在a循环中一遍又一遍地创建对象。这是同一个任务,所以它应该在你的循环之外。这不是什么大问题,但是如果您开始使用更大的数据集,它可以加起来。

library(rstatix)
#> 
#> Attaching package: 'rstatix'
#> The following object is masked from 'package:stats':
#> 
#>     filter

iris <- iris

a <- colnames(iris)
a <- a[1:4]

myfunc <- function(y, x){
  form <- as.formula(paste0(y, " ~ ", x))
  res <- rstatix::kruskal_test(form, data = iris)
  
  if (res$p < 0.05){
     post <- rstatix::dunn_test(data = iris, form, p.adjust.method= "bonferroni")
     
     if(any(post$p.adj < 0.05)) return(post)
  }
}

want <- lapply(a, FUN = myfunc, x = "Species")
want <- do.call(rbind, want)

如果您只想要显着的特定成对比较,因为输出dunn_test是 a data.frame,您可以通过小于 0.05 的调整 p 值对其进行子集化return

myfunc <- function(y, x){
  form <- as.formula(paste0(y, " ~ ", x))
  res <- rstatix::kruskal_test(form, data = iris)
  
  if (res$p < 0.05){
     post <- rstatix::dunn_test(data = iris, form, p.adjust.method= "bonferroni")
     post <- post[post$p.adj < 0.05 ,]
     return(post)
  }
}

作为一个循环,这将是:

res <- list()
post <- list()
post_sig <- list()
for(i in 1:4){
  form <- as.formula(paste0(a[i], " ~ Species"))
  res[[i]] <- rstatix::kruskal_test(form, data = iris)
  post[[i]] <- rstatix::dunn_test(data = iris, form, p.adjust.method= "bonferroni")
  
  if (res[[i]]$p < 0.05 & any(post[[i]]$p.adj < 0.05)){
       print(post[[i]])
       ## could be blanks in the list here as the number i is used
       ## e.g. if var 2 was not significant, post_sig[[2]] is blank
       post_sig[[i]] <- post[[i]]
  }
}

## if you want results as a dataframe
res <- do.call(rbind, res)
post <- do.call(rbind, post)
post_sig <- do.call(rbind, post_sig)
于 2022-02-02T20:24:09.640 回答
1

据我所知,您的代码大部分都有效。唯一的主要问题是您滥用该any()功能。你放错了第二个括号。修复它并重新排列代码,我运行了这个:

library(rstatix)
library(purrr)

iris<- iris

a<- colnames(iris)
anova<- map(names(iris)[1:4], ~ kruskal.test(reformulate('Species', response=.x), data=iris))

for(i in 1:4){
  post<- dunn_test(iris, as.formula(paste(a[i], a[5], sep="~")), p.adjust.method= "bonferroni")
  
  if(any(post$p.adj < 0.05) & anova[[i]]$p.value < 0.05){
    print(a[i])
    print(post)
  }
}

这段代码一个接一个地打印出被测试变量的名称和 dunn_test 的输出,只要 kruskal 测试的相关 p 值小于 0.05,并且至少有一个比较在dunn_test 很重要。

于 2022-02-02T20:17:20.030 回答