ggraph/igraph 中的节点不考虑分面

Nodes not respecting facetting in ggraph/igraph

我有点难以理解 ggplot2ggraph 在分面方面的区别。考虑以下数据:

library(igraph)
library(ggraph)
library(ggplot2)

df <- structure(list(x = c("H001", "H024", "H090", "H090", "H098", 
                     "H103", "H126", "H152", "H155", "H155", "B002", "B011", "B075", 
                     "B092", "M002", "M002", "M002", "M050", "M050", "M085", "M085", 
                     "M247", "M247", "M247"), 
               y = c("H103", "H126", "H152", "H155","H155", "H001", "H024", "H090", "H090", "H098", "B092", "B075", 
                      "B011", "B002", "M050", "M085", "M247", "M002", "M247", "M002", "M247", "M002", "M050", "M085"), 
               r = c(0.963248925980302, 0.991452643542894, 0.965947578382865, 
                     0.963234153063794, 0.962277411462605, 0.963248925980302, 
                     0.991452643542894, 0.965947578382865, 0.963234153063794, 
                     0.962277411462605, 0.960948147492217, 0.957371360458182, 
                     0.957371360458182, 0.960948147492217, 0.96976135236222, 
                     0.977435712803837, 0.997037031981303, 0.96976135236222, 
                     0.978553503235858, 0.977435712803837, 0.992741796542001, 
                     0.997037031981303, 0.978553503235858, 0.992741796542001), 
               facet_var = c("08MH", "08MH", "08MH", "08MH", "08MH", "08MH", "08MH", "08MH", "08MH", 
                             "08MH", "08HB", "08HB", "08HB", "08HB", "08NM", "08NM", "08NM", "08NM", 
                             "08NM", "08NM", "08NM", "08NM", "08NM", "08NM")), 
          class = "data.frame", row.names = c(NA, -24L), .Names = c("x", "y", "r", "facet_var")
)

如果我使用简单的 ggplot 绘制数据,我可以按照我认为的方式进行分面 "normal":

ggplot(df, aes(x = x, y = y)) +
         geom_point() +
         facet_wrap(~facet_var)

也就是说,facet_var 的每个级别都有一些与之关联的点,并且只有这些点被绘制在相应的方面。现在,如果我使用 ggraph 尝试类似的方法,我会遇到对我来说很奇怪的行为(尽管我显然承认这只是反映了缺乏理解):

graph_cors <- graph_from_data_frame(df, directed = FALSE)

ggraph(graph_cors) +
  geom_edge_link(aes(edge_alpha = abs(r), color = r), edge_width = 2) +
  guides(edge_alpha = "none") +
  scale_edge_colour_gradientn(limits = c(-1, 1), colors = topo.colors(5)) +
  geom_node_point(color = "black", size = 5) +
  geom_node_text(aes(label = name), repel = TRUE) +
  facet_edges(~facet_var)

因此所有节点都绘制在每个小平面中,尽管边缘尊重小平面。谁能概述一下我在这里做错了什么?

Session 信息

> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_Canada.1252  LC_CTYPE=English_Canada.1252    LC_MONETARY=English_Canada.1252 LC_NUMERIC=C                   
[5] LC_TIME=English_Canada.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggraph_1.0.0    ggplot2_2.2.1   igraph_1.1.2    testthat_1.0.2  devtools_1.13.3

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13          compiler_3.4.2        plyr_1.8.4            bindr_0.1             viridis_0.4.0        
 [6] tools_3.4.2           digest_0.6.12         viridisLite_0.2.0     memoise_1.1.0         tibble_1.3.4         
[11] gtable_0.2.0          pkgconfig_2.0.1       rlang_0.1.2           rstudioapi_0.7.0-9000 ggrepel_0.7.0        
[16] yaml_2.1.14           bindrcpp_0.2          gridExtra_2.3         withr_2.0.0           dplyr_0.7.4          
[21] grid_3.4.2            glue_1.1.1            R6_2.2.2              tweenr_0.1.5          udunits2_0.13        
[26] magrittr_1.5          scales_0.5.0          fortunes_1.5-4        MASS_7.3-47           units_0.4-6          
[31] assertthat_0.2.0      swtext_0.0.1          ggforce_0.1.1         colorspace_1.3-2      lazyeval_0.2.0       
[36] munsell_0.4.3         crayon_1.3.4    

我认为这是设计使然,您什么也没做 "wrong"。

facet_edges 在每个面板中重复节点并绘制映射到变量的边。

facet_nodes 绘制映射到变量的节点,并绘制面板中存在终端节点的边。

facet_graph - 来自其文档 - "takes care of all of these issues, allowing you to define which data type the rows and columns are referencing as well as filtering the edges based on the nodes in each panel (even when nodes are not drawn)."

因此 facet_nodesfacet_graph 的行为可能更符合您的预期。

您需要将相关变量作为节点属性分配给节点分面。您的 facet_var 变量是边缘属性;如果您将它作为节点属性分配给每个二元体中的每个节点,则分面有效。

facet_graph facets by two variables (e.g. 边属性和节点属性)。似乎 facet_nodes 是你想要的,但你需要将节点属性发送到参数,而不是边缘属性。

目前,您的 igraph 对象只有一个边缘属性:

> graph_cors
IGRAPH UN-- 16 24 -- 
+ attr: name (v/c), r (e/n), facet_var (e/c)
+ edges (vertex names):
 [1] H001--H103 H024--H126 H090--H152 H090--H155 H098--H155 H001--H103 H024--H126 H090--H152
 [9] H090--H155 H098--H155 B002--B092 B011--B075 B011--B075 B002--B092 M002--M050 M002--M085
[17] M002--M247 M002--M050 M050--M247 M002--M085 M085--M247 M002--M247 M050--M247 M085--M247

graph_cors <- graph_from_data_frame(df, directed = FALSE)

facet_nodes <- cbind(c(df[,1], df[,2]), 
                     df[match(c(df[,1], df[,2]), df[,1]),4])

# Assign the facet_var variable to corresponding dyad pairs
V(graph_cors)$facet_node <- facet_nodes[match(V(graph_cors)$name, facet_nodes[,1]),2]

现在,igraph对象有一个节点属性("facet_node"):

> graph_cors
IGRAPH UN-- 16 24 -- 
+ attr: name (v/c), facet_node (v/c), r (e/n), facet_var (e/c)
+ edges (vertex names):
 [1] H001--H103 H024--H126 H090--H152 H090--H155 H098--H155 H001--H103 H024--H126 H090--H152
 [9] H090--H155 H098--H155 B002--B092 B011--B075 B011--B075 B002--B092 M002--M050 M002--M085
[17] M002--M247 M002--M050 M050--M247 M002--M085 M085--M247 M002--M247 M050--M247 M085--M247

# Use the facet_nodes argument with the nodal attribute
ggraph(graph_cors) +
  geom_edge_link(aes(edge_alpha = abs(r), color = r), edge_width = 2) +
  guides(edge_alpha = "none") +
  scale_edge_colour_gradientn(limits = c(-1, 1), colors = topo.colors(5)) +
  geom_node_point(color = "black", size = 5) +
  geom_node_text(aes(label = name), repel = TRUE) +
  facet_nodes(~facet_node)