简体   繁体   中英

Knit with parameters in R Markdown by selecting shapefile (.shp) as file input

I am trying to render an R Markdown script to a PDF using Knit with parameters. I want other people to be able to render the report using a UI generated by the YAML header. I would like to use a shiny control ( file ) as as a parameter input instead of the generic text one (ie the UI opens up a window in which the user can select the file from a File Explorer).

Minimal reproducible example:

I first create a copy of the sf package's nc.shp so that I can easily find it when testing the UI:

library(sf)
sf_nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
sf::st_write(sf_nc, 'C:/Temp/nc_temp.shp')

Here is the R Markdown (.rdm) file

---
title: "Params_Test"
output: pdf_document

params:
  shp_program: 
    input: file
    label: 'NC Shapefile'
    value: 'C:/Temp/nc_temp.shp'
    multiple: FALSE
    buttonLabel: 'browse shapefiles'
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```


```{r, eval = TRUE, include = TRUE}

library(sf)
library(ggplot2)

sf_nc_temp <- sf::st_read(params$shp_program)

plot <- ggplot2::ggplot(sf_nc_temp) +
  geom_sf(aes(color = NAME)) +
  geom_sf_text(aes(label = NAME)) 
plot

```

The tool runs fine when I just Knit using the default (Knit drop down icon > Knit with parameters > Knit). This uses the string to the shapefile path as text. 在此处输入图片说明

However I get the following error message when I try to select the shapefile from the UI: Line 20 Error: Cannot open 'C:\\Users\\username\\AppData\\Local\\Temp\\1\\Rtmp8gVT2L\\file2784148636a\\0.shp"; The source could be corrupt or not supported. See st_drivers() for a list of supported formats.

在此处输入图片说明

I tried replacing the chunk based on: How do I access the data from a file passed as parameters in a RMarkdown document?

library(sf)
library(ggplot2)

cat(params$shp_program)
c <- sf::st_read(params$shp_program)
c

plot <- ggplot2::ggplot(c) +
  geom_sf(aes(color = NAME)) +
  geom_sf_text(aes(label = NAME)) 
plot

As @lbusett had mentioned in their comment, you're selecting only one part of the shapefile. The *.shp file is only a component of the shapefile, which is comprised of several files ( .shp , .shx , .dbf , etc.).

One way to work around this is to adjust your parameters so that multiple = TRUE , which will allow you to select all of the files associated with a particular shapefile (ie place.shp , place.shx , place.df , etc.)

---
title: "Params_Test"
output: pdf_document

params:
  shp_program: 
    input: file
    label: 'NC Shapefile'
    value: 'C:/Temp/nc_temp.shp'
    multiple: TRUE
    buttonLabel: 'browse shapefiles'
---

Later in your code, you will need to identify the respective file paths of each file and copy them to your working directory. This will ensure that they all share the same name and location.

Set the working directory and then use str_which() to identify the appropriate index of params$shp_program for each respective filetype, as follows:

```
{r, eval = TRUE, include = TRUE}

library(sf)
library(ggplot2)

setwd("C:/temp")

shp_index<- str_which(params$shp_program, ".shp")
shx_index <- str_which(params$shapefile, ".shx")
dbf_index <- str_which(params$shapefile, ".dbf")
prj_index <- str_which(params$shapefile, ".prj")    

file.copy(params$shapefile[shp_index], "temp_shape.shp")
file.copy(params$shapefile[shx_index], "temp_shape.shx")
file.copy(params$shapefile[dbf_index], "temp_shape.dbf")
file.copy(params$shapefile[prj_index], "temp_shape.prj")

sf_nc_temp <- sf::st_read("temp_shape.shp")

plot <- ggplot2::ggplot(sf_nc_temp) +
  geom_sf(aes(color = NAME)) +
  geom_sf_text(aes(label = NAME)) 
plot
```

When using parameters to load files through Shiny, R copies the selected files over to a temporary directory and renames them. Thus, if you selected "place.shp" , "place.shx" , and "place.dbf" they would be copied to separate subfolders in your local temp directory as "0.shp" , "1.shx" , and "2.dbf" . The original file path is lost in this process, so it prevents people after you from seeing which files you selected. If your workflow requires peer review, this can be a deal breaker.

In addition, you may encounter file size limitations that require additional coding to increase beyond the 5mb default. Specifically, you'll need to drop the following code at the top to increase the file size limit to 30 MB:

options(shiny.maxRequestSize = 30*1024^2)

As a result of these issues, I find it easierto use the file.choose() function instead of parameters. Doing so will allow you to select just the .shp file while preserving the original filepath, so that R will know where the rest of the shapefile's component files are located.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM