R Markdown:使用 for 循环(或函数)时,visNetWork 未显示在 html 输出中

R Markdown: visNetWork not displayed in html output when using for loops (or functions)

我的 visNetwork 在 for 循环中尝试显示时根本不显示。在常规 R 脚本中,我使用 print 函数,它工作得很好,但它在 R Markdown 文档中不起作用。

这是一个(希望)可重现的例子:

---
title: "I want my beautiful networks back!"
---

# First example that works

```{r}
require(visNetwork, quietly = TRUE)
# minimal example
nodes <- data.frame(id = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))
vn <- visNetwork(nodes, edges, width = "100%")
vn # Or print(vn)
```

# When does it not work?

## In a for loop

```{r}
for (i in 1) vn
```

## In a for loop + using print

This will display the network in the Viewer.

```{r}
for (i in 1) print(vn)
```

## And also in functions

Same remark...

```{r}
foo <- function(x) print(x)
foo(vn)
```

我使用的是 Rstudio 版本 1.1.383 和 这是 sessionInfo()

的结果
R version 3.4.2 (2017-09-28)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Sierra 10.12.6

other attached packages:
[1] visNetwork_2.0.2

我刚刚找到了一个小的解决方法,包括以下步骤:

  • 将情节另存为HTML
  • 在 RMD 文件中包含 HTML 代码

举个例子:

```{r}
for (i in 1:3){
  visSave(vn, file = paste0("test",i,".html"))
}
```

```{r, results='asis'}
for (i in 1:3){
  cat(htmltools::includeHTML(paste0("test",i,".html")))
}
```

另一个解决方案是使用print(htmltools::tagList())

这可以防止在输出中显示 !DOCTOOLS。

```{r}
for (i in 1) print(htmltools::tagList(vn))
```

我在使用 Datatables 时遇到了同样的问题/解决方案,@Yihui 在这里提供了解决方案:https://github.com/rstudio/DT/issues/67

Edit 从那以后我意识到你至少需要一个在循环之外绘制的 visnetwork,即在 print(htmltools::taglist() 之外),否则要呈现的脚本不会添加到 html 文件。

您可以通过对字符串进行操作来删除!DOCTYPE。

cat (as.character(htmltools::includeHTML(paste0("vn",".html"))) %>%
  {gsub("<!DOCTYPE html>","",.,fixed = TRUE)} %>%
  {sub("\n","",.)}
)

我有同样的问题,但也想从命令行编织我的 Rmd,而不是在 RStudio 中,以便轻松生成许多不同参数的报告,例如:

Rscript -e "rmarkdown::render('graphical-res-vis-reports.Rmd', \
      params = list(tissue = '${tissue}'), \
      output_file = sprintf('graphical-analysis-results_%s.html','${tissue}'))"

htmltools::includeHTML(html_path) 技巧在 RStudio 中编织时效果很好,但当我尝试从命令行编织它时它吐出了一个 pandoc 错误,因为它有效地连接了多个独立的 HTMLs,这不会导致有效的 HTML 格式。 (编辑: pandoc 错误也可能是因为命令行中的 R 使用的 pandoc 版本比 RStudio 旧得多,但使用 iframes 仍然更干净。)

我终于找到了一个使用 iframe 的解决方案,效果很好。这是一个最小的可重现示例:

---
title: "Finally, a way to print visNetworks in a loop!"
---

```{r make networks}
require(visNetwork, quietly = TRUE)
# minimal example
nodes <- data.frame(id = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))

html_list <- c()
for (i in 1:3){
    vn <- visNetwork(nodes, edges)
    outfile <- sprintf("vn_%s.html", i)
    visSave(vn, file=outfile)
    html_list <- c(html_list, outfile)
}
```

```{r plot networks, results="asis"}
for (i in html_list){
    print(htmltools::tags$iframe(title = "My embedded document", 
          src = f, height = "650", width = "900", frameBorder = "0"))
}
```

编辑: 请注意,更改 iframe 的高度和宽度不会调整 HTML 文件中对象的大小。但是,您可以通过简单的文本替换来增加 visNetwork HTML 对象的大小。在此示例中,我删除了空白填充并将大小从 960x500 更改为 960x960:

visSave(v1, file = out_html)

# adjust browser window size 
cmd = sprintf('sed -i \'s|"browser":{"width":960,"height":500,"padding":40,"fill":false}|"browser":{"width":960,"height":960,"padding":0,"fill":false}|\' %s', out_html)
system(cmd)