假设我们从代表 5 个人口的 5 个位置抽取了几个个体的独立随机样本。设计相当不平衡:从每个位置抽样的个体数量是可变的(代码中的示例)。对于每个个体,我们测量了一些连续的随机变量(例如,某种化学物质的浓度,假设它的值纯粹是各个个体被采样的位置的函数),我们希望使用这个变量来了解哪些位置不同(浓度化学品)。我将在这里模拟这些数据的示例:
set.seed(123)
data <- data.frame(group = factor(rep(c(paste0("G",1:5)), c(10,24,10,12,9))),
val = c(rnorm(10, mean=1.34,sd=0.17),
rnorm(24, mean = 1.14, sd=0.11),
rnorm(10, mean=1.19, sd=0.15),
rnorm(12, mean=1.06, sd=0.11),
rnorm(9, mean=1.09, sd = 0.10)))
让我们假设group
表示 5 个采样位置,并val
表示每个样品中化学物质的浓度。
假设我们已经进行了一系列综合非参数测试(使用距离矩阵,PERMANOVA),表明各组之间的化学物质浓度存在差异。我们想要进行成对分析以查看哪些组是不同的,因此我们vegan
使用欧几里得距离为这些数据计算一个相异矩阵(在此示例中使用 R 中的包):
library(vegan)
dist.mat <- vegdist(data$val, method = "euclidean")
有几个包具有执行通常称为 PERMANOVA/permutaional MANOVA/adonis 测试的成对版本的功能(基于 Marti J. Anderson 的方法:Anderson, MJ 2001。非参数多元变量的新方法方差分析。Austral Ecology,26:32-46。)可以在以下链接中找到一些示例: https ://www.rdocumentation.org/packages/RVAideMemoire/versions/0.9-77/topics/pairwise.perm.manova https://github.com/pmartinezarbizu/pairwiseAdonis/blob/master/pairwiseAdonis/R/pairwise.adonis.R https://rdrr.io/github/gauravsk/ranacapa/man/pairwise_adonis.html https://rdrr。 io/github/GuillemSalazar/EcolUtils/man/adonis.pair.html
我遇到的大多数演示如何在 R 中使用和解释这些方法的示例都应用于计数数据(主要是生态数据中的物种组成,这与安德森的意图相对应)。然而,有一些例子表明这些方法被应用于其他情况,特别是在我的兴趣中,用于连续数据,例如上面介绍的那些。在我提出的那种情况下,如果我们使用欧几里德距离计算相异矩阵,并执行此过程的成对版本(我将使用pairwise.adonis()
@pmartinezarbizu 的函数,上面的第二个链接):
library(pairwiseAdonis)
#default is 999 permutations
res<-pairwiseAdonis::pairwise.adonis(dis.mat, data[,"group"])
res[,3:5] <- round(res[,3:5],2)
res
pairs Df SumsOfSqs F.Model R2 p.value p.adjusted sig
1 G1 vs G2 1 0.26 19.95 0.38 0.001 0.01 *
2 G1 vs G3 1 0.09 5.06 0.22 0.038 0.38
3 G1 vs G4 1 0.28 23.98 0.55 0.001 0.01 *
4 G1 vs G5 1 0.34 18.72 0.52 0.001 0.01 *
5 G2 vs G3 1 0.02 1.78 0.05 0.172 1.00
6 G2 vs G4 1 0.01 0.95 0.03 0.323 1.00
7 G2 vs G5 1 0.04 2.92 0.09 0.093 0.93
8 G3 vs G4 1 0.05 3.87 0.16 0.077 0.77
9 G3 vs G5 1 0.09 4.62 0.21 0.047 0.47
10 G4 vs G5 1 0.01 0.78 0.04 0.376 1.00
我是否不正确地说这相当于一系列简单的成对方差分析,其 p 值根据观察到的 F 统计概率在通过组成员资格(或“位置”成员资格在此中的随机排列产生的经验零分布下)计算案子)。如果是这样,这怎么可能是成对比较的有效非参数方法?让我解释:
让我们以第 1 组和第 5 组(G1
和G5
)为例:
library(dplyr)
ex <- c("G1","G5")
se <- function(x) sd(x) / sqrt(length(x))
data%>%
dplyr::filter(., group %in% ex)%>%
group_by(group)%>%
summarise_at(., "val", list(mean=mean,med=median,sd=sd,se=se))%>%
mutate(across(is.numeric, round, 2))
# A tibble: 2 x 5
group mean med sd se
<fct> <dbl> <dbl> <dbl> <dbl>
1 G1 1.35 1.33 0.16 0.05
2 G5 1.05 1.06 0.07 0.02
我们知道它们一开始是异方差的,但仍然让我们拟合一个 lm 并查看残差图:
ex <- c("G1","G5")
dat2 <- data%>%dplyr::filter(., group %in% ex)
summary(lm(val~group, dat2))
plot(lm(val~group, dat2))
Residuals:
Min 1Q Median 3Q Max
-0.22775 -0.08020 -0.00070 0.06125 0.27887
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.35269 0.04061 33.306 < 2e-16 ***
groupG5 -0.29792 0.05901 -5.049 9.9e-05 ***
现在让我们做常规方差分析:
ex <- c("G1","G5")
dat2 <- data%>%dplyr::filter(., group %in% ex)
summary(aov(val ~ group, data = dat2))
Df Sum Sq Mean Sq F value Pr(>F)
group 1 0.4204 0.4204 25.49 9.9e-05 ***
Residuals 17 0.2804 0.0165
现在让我们只对这两组做成对的阿多尼斯程序:
set.seed(123)
dis.mat <- vegdist(dat2$val, method="euclidean")
res<-pairwiseAdonis::pairwise.adonis(dis.mat, dat2[,"group"])
res[,3:5] <- round(res[,3:5],2)
res
pairs Df SumsOfSqs F.Model R2 p.value p.adjusted sig
1 G1 vs G5 1 0.42 25.49 0.6 0.001 0.001 **
我们应该得到相同的观察模型,以及基于排列的 p 值。稍微看一下引擎盖就会告诉我,这个函数实际上所做的就是adonis
在每一对(或本例中的单对)上执行该函数。为了演示,我们通过这样做得到相同的答案:
set.seed(123)
dis.mat <- vegdist(dat2$val, method="euclidean")
res2<- adonis(dis.mat ~ dat2$group, method = "euclidean")
res2$aov.tab
Terms added sequentially (first to last)
Df SumsOfSqs MeanSqs F.Model R2 Pr(>F)
dat2$group 1 0.42041 0.42041 25.488 0.59989 0.001 ***
Residuals 17 0.28041 0.01649 0.40011
Total 18 0.70082 1.00000
所以我们在这里所做的一切(仍然使用G1
vsG5
示例)是
- 计算原始比较的 F 检验(相异值,在数学上等同于原始数据的差异,因为我们使用了欧几里得距离),
- 打乱原始数据并计算新的 F 统计量
- 重复步骤 2 999 次以创建经验 F 分布(生成空模型),
- 最后计算出观察到的 F 值在空模型下出现的概率:
perm<-permustats(res2)
densityplot(perm)
因此,如果我们真正要做的只是比较从正常方差分析/线性模型计算的 F 值,那么这真的是一种有效的“非参数”方法来进行成对比较吗?