Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

accessing the original file name of r markdown parameters file

I want to provide the user a convenient way to define the input file. For this I am using the parameters functionality in markdown. If I "knit with parameters" I get asked for the input file.

Is there any chance to retrieve the file name? Because I am creating during the markdown some different files and I would use the filename of the input file as a prefix. So far, the file gets uploaded in a temp directory and there, the original file name is lost.

How can I get the file name and location via drop down menu into my markdown document? I don't want the user to write the path and filename manually.

---
title: "Untitled"
date: "11/16/2021"
output: html_document
params:
  date_file:
    label: "date file"
    value: 'dates.tsv'
    input: file
---

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

## R Markdown

Filename: `r params$date_file`
like image 735
drmariod Avatar asked Nov 16 '21 08:11

drmariod


People also ask

How do I view an R Markdown file?

To open a new file, click File > New File > R Markdown in the RStudio menu bar. A window will pop up that helps you build the YAML frontmatter for the . Rmd file. Use the radio buttons to select the specific type of output that you wish to build.

What is the file format for an R Markdown file?

To create an R Markdown report, open a plain text file and save it with the extension . Rmd.

How do I change a file from Markdown to R?

To create a new RMarkdown file ( . Rmd ), select File -> New File -> R Markdown... _ in RStudio , then choose the file type you want to create.


2 Answers

You could have users select a file in the rendered document by embedding a Shiny application. The caveat is that all expressions involving dependencies of the user's selection have to be wrapped inside of reactive(). That is obviously not optimal if you are trying to teach R, but in case it helps or inspires a better answer, here is an example:

## Create a TSV file for testing
cat("x\ty\n1\t2\n3\t4\n", file = "test.tsv")
---
title: "Untitled"
output: html_document
runtime: shiny
---

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

Users can select a file by interacting with an embedded Shiny application.

```{r ui, echo=FALSE}
inputPanel(
  fileInput("file", label = "Select a TSV file:", accept = ".tsv")
)
```

User input is stored in a named list-like object `input`, 
but this object can only be accessed inside of a _reactive context_.

```{r test1, error=TRUE}
input$file$name
## Name of file selected by user ... _not_ an absolute or relative path
fn <- reactive(input$file$name)
fn
## Absolute path of temporary copy of file
dp <- reactive(input$file$datapath)
dp
```

Don't be misled by how `fn` and `dp` are printed. They are not 
strings, but _reactive expressions_. As as a result, they, too, 
must be handled inside of a reactive context.

```{r test2}
class(fn)
reactive(class(fn()))
```

Some more examples:

```{r test3, error=TRUE}
## Define reactive data
dd <- reactive(read.table(file = dp(), sep = "\t", header = TRUE))
## Do stuff with it
reactive(names(dd()))
reactive(nrow(dd()))
## Write object to file in _working directory_
reactive(saveRDS(dd(), file = sub("tsv$", "rds", fn())))
```
like image 169
Mikael Jagan Avatar answered Oct 21 '22 20:10

Mikael Jagan


As alternative to using the Shiny runtime, you can also use Shiny Gadgets in combination with customized Knit button behavior (To my understanding, this is largely what's happening when you use 'Knit with Parameters')

You'll need two things: a function to run the gadget, a function to run when knitting.

The gadget is essentially a Shiny app, but you can use specialized UI elements from miniUI. As a mini-app, there's a lot more you can do, but here's a basic implementation.

library(shiny)
library(miniUI)

get_file_param <- function(){
  
  ui <- miniPage(
    miniContentPanel(
      
      fileInput("dateFile", "Date File")
      
      # ...Other UI elements to collect other parameters... 
      
    ),
    miniTitleBar(
      NULL,
      right = miniButtonBlock(
        miniTitleBarCancelButton(),
        miniTitleBarButton("done", "Done", primary = TRUE))
    )
    
  )
  
  server <- function(input, output, session){
    
    # Handle the Done button being pressed
    observeEvent(input$done, {
      # Return the full file info data.frame. See ?shiny::fileInput
      stopApp(input$dateFile)
    })
    
  }
  
  runGadget(
    app = ui, 
    server = server, 
    viewer = paneViewer() #dialogViewer("Knit with Parameters - Custom UI")
  )
  
}

The knit function will call the gadget and then use its output in a call to rmarkdown::render

knit_with_file <- function(input, ...){
  
  fileInfo <- get_file_param()
  
  rmarkdown::render(
    input,
    params = list(
      date_file = list(name = fileInfo$name, datapath = fileInfo$datapath)
    ),
    envir = globalenv()
  )
  
}

To customize the knit button, you provide a function to the knit field in the document YAML header. The R Markdown cookbook suggest you keep this in a package, but I put both of the above functions in file ("knitFx.R"), which the rmarkdown document will source.

---
title: "Untitled"
date: "11/16/2021"
output: html_document
params:
  date_file: 'dates.tsv'
knit: (function(input, ...) {

    source("knitFx.R")
    
    knit_with_file(input, ...)

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

## R Markdown

**Original Name of Uploaded File**: *`r params$date_file$name`*

**Local Temp File Path**: *`r params$date_file$datapath`*

When the user clicks "Knit", a UI will be displayed to choose the file. Based on implementation above, the name and datapath will then be available to use in the rmarkdown document.

Here's the rendered HTML document: enter image description here

like image 21
Marcus Avatar answered Oct 21 '22 22:10

Marcus