r语言 - 一种执行多个成对测试(例如 t 检验)的紧凑方法,其中单个变量在长格式的多个类别中拆分



我有兴趣对单个变量执行多个测试,该变量具有将值分成多个组的相关因子。它与这个问题有关,实际上,我想得到这样的解决方案,但它并不完全相同。

就我而言,我有一个变量和多个组(最终是很多组(。扩展此示例:

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(和测试(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

然后遍历全对全列,为此,我已经看到了几个比我使用的 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
}
}

但是我的问题不是关于在宽格式的情况下哪个是最佳解决方案,而是是否有可能找到解决从原始长格式工作的问题的解决方案,与我上面提供的使用dplyrbroom等的链接找到的解决方案一致。

这比我希望的要棘手,也没那么简单。您可以先找出位置的组合,为了简化一点,将其保存在查找表中。我将其转换为一个长形状,每对都有一个 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>

如果需要,您可以执行一些操作来显示每对中的位置 - 与查找表连接将是执行此操作的一种方法。

我还意识到您提到之后想要使用broom函数,但没有指定您需要broom::tidy调用。在这种情况下,只需删除最后 2 行。

一点基本的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将一次生成mx元素的所有组合(原文如此(。结合subset,您将测试应用于 data.frame 的子集。

最新更新