Р создание матрицы смежности из столбцов в таблице данных
мне интересно протестировать некоторые методы визуализации сети, но прежде чем попробовать эти функции, я хочу построить матрицу смежности (От, До) с помощью фрейма данных, который выглядит следующим образом.
Id Gender Col_Cold_1 Col_Cold_2 Col_Cold_3 Col_Hot_1 Col_Hot_2 Col_Hot_3
10 F pain sleep NA infection medication walking
14 F Bump NA muscle NA twitching flutter
17 M pain hemoloma Callus infection
18 F muscle pain twitching medication
моя цель-создать матрицу смежности следующим образом
1) All values in columns with keyword Cold will contribute to the rows
2) All values in columns with keyword Hot will contribute to the columns
например, pain, sleep, Bump, muscle, hemaloma
значения ячеек в Столбцах с ключевым словом холод и они будут формировать строки и значения ячеек, такие как infection, medication, Callus, walking, twitching, flutter
находятся под Столбцами с ключевыми словами горячий и это будет формировать столбцы матрицы ассоциаций.
конечный желаемый результат должен выглядеть так:
infection medication walking twitching flutter Callus
pain 2 2 1 1 1
sleep 1 1 1
Bump 1 1
muscle 1 1
hemaloma 1 1
[pain, infection]
= 2, потому что связь между болью и инфекцией возникает дважды в исходном фрейме данных: один раз в строке 1 и снова в строке 3.[pain, medication]
=2, потому что связь между болью и лекарством происходит дважды один раз в строке 1 и снова в строке 4.
любые предложения или советы по созданию такой матрицы ассоциаций очень ценятся спасибо.
Воспроизводимый Набор Данных
df = structure(list(id = c(10, 14, 17, 18), Gender = structure(c(1L, 1L, 2L, 1L), .Label = c("F", "M"), class = "factor"), Col_Cold_1 = structure(c(4L, 2L, 1L, 3L), .Label = c("", "Bump", "muscle", "pain"), class = "factor"), Col_Cold_2 = structure(c(4L, 2L, 3L, 1L), .Label = c("", "NA", "pain", "sleep"), class = "factor"), Col_Cold_3 = structure(c(1L, 3L, 2L, 4L), .Label = c("NA", "hemaloma", "muscle", "pain" ), class = "factor"), Col_Hot_1 = structure(c(4L, 3L, 2L, 1L), .Label = c("", "Callus", "NA", "infection"), class = "factor"), Col_Hot_2 = structure(c(2L, 3L, 1L, 3L), .Label = c("infection", "medication", "twitching"), class = "factor"), Col_Hot_3 = structure(c(4L, 2L, 1L, 3L), .Label = c("", "flutter", "medication", "walking" ), class = "factor")), .Names = c("id", "Gender", "Col_Cold_1", "Col_Cold_2", "Col_Cold_3", "Col_Hot_1", "Col_Hot_2", "Col_Hot_3" ), row.names = c(NA, -4L), class = "data.frame")
1 ответов
один из способов-сделать набор данных в "ухоженном" виде, а затем использовать xtabs
. Во-первых, некоторые очистки:
df[] <- lapply(df, as.character) # Convert factors to characters
df[df == "NA" | df == "" | is.na(df)] <- NA # Make all blanks NAs
теперь очистите набор данных:
library(tidyr)
library(dplyr)
out <- do.call(rbind, sapply(grep("^Col_Cold", names(df), value = T), function(x){
vars <- c(x, grep("^Col_Hot", names(df), value = T))
setNames(gather_(select(df, one_of(vars)),
key_col = x,
value_col = "value",
gather_cols = vars[-1])[, c(1, 3)], c("cold", "hot"))
}, simplify = FALSE))
идея состоит в том, чтобы" соединить "каждый из" холодных "столбцов с каждым из" горячих " столбцов, чтобы сделать длинный набор данных. out
выглядит так:
out
# cold hot
# 1 pain infection
# 2 Bump <NA>
# 3 <NA> Callus
# 4 muscle <NA>
# 5 pain medication
# ...
наконец, использовать xtabs
чтобы сделать желаемый результат:
xtabs(~ cold + hot, na.omit(out))
# hot
# cold Callus flutter infection medication twitching walking
# Bump 0 1 0 0 1 0
# hemaloma 1 0 1 0 0 0
# muscle 0 1 0 1 2 0
# pain 1 0 2 2 1 1
# sleep 0 0 1 1 0 1