r从数据框中的列创建邻接矩阵

Lil*_*ten 6 r graph igraph adjacency-matrix

我有兴趣测试一些网络可视化技术,但在尝试这些功能之前,我想使用数据帧构建一个邻接矩阵(from,to),如下所示.

 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
Run Code Online (Sandbox Code Playgroud)

我的目标是创建一个邻接矩阵,如下所示

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
Run Code Online (Sandbox Code Playgroud)

例如,pain, sleep, Bump, muscle, hemaloma具有关键字Cold的列下的单元格值是,它们将形成行和单元格值,例如infection, medication, Callus, walking, twitching, flutter在具有关键字Hot的列下,这将形成关联矩阵的列.

最终所需的输出应如下所示:

           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
Run Code Online (Sandbox Code Playgroud)
  • [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")
Run Code Online (Sandbox Code Playgroud)

Wei*_*ong 1

一种方法是将数据集变成“整齐”的形式,然后使用xtabs. 首先,进行一些清理工作:

df[] <- lapply(df, as.character)  # Convert factors to characters
df[df == "NA" | df == "" | is.na(df)] <- NA  # Make all blanks NAs
Run Code Online (Sandbox Code Playgroud)

现在,整理数据集:

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))
Run Code Online (Sandbox Code Playgroud)

这个想法是将每个“冷”列与每个“热”列“配对”以形成一个长数据集。out看起来像这样:

out
#        cold        hot
# 1      pain  infection
# 2      Bump       <NA>
# 3      <NA>     Callus
# 4    muscle       <NA>
# 5      pain medication
# ...
Run Code Online (Sandbox Code Playgroud)

最后,使用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
Run Code Online (Sandbox Code Playgroud)