以下是两种方法:
数据
library(car)
df <- structure(list(Count = c(13, 14, 14, 12, 11, 13, 14, 15, 13, 12, 20, 15, 9, 5, 13, 14, 7, 17, 18, 14, 12, 12, 13, 14, 11, 10, 15, 14, 14, 13),
Group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("a", "b", "c" ), class = "factor")),
.Names = c("Count", "Group"),
row.names = c(NA, -30L), class = "data.frame")
基础 R
首先,是 Group
因子的唯一配对集合:
allPairs <- expand.grid(levels(df$Group), levels(df$Group))
allPairs <- unique(t(apply(allPairs, 1, sort)))
allPairs <- allPairs[ allPairs[,1] != allPairs[,2], ]
allPairs
现在进行分析:
allResults <- apply(allPairs, 1, function(p) {
dat <- df[ df$Group %in% p, ]
ret <- oneway.test(Count ~ Group, data = dat, na.action = na.omit, var.equal = FALSE)
ret$groups <- p
ret
})
length(allResults)
allResults[[1]]
如果你想把它看作一个矩阵,或许可以这样看:
mm <- diag(length(levels(df$Group)))
dimnames(mm) <- list(levels(df$Group), levels(df$Group))
pMatrix <- lapply(allResults, function(res) {
mm[res$groups[1], res$groups[2]] <<- mm[res$groups[2], res$groups[1]] <<- res$p.value
})
mm
(同样可以轻松地对F统计量进行操作。)
使用dplyr
首先,获取Group
因子的唯一对集合:
library(dplyr)
allPairs <- expand.grid(levels(df$Group), levels(df$Group), stringsAsFactors = FALSE) %>%
filter(Var1 != Var2) %>%
mutate(key = paste0(pmin(Var1, Var2), pmax(Var1, Var2), sep='')) %>%
distinct(key) %>%
select(-key)
allPairs
如果顺序很重要,你可以在这个管道中早期添加
dplyr::arrange(Var1, Var2)
,也许是在调用
expand.grid
之后。
现在开始分析:
ret <- allPairs %>%
rowwise() %>%
do({
data.frame(.,
oneway.test(Count ~ Group, filter(df, Group %in% c(.$Var1, .$Var2)),
na.action = na.omit, var.equal = FALSE)[c('statistic', 'p.value')],
stringsAsFactors = FALSE)
})
ret
我不对这两个东西的性能做任何声明;通常情况下,一个在像这个例子一样的少量数据上表现出色,但是在更大的数据集上另一个可能会更胜一筹。它们似乎都使用相同的统计方法进行成对比较,并得出相同的结果。现在轮到你了!
df
的例子吗? - r2evansa
和b
组的df
子集执行oneway.test
? - r2evans