原文见https://www.statworx.com/de/blog/interactive-network-visualization-with-r/
网络无处不在。我们有社会网络如脸书,竞争产品网络或组织内的各种网络。对STARWORX公司来讲,揭示网络背后隐藏的结构和类群是再普通不过的任务了。过去,用Gephi工具把网络分析结果进行可视化。它极致的美丽和交互可视化给人印象深刻,我们的想在R中找到同样高质量的可视化方法,用R shiny app提供给我们的客户。
首先我们想用igraph来可视化网络。这个R包包含一系列的网络分析工具,重点关注高效、便携和易用。我们过去把它用于我们的helfRlein包的getnetwork函数。不幸的是,igraph虽然能创造出优雅的网络可视化效果,但是他们都是静止的。为了构建交互可视化的网络,可以采用R中特定的包,它们都采用java脚本库。
我们最喜欢的可视化任务包是visNetwork,它采用vis.js java脚本库,基于htmlwidgets。它与Shiny、R Markdown文本、RStudio可视化包兼容。visNetwork对个性化你的网络有很多调整,有非常漂亮的输出和良好的操作性。在Shiny输出是这些都是极其重要的。进一步可以在这里(http://datastorm-open.github.io/visNetwork/)找到非常棒的文档。
让我们浏览一下用R Shiny从你的数据直到完美可视化必须要经过的步骤。为此,我们采用Misérables Characters网络为例。这个无向的网络包含Victor Hugo’s 小说 ‚Les Misérables‘中共出现的角色。节点代表人物,节点中间的连线表示在书中同一个章节中两个人物共同出现。每个连线的权重表示人物共同出现的频率。
数据准备
首先安装R报,install.packages("visNetwork"),加载数据lesmis。数据在geomnet包中。
可是化 Les Miserables 人物的网络,visNetwork包需要两个数据框。一个是网络的节点,另一个是网络的边。幸运的是加载的数据都提供了,我们只需要把它们以正确的格式引入。
rm(list = ls())
# Libraries ---------------------------------------------------------------
library(visNetwork)
library(geomnet)
library(igraph)
# Data Preparation --------------------------------------------------------
#Load dataset
data(lesmis)
#Nodes
nodes <- as.data.frame(lesmis[2])
colnames(nodes) <- c("id", "label")
#id has to be the same like from and to columns in edges
nodes$id <- nodes$label
#Edges
edges <- as.data.frame(lesmis[1])
colnames(edges) <- c("from", "to", "width")
以下的函数需要特定的名称来命名每一列,以检测到正确的列。为此,连线必须是带有至少一列的数据框,指明了节点的边起始和终止。对于节点,需要最少一个唯一的ID,要与边的起始和终止数据保持一致。
节点Nodes:
·label: A column that defines how a node is labelled
·value: Defines the size of a node inside the network
·group: Assigns a node to a group; this can be a result of a cluster analysis or a community detection
·shape: Defines how a node is presented. For example as a circle, square or triangle
·color: Defines the color of a node
·title: Sets the tooltip, which occurs when you hover over a node (this can be HTML or character)
·shadow: Defines if a node has a shadow or not (TRUE/FALSE)
边Edges:
·label, title, shadow
·length, width: Defines the length/width of an edge inside the network
·arrows: Defines where to set a possible arrow on the edge
·dashes: Defines if the edges should be dashed or not (TRUE/FALSE)
·smooth: Smooth lines (TRUE/FALSE)
这些都是最重要的参数,他们特别为每个节点和边定制。为设定所有的节点或边的形状,如同样的外观或箭头,可以用visNodes和visEdges来指定输出的结果。随后我们也会展示。
另外,我们想在groups内部有更有趣的网络,可以通过随后给网络中的边加入颜色加以强调。因此,我们用Louvain社区检测的方法聚类数据,得到一个group的列。
#Create graph for Louvain
graph <- graph_from_data_frame(edges, directed = FALSE)
#Louvain Comunity Detection
cluster <- cluster_louvain(graph)
cluster_df <- data.frame(as.list(membership(cluster)))
cluster_df <- as.data.frame(t(cluster_df))
cluster_df$label <- rownames(cluster_df)
#Create group column
nodes <- left_join(nodes, cluster_df, by = "label")
colnames(nodes)[3] <- "group"
可选的输出
当我们创造输出时,进行设计和功能选择,为了给出一个可能的印象,我们为Les Misérables给出两个深层次的展示结果。
visNetwork(nodes, edges)
image.png
用管道函数加上 visNodes, visEdges, visOptions, visLayout 或visIgraphLayout等函数,可以自定义网络。
visNetwork(nodes, edges, width = "100%") %>%
visIgraphLayout() %>%
visNodes(
shape = "dot",
color = list(
background = "#0085AF",
border = "#013848",
highlight = "#FF8000"
),
shadow = list(enabled = TRUE, size = 10)
) %>%
visEdges(
shadow = FALSE,
color = list(color = "#0085AF", highlight = "#C62F4B")
) %>%
visOptions(highlightNearest = list(enabled = T, degree = 1, hover = T),
selectedBy = "group") %>%
visLayout(randomSeed = 11)
image.png
visNodes 和 visEdges 表述了网络中节点和边的整体外观。例如,可以为所有的节点设置形状,为每一条边设定颜色。
用R进行发布,可能导致花很长时间才能得到网络。为解决这个问题,采用visIgraph函数。它减少了绘图时间,同时事先协调运算提供了所有可能的igraph排布。
用visOptions,可以在我们进行交互时,调整网络的应答。例如,在我们点击一个节点时会出现什么。
visLayout可以使得我们定义一个网络的外观。是层次聚类或用特殊的算法改进的排布图。进一步,可以提供一个种子(randomSeed),因此当你加载时,网络看起来都一样。
在自定义网络时,只有几个实例函数。R包提供了更多的可视化选项。更多的内容见(http://datastorm-open.github.io/visNetwork/)。
Shiny整合
为了给客户呈现交互式的结果,我们想把他们整合到Shiny app中。因此准备了离线的数据,保存了节点和边的文件,制定了在线Shiny app内部的输出。这里展示了一个用Shiny的一小段代码。
global.R:
library(shiny)
library(visNetwork)
server.R:
shinyServer(function(input, output) {
output$network <- renderVisNetwork({
load("nodes.RData")
load("edges.RData")
visNetwork(nodes, edges) %>%
visIgraphLayout()
})
})
ui.R:
shinyUI(
fluidPage(
visNetworkOutput("network")
)
)
以下展示了Shiny app结果的截屏。
image.png
结论
除了R中可视化网络的其它包,visNetwork我情有独钟。强大的包能在直接在R中能创造出交互式的网络,并用Shiny进行发布。可以把网络直接整合到Shiny应用中,当用visIgaphLayout函数时进行稳定应用。而不再需要外部软件如Gephi等。
参考文献
Knuth, D. E. (1993) „Les miserables: coappearance network of characters in the novel les miserables“, The Stanford GraphBase: A Platform for Combinatorial Computing, Addison-Wesley, Reading, MA
网友评论