是否可以在 R 包 visNetwork 中以编程方式将网络列表逐一导出到 PNG?

Is it possible to programmatically export a list of networks one by one to PNG in the R package visNetwork?

我尝试了 visExport() 的示例代码,并且能够将 "Export as PNG" 按钮添加到 Shiny 网页。但这需要用户交互来按下按钮将网络导出到 PNG 图像文件。

我有超过一百个网络,我想将它们分别导出到一个 PNG 文件中。其中一些需要定期更新。因此,如果用户无需为每个网络按下 "Export as PNG" 按钮,就可以将它们全部导出为 PNG 文件,这在逻辑上会很好。

那么是否可以通过编程将网络列表逐一导出到 PNG?这就像 visSave() 为每个网络逐一导出 HTML。

简短的回答必须是 "Yes",但是由于您没有给我们任何示例代码,所以不可能给您一个经过测试的解决方案。但是你说你有一百个网络。让我们假设在一个向量 networks 中。 (只要对下面的示例代码稍作改动,列表就可以正常工作。)您可以使用闪亮按钮导出一个图表。所以你必须有代码来创建一个单一的网络图像。假设它在一个函数 createImageForNetwork(x) 中,其中 x 是一个网络。您还需要一个函数来为每个图像创建一个输出文件名。假设这叫做 getFilename(x)。然后类似于下面未经测试的代码将执行您想要的操作:

exportNetworkImage <- function(x) {
  png(getFilename(x))
  createImageForNetwork(x)
  dev.off()
}
lapply(1:length(networks), function(x) exportNetworkImage(networks[x]))

如果您想通过在 Shiny 应用程序中单击一个按钮来做到这一点,只需将该代码放入按钮的 observeEvent 处理程序中即可。

参考其他 ,这里是使用 webshot 包的工作代码。

library(visNetwork)
library(tidyverse)
library(webshot)

# create network data
nodes = data.frame(id = numeric(),label=character(),set = numeric(),stringsAsFactors = F)
edges = data.frame(from = numeric(),to = numeric(),set = numeric(),stringsAsFactors = F)
for (i in 1:10){
  tempNodes <- data.frame(id = 1:15, label = paste("Label", 1:15), set = i)
  tempEdges <- data.frame(from = trunc(runif(15)*(15-1))+1,
                          to = trunc(runif(15)*(15-1))+1, set = i)
  nodes = rbind(nodes,tempNodes)
  edges = rbind(edges,tempEdges)
}

# loop through each set to export to PNG
for (i in 1:max(nodes$set)){
  subNodes = nodes[nodes$set==i,]
  subEdges = edges[edges$set==i,]
  network = visNetwork(subNodes, subEdges, width="100vw",height = "100vh") %>% 
    visLayout(randomSeed=1,improvedLayout=TRUE) %>% 
    visGroups(groupname = "actorImported",shape="circle") %>%  
    visEdges(smooth=FALSE) %>% 
    visPhysics(solver = "barnesHut") 
  fname = paste0("network",sprintf("%03d",i),".html")
  visSave(network,fname)
  webshot(fname,delay=0.5,zoom=2,file=paste0("network",sprintf("%03d",i),".png"),
          vwidth=900,vheight=900)
}