Создание матрицы совместного вхождения из многих переменных и ее построение - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть набор данных людей с рядом заболеваний.У людей либо есть (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()   

Возможно, это совсем не правильный подход, и мне действительно нужно преобразовать данные в матрицу 3х3.Любые возможные решения будут с благодарностью приняты!

1 Ответ

0 голосов
/ 08 февраля 2019

Вот способ

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 s, чтобы получить желаемый результат.

...