Узлы, не соблюдающие огранку в ggraph/igraph
У меня возникли небольшие проблемы с пониманием разницы между ggplot2
а также ggraph
в отношении огранки. Рассмотрим следующие данные:
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, я могу представить их так, как я считаю "нормальными":
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)
Так что все узлы построены в каждом фасете, хотя ребра учитывают фасетку. Кто-нибудь может обрисовать, что я здесь делаю не так?
Информация о сессии
> 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
2 ответа
Вам необходимо назначить соответствующую переменную в качестве атрибута узла для фасета по узлам. Ваш facet_var
переменная является атрибутом ребра; если вы назначите его каждому узлу в каждой диаде в качестве атрибута узла, огранка будет работать.
facet_graph
фасет от двух переменных (например, атрибут ребра и атрибут узла). Похоже на 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)
Я думаю, что это по замыслу, и вы не делаете ничего "неправильно".
facet_edges
повторяет узлы на каждой панели и рисует ребра, которые отображаются на переменную.
facet_nodes
рисует узлы, которые отображаются на переменную, и рисует ребра, для которых на панели присутствуют терминальные узлы.
facet_graph
- из документации - "заботится обо всех этих проблемах, позволяя вам определить, к какому типу данных относятся ссылки на строки и столбцы, а также отфильтровывать края на основе узлов в каждой панели (даже когда узлы не прорисованы)".
Так может случиться так, что поведение facet_nodes
или же facet_graph
больше похоже на то, что вы ожидали.