我正在公司维护 R 代码,供多名同事使用。 我决定将我的代码转换成一个包,以使其更易于共享、维护和记录。 我的包是为了保留在内部而构建的,可以在封闭的环境中使用,并且不会在 CRAN 上。我正在使用 Rstudio,它运行得相对顺利,但我在构建小插图时遇到了问题。
问题是我的代码对非常大的数据集进行了非常具体、漫长且复杂的分析。 因此,我不可能每次重建软件包时都构建小插图。 更不用说让用户在使用
devtools::install_git(build_vignettes = TRUE)
时这样做。 我在这个不错的博客中找到了这个问题的解决方案(https://ropensci.org/blog/2019/12/08/precompute-vignettes/)。 简而言之,您可以在小插图名称 .orig
之后添加 .Rmd
,这样构建过程就不会将它们识别为小插图。 然后,当您准备好时,您可以通过使用以下内容编织 .Rmd.orig
文件来预编译脚本:
knitr::knit("vignettes/longexample.Rmd.orig", output = "vignettes/longexample.Rmd")
这将为您的包创建一个快速且简单的可编译版本的小插图。 这适用于带有文本和图形的基本文档。 但是,我需要在我的插图中输入传单地图。 如果我使用此过程创建带有传单的小插图,我会收到错误:
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## Error in path.expand(path): invalid 'path' argument
我认为这是一条消息,表明 knitr 正在尝试获取我的地图的屏幕截图并将其另存为图像。 这不是我想要的,我想要一张实际的地图。
我写的小插曲:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```{r setup, message=F, warning=FALSE}
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```{r}
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
## The leaflet
```{r}
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r}
m
```
然后,我编译它:
knitr::knit("c://temp//longexample.Rmd.orig", output = "c://temp//longexample.Rmd")
产生以下输出:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```r
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```r
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
```
## I've waited this long!
```
## The leaflet
```r
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r}
m
```
```
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
```
```
## Error in path.expand(path): invalid 'path' argument
```
因此,它无法将传单传递到新的 knit markdown 文件中(这是有道理的)。
我试图通过将传单保存到这样的临时文件中来绕过这个问题(在我的
.orig
文件中):
```{r, include=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
这将保存我的地图,但随后我必须找到一种方法在编译版本中添加下一个代码块,因此它会出现并且仅在那里运行。有某种方法可以让下面的代码块按原样由knitr传递。
```{r, include=FALSE}
m <- readRDS("c://temp/temp_leaflet.rds")
```
所以我被困住了。 知道如何在预编译后将传单显示为降价/小插图吗?
这个问题可以通过让knitr knit“asis”你想要在第二次运行中编织的代码行来解决,所以在构建小插图时......要做到这一点,你可以更改部分:
```{r}
m
```
作者:
```{r, echo=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=FALSE, warning=FALSE} \n")
cat("library(leaflet) \n")
cat("m <- readRDS('c://temp/temp_leaflet.rds') \n")
cat("```")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=TRUE} \n")
cat("m \n")
cat("```")
```
首先,将地图(或数据)保存在 rds 文件中的某个位置。 然后,您使用
results="asis"
代码块选项和 cat
函数来编写仅需要在第二次编译(构建小插图时)中渲染的代码块。 所以你实际上是将 Rmarkdown 代码包装到 Rmarkdown 中......它很丑陋且令人困惑,但它有效。 使用这种方法,编织 Rmd.orig
文件后的渲染代码看起来就像正常的 Rmarkdown 代码:
```{r, echo=FALSE, warning=FALSE}
library(leaflet)
m <- readRDS('c://temp/temp_leaflet.rds')
```
```{r, echo=TRUE}
m
```
然后它将在您的小插图中完美渲染。
现在唯一的麻烦是管理
rds
文件的保存和读取位置,因为 markdown 和 vignettes 可能有棘手的工作目录。
所以最终的
.orig
文件现在是:
---
title: "Example"
author: "BastienFR"
date: "09/05/2022"
output: html_document
---
```{r setup, message=F, warning=FALSE}
library(leaflet)
```
## Intro
A simple and slow example of vignette with a `leaflet`
## The slow part
```{r}
time <- 2
Sys.sleep(time)
message("I've waited this long!")
```
## The leaflet
```{r}
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
```{r, echo=FALSE}
saveRDS(m, "c://temp/temp_leaflet.rds")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=FALSE, warning=FALSE} \n")
cat("library(leaflet) \n")
cat("m <- readRDS('c://temp/temp_leaflet.rds') \n")
cat("```")
```
```{r, eval=T, results="asis", echo=FALSE}
cat("```{r, echo=TRUE} \n")
cat("m \n")
cat("```")
```