繁体   English   中英

我如何使用 dplyr 计算 R 中组之间的相关性?

[英]How i can calculate the correlation between groups in R using dplyr?

假设我在 R 中有如下所示的数据框:

var = c(rep("A",3),rep("B",3),rep("C",3),rep("D",3),rep("E",3))
y = rnorm(15)
data = tibble(var,y);data

带输出:

# A tibble: 15 x 2
   var        y
   <chr>  <dbl>
 1 A     -1.23 
 2 A     -0.983
 3 A      1.28 
 4 B     -0.268
 5 B     -0.460
 6 B     -1.23 
 7 C      1.87 
 8 C      0.416
 9 C     -1.99 
10 D      0.289
11 D      1.70 
12 D     -0.455
13 E     -0.648
14 E      0.376
15 E     -0.887

我想使用 dplyr 计算 R 中每个不同对的相关性。 理想情况下,我希望看起来像这样(第三列包含每个相关对的值):

变量1 变量2 价值
一个 心电图(A,B)
一个 C 心电图(A,C)
一个 D 心(A,D)
一个 心(A,E)
C 心(乙,乙)
D 心(乙,乙)
心(乙,乙)
C D 科尔(C,E)
C 科尔(C,E)
D 心电图(D,E)

我怎么能在 R 中做到这一点? 有什么帮助吗?

额外的

如果我有另一个分组变量说 group2:

var2 = c(rep("A",3),rep("B",3),rep("C",3),rep("D",3),rep("E",3),rep("F",3),
        rep("H",3),rep("I",3))

y2 = rnorm(24)
group2 = c(rep(1,6),rep(2,6),rep(3,6),rep(1,6))
data2 = tibble(var2,group2,y2);data2

理想情况下必须是这样的:

团体 变量1 变量2 价值
1 一个 心电图(A,B)
1 一个 H 心电图(A,H)
1 一个 心电图(A,I)
1 H 心(B,H)
1 心(乙,我)
1 H 心电图(H,I)
2 C D 心(C,D)
3 F 心(E,F)

我如何计算每个组 group2 的列 var2 中的每个变量?

另一种可能的解决方案:

library(tidyverse)

df %>% 
  group_by(var) %>% 
  group_map(~ data.frame(.x) %>% set_names(.y)) %>% 
  bind_cols %>% cor %>% 
  {data.frame(row=rownames(.)[row(.)[upper.tri(.)]], 
              col=colnames(.)[col(.)[upper.tri(.)]], 
              corr=.[upper.tri(.)])}

#>    row col       corr
#> 1    A   B -0.9949738
#> 2    A   C -0.9574502
#> 3    B   C  0.9815368
#> 4    A   D -0.7039708
#> 5    B   D  0.6293137
#> 6    C   D  0.4690460
#> 7    A   E -0.5755463
#> 8    B   E  0.4907660
#> 9    C   E  0.3150499
#> 10   D   E  0.9859711

这是通过基础 R 的单线

data.frame(t(combn(unique(data$var), 2, function(i)
                     list(v1 = i[[1]], 
                          v2 = i[[2]], 
                          value = cor(data$y[data$var %in% i[[1]]], 
                                      data$y[data$var %in% i[[2]]])))))

   X1 X2         X3
1   A  B   0.997249
2   A  C  0.7544987
3   A  D -0.7924587
4   A  E 0.03567887
5   B  C  0.8010711
6   B  D -0.7450683
7   B  E  0.1096579
8   C  D -0.1976141
9   C  E  0.6828033
10  D  E  0.5812632

1)添加一个索引列 1, 2, 3, 1, 2, 3, ... 然后使用 read.zoo 将 long 转换为 wide。 使用 as.data.frame.table 将相关重塑回长格式并过滤掉所需的行。

library(dplyr)
library(zoo)

DF %>%
  mutate(index = sequence(rle(var)$lengths)) %>%
  read.zoo(index = "index", split = "var") %>%
  cor %>%
  as.data.frame.table(responseName = "cor") %>%
  filter(format(Var1) < format(Var2))

2)以多一行代码为代价,我们可以用 pivot_wider 代替 read.zoo。

library(dplyr)
library(tidyr)

DF %>%
  mutate(index = sequence(rle(var)$lengths)) %>%
  pivot_wider(index, names_from = "var", values_from = "y") %>%
  select(-index) %>%
  cor %>%
  as.data.frame.table(responseName = "cor") %>%
  filter(format(Var1) < format(Var2))

3)基本解决方案包括使用 combn 获得具有指定函数 f 的 var 对。

co <- combn(unique(DF$var), 2)
f <- function(v) with(DF, data.frame(t(v), cor = cor(y[var==v[1]], y[var==v[2]])))
do.call("rbind", apply(co, 2, f))

笔记

可重现形式的输入。

DF <-
structure(list(var = c("A", "A", "A", "B", "B", "B", "C", "C", 
"C", "D", "D", "D", "E", "E", "E"), y = c(-1.23, -0.983, 1.28, 
-0.268, -0.46, -1.23, 1.87, 0.416, -1.99, 0.289, 1.7, -0.455, 
-0.648, 0.376, -0.887)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15"))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM