【发布时间】:2019-11-28 00:03:48
【问题描述】:
我正在使用igraph 函数创建一个三方图,将一位讲师 (A) 与参加该讲师指导的 3 个俱乐部的学生列表(B 到 R)联系起来。学生有 2 个班级的交叉成员资格,并且可能具有相同的性别。最后,边的宽度代表教练和每个学生在给定周内平均投入每个俱乐部的时间。
创建图表很简单(我的代码在下面提供),但鉴于我的列表总共包含 17 名学生(B 到 R),最好以水平方式呈现图表将讲师 (A) 放在顶部,将 3 个俱乐部放在中间,将 17 名学生 (B 到 R) 放在底部。我怀疑这是因为我在图表中使用了layout_with_sugiyama(),但是任何人都可以提出替代方案来实现我想要的水平布局吗?
以下是我当前用于此图表的R 代码:
rm(list=ls())
library(foreign)
library(igraph)
library(dplyr)
### create tripartite node list and pairwise attributes
time <- data.frame(student = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D", "E", "E", "E", "F", "F", "F", "G", "G", "G", "H", "H", "H", "I", "I", "I", "J", "J", "J", "K", "K", "K", "L", "L", "L", "M", "M", "M", "N", "N", "N", "O", "O", "O", "P", "P", "P", "Q", "Q", "Q", "R", "R", "R"),
club = c("club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3", "club 1", "club 2", "club 3"),
hours = c(10, 3, 6, 5, 2, 1, 3, 3, 2, 7, 5, 11, 1, 0, 3, 8, 2, 2, 2, 2, 0, 5, 7, 11, 1, 0, 1, 0, 1, 3, 8, 9, 2, 0, 0, 3, 4, 3, 6, 3, 1, 0, 3, 1, 7, 0, 0, 1, 0, 1, 5, 1, 3, 3))
### convert time dataframe into a graph object
df <- time[!time$hours == 0, ]
g <- graph_from_data_frame(df, directed = FALSE)
E(g)$width <- log(E(g)$hours)
### parse the data into three disjoint sets, use different node shapes to distinguish them
A <- "A"
club <- c("club 1", "club 2", "club 3")
V(g)$type <- 1
V(g)[name %in% club]$type <- 2
V(g)[name %in% "A"]$type <- 3
shape <- c("circle", "square", "circle")
size <- c(12, 15, 12)
### label class affiliation (except node A; G, K, L, Q do not belong to any classes)
Class1 <- c("B", "C", "E", "H", "J", "O")
Class2 <- c("D", "F", "M", "P", "I", "N", "R")
V(g)$color[V(g)$name] = "white"
V(g)$color[V(g)$name %in% Class1] = "red"
V(g)$color[V(g)$name %in% Class2] = "orange"
V(g)$color[V(g)$name == "A"] = "olivedrab1"
### highlight same sex nodes
s <- c("B", "D", "F", "G", "H", "K", "M", "P", "Q")
s_col = ifelse(V(g)$name %in% s,'black','grey80')
layout = layout_with_sugiyama(g, layers=V(g)$type)
V(g)$vertex_degree <- igraph::degree(g)
plot(g,
layout=cbind(V(g)$type, layout$layout[,1]), edge.curved=0,
vertex.color = V(g)$color,
vertex.label.color = "black",
vertex.label.cex = 0.45,
vertex.size = size[V(g)$type],
vertex.shape = shape[V(g)$type],
vertex.frame.color = s_col,
edge.color= "grey30",
asp = 1.3,
edge.width = E(g)$width
)
上面的代码生成了这个图。
但我想要的输出应该是这样的
【问题讨论】:
-
添加所需输出的图像可能会有所帮助。我的想法是切换列 a̶n̶d̶̶r̶e̶v̶e̶r̶s̶e̶̶t̶h̶e̶̶o̶r̶d̶e̶r̶:
cbind(layout$layout[,1], V(g)$type)。但这不是你要找的,不是吗? -
@Ben,感谢您的提醒,我将添加一张我想要的输出的图片。