一种执行多个成对测试(例如 t 测试)的紧凑方法,其中单个变量以长格式拆分为多个类别
A compact way to perform multiple pairwise tests (e.g. t-test) with a single variable split in multiple categories in long-format
我有兴趣对单个变量执行多个测试,该变量具有将值分成多个组的关联因子。它与 有关,实际上,我想得到那种解决方案,但它并不完全相同。
在我的例子中,我有一个变量和多个组(最终有很多)。扩展 :
library(reshape)
# Create a dataset
mu=34
stdv=5
Location=rep(c("Area_A","Area_B","Area_C"),5)
distro=rnorm(length(Location),mu,stdv)
id=seq(1:length(Location))
sample_long=data.frame(id,Location,distro)
sample_long
id Location distro
1 1 Area_A 34.95737
2 2 Area_B 31.30298
3 3 Area_C 35.86569
4 4 Area_A 40.45378
5 5 Area_B 36.12060
6 6 Area_C 28.29649
7 7 Area_A 30.64495
8 8 Area_B 29.70668
9 9 Area_C 33.22874
10 10 Area_A 25.29148
11 11 Area_B 32.35511
12 12 Area_C 34.69159
13 13 Area_A 26.89791
14 14 Area_B 35.30717
15 15 Area_C 40.64628
我想在区域之间进行全对抗测试,即测试(Area_A,Area_B),测试(Area_A,Area_C)和test(Area_B,Area_C)(在更一般的情况下,所有 i<j
可能的测试)。
一种简单的方法是将数据转换为宽格式:
# Reshape to wide format
sample_wide=reshape(sample_long,direction="wide",idvar="id",timevar="Location")
sample_wide
id distro.Area_A distro.Area_B distro.Area_C
1 1 34.95737 NA NA
2 2 NA 31.30298 NA
3 3 NA NA 35.86569
4 4 40.45378 NA NA
5 5 NA 36.12060 NA
6 6 NA NA 28.29649
7 7 30.64495 NA NA
8 8 NA 29.70668 NA
9 9 NA NA 33.22874
10 10 25.29148 NA NA
11 11 NA 32.35511 NA
12 12 NA NA 34.69159
13 13 26.89791 NA NA
14 14 NA 35.30717 NA
15 15 NA NA 40.64628
然后遍历所有列,我已经看到几个 approximations 比我使用 for 循环的下面一个更像 R:
# Now compute the test
test.out=list()
k=0
for(i in 2:(dim(sample_wide)[2]-1)){ # All against all var groups
for(j in (i+1):dim(sample_wide)[2]){
k=k+1
test.out[[k]]=t.test(sample_wide[,i],
sample_wide[,j]) # store results in a list
}
}
但我的问题是不是考虑到宽格式哪个是最佳解决方案,但是否有可能找到解决问题的解决方案原始的长格式,与我在上面提供的使用dplyr
、broom
等链接找到的解决方案一致
这比我希望的要复杂一些,也不那么简单。您可以先找出位置的组合,然后将其保存在查找 table 中以使其更简单一些。我把它变成了一个长形,每对都有一个 ID,我将把它用作数据的分组变量。
library(dplyr)
library(tidyr)
library(purrr)
set.seed(111)
# same data creation code
grps <- as.data.frame(t(combn(levels(sample_long$Location), 2))) %>%
mutate(pair = row_number()) %>%
gather(key, value = loc, -pair) %>%
select(-key)
grps
#> pair loc
#> 1 1 Area_A
#> 2 2 Area_A
#> 3 3 Area_B
#> 4 1 Area_B
#> 5 2 Area_C
#> 6 3 Area_C
将查找加入到数据框会使行数加倍——这将根据您合并的级别数而有所不同。另请注意,我删除了您的 ID 列,因为现在似乎没有必要。嵌套,做t检验,整理结果。
sample_long %>%
select(-id) %>%
inner_join(grps, by = c("Location" = "loc")) %>%
group_by(pair) %>%
nest() %>%
mutate(t_test = map(data, ~t.test(distro ~ Location, data = .)),
tidied = map(t_test, broom::tidy)) %>%
unnest(tidied)
#> # A tibble: 3 x 13
#> pair data t_test estimate estimate1 estimate2 statistic p.value
#> <int> <lis> <list> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 <tib… <htes… -0.921 31.8 32.7 -0.245 0.816
#> 2 2 <tib… <htes… -1.48 31.8 33.3 -0.383 0.716
#> 3 3 <tib… <htes… -0.563 32.7 33.3 -0.305 0.769
#> # … with 5 more variables: parameter <dbl>, conf.low <dbl>,
#> # conf.high <dbl>, method <chr>, alternative <chr>
如果需要,您可以做一些事情来显示每对中的位置 - 加入查找 table 是一种方法。
我也意识到你提到过想在之后使用 broom
函数,但没有指定你 需要 一个 broom::tidy
调用。在那种情况下,只需删除最后两行。
一点基础 R 就可以解决问题:
combn(x=unique(sample_long$Location), m=2, simplify=FALSE,
FUN=function(l) {
t.test(distro ~ Location, data=subset(sample_long, Location %in% l))
})
combn
将一次生成 x
元素的所有组合 m
(原文如此)。结合 subset
,您会将测试应用于 data.frame.
的子集
我有兴趣对单个变量执行多个测试,该变量具有将值分成多个组的关联因子。它与
在我的例子中,我有一个变量和多个组(最终有很多)。扩展
library(reshape)
# Create a dataset
mu=34
stdv=5
Location=rep(c("Area_A","Area_B","Area_C"),5)
distro=rnorm(length(Location),mu,stdv)
id=seq(1:length(Location))
sample_long=data.frame(id,Location,distro)
sample_long
id Location distro
1 1 Area_A 34.95737
2 2 Area_B 31.30298
3 3 Area_C 35.86569
4 4 Area_A 40.45378
5 5 Area_B 36.12060
6 6 Area_C 28.29649
7 7 Area_A 30.64495
8 8 Area_B 29.70668
9 9 Area_C 33.22874
10 10 Area_A 25.29148
11 11 Area_B 32.35511
12 12 Area_C 34.69159
13 13 Area_A 26.89791
14 14 Area_B 35.30717
15 15 Area_C 40.64628
我想在区域之间进行全对抗测试,即测试(Area_A,Area_B),测试(Area_A,Area_C)和test(Area_B,Area_C)(在更一般的情况下,所有 i<j
可能的测试)。
一种简单的方法是将数据转换为宽格式:
# Reshape to wide format
sample_wide=reshape(sample_long,direction="wide",idvar="id",timevar="Location")
sample_wide
id distro.Area_A distro.Area_B distro.Area_C
1 1 34.95737 NA NA
2 2 NA 31.30298 NA
3 3 NA NA 35.86569
4 4 40.45378 NA NA
5 5 NA 36.12060 NA
6 6 NA NA 28.29649
7 7 30.64495 NA NA
8 8 NA 29.70668 NA
9 9 NA NA 33.22874
10 10 25.29148 NA NA
11 11 NA 32.35511 NA
12 12 NA NA 34.69159
13 13 26.89791 NA NA
14 14 NA 35.30717 NA
15 15 NA NA 40.64628
然后遍历所有列,我已经看到几个 approximations 比我使用 for 循环的下面一个更像 R:
# Now compute the test
test.out=list()
k=0
for(i in 2:(dim(sample_wide)[2]-1)){ # All against all var groups
for(j in (i+1):dim(sample_wide)[2]){
k=k+1
test.out[[k]]=t.test(sample_wide[,i],
sample_wide[,j]) # store results in a list
}
}
但我的问题是不是考虑到宽格式哪个是最佳解决方案,但是否有可能找到解决问题的解决方案原始的长格式,与我在上面提供的使用dplyr
、broom
等链接找到的解决方案一致
这比我希望的要复杂一些,也不那么简单。您可以先找出位置的组合,然后将其保存在查找 table 中以使其更简单一些。我把它变成了一个长形,每对都有一个 ID,我将把它用作数据的分组变量。
library(dplyr)
library(tidyr)
library(purrr)
set.seed(111)
# same data creation code
grps <- as.data.frame(t(combn(levels(sample_long$Location), 2))) %>%
mutate(pair = row_number()) %>%
gather(key, value = loc, -pair) %>%
select(-key)
grps
#> pair loc
#> 1 1 Area_A
#> 2 2 Area_A
#> 3 3 Area_B
#> 4 1 Area_B
#> 5 2 Area_C
#> 6 3 Area_C
将查找加入到数据框会使行数加倍——这将根据您合并的级别数而有所不同。另请注意,我删除了您的 ID 列,因为现在似乎没有必要。嵌套,做t检验,整理结果。
sample_long %>%
select(-id) %>%
inner_join(grps, by = c("Location" = "loc")) %>%
group_by(pair) %>%
nest() %>%
mutate(t_test = map(data, ~t.test(distro ~ Location, data = .)),
tidied = map(t_test, broom::tidy)) %>%
unnest(tidied)
#> # A tibble: 3 x 13
#> pair data t_test estimate estimate1 estimate2 statistic p.value
#> <int> <lis> <list> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 <tib… <htes… -0.921 31.8 32.7 -0.245 0.816
#> 2 2 <tib… <htes… -1.48 31.8 33.3 -0.383 0.716
#> 3 3 <tib… <htes… -0.563 32.7 33.3 -0.305 0.769
#> # … with 5 more variables: parameter <dbl>, conf.low <dbl>,
#> # conf.high <dbl>, method <chr>, alternative <chr>
如果需要,您可以做一些事情来显示每对中的位置 - 加入查找 table 是一种方法。
我也意识到你提到过想在之后使用 broom
函数,但没有指定你 需要 一个 broom::tidy
调用。在那种情况下,只需删除最后两行。
一点基础 R 就可以解决问题:
combn(x=unique(sample_long$Location), m=2, simplify=FALSE,
FUN=function(l) {
t.test(distro ~ Location, data=subset(sample_long, Location %in% l))
})
combn
将一次生成 x
元素的所有组合 m
(原文如此)。结合 subset
,您会将测试应用于 data.frame.