我有一组具有多种健康状况的个人数据。每个人都有(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矩阵。任何可能的解决方案将不胜感激!
答案 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-b
和b-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
以获得所需的输出。