从许多变量创建同现矩阵,并将其绘制

时间:2019-02-08 10:19:08

标签: r dplyr tidyr

我有一组具有多种健康状况的个人数据。每个人都有(1)或没有(0)的每个条件(我的真实数据集有14个)。我想做的是汇总数据,这样我就知道发生几对情况。请注意,有些人可能有三个或四个条件,但我感兴趣的是成对共现。然后,我想将其绘制为热图。

我怀疑该解决方案涉及tidyr的“聚集”功能,但我无法解决该问题。这是我的输入看起来和我想要实现的示例:

以下是一些有关个人的数据以及他们是否具有条件“ a”,“ b”或“ c”:

library(tidyverse)
library(viridis)

dat <- tibble(
  id = c(1:15),
  a = c(1,0,0,0,1,1,1,0,1,0,0,0,1,0,1),
  b = c(1,0,0,1,1,1,0,0,1,0,0,1,1,0,1),
  c = c(0,0,1,1,0,1,0,1,0,1,1,0,1,1,0))

我想总结一下每种情况发生的频率以及它们共同发生的频率。在这种情况下,很明显,条件“ a”和“ b”的出现频率要比其中任何一个与“ c”的发生频率更高,后者通常独立发生。以下是我对图表格式的数据的想象构想。第一列是“变量1”,第二列是“变量2”,第三列是这些变量一起出现的频率的计数。下面是我脑海中的情节。

plotdat <- tibble(
  var1 = c("a", "a", "a", "b", "b", "c"),
  var2 = c("a", "b", "c", "b", "c", "c"),
  count = c(7, 6, 2, 8, 3, 8))

ggplot(plotdat) +
  geom_tile(aes(var1, var2, fill = count)) +
  scale_fill_viridis()   

也许这根本不是正确的方法,我实际上需要将数据转换为3x3矩阵。任何可能的解决方案将不胜感激!

1 个答案:

答案 0 :(得分:0)

这是一种方法

library(tidyverse)
as.matrix(dat[-1]) %>% 
  crossprod() %>% 
  `[<-`(upper.tri(.), NA) %>% 
  as.data.frame() %>% 
  rownames_to_column() %>% 
  gather(key, value, -rowname) %>%
  filter(!is.na(value))
#  rowname key value
#1       a   a     7
#2       b   a     6
#3       c   a     2
#4       b   b     8
#5       c   b     3
#6       c   c     8

我认为最重要的是crossprod。但是,让我们逐步进行一下。

您不需要列id,因此我们将其排除在外,并将dat[-1]转换为矩阵,因为这正是crossprod的期望。

as.matrix(dat[-1]) %>% 
  crossprod()
#  a b c
#a 7 6 2
#b 6 8 3
#c 2 3 8

然后我们用NA替换该矩阵的上三角,因为您不想比较a-bb-a等。

下一步是转换为数据框,将行名设置为列,然后从宽变长。

as.matrix(dat[-1]) %>% 
  crossprod() %>% 
  `[<-`(upper.tri(.), NA) %>% 
  as.data.frame() %>% 
  rownames_to_column() %>% 
  gather(key, value, -rowname)
#  rowname key value
#1       a   a     7
#2       b   a     6
#3       c   a     2
#4       a   b    NA
#5       b   b     8
#6       c   b     3
#7       a   c    NA
#8       b   c    NA
#9       c   c     8

最后删除NA以获得所需的输出。