Reputation: 5206
I want to be able to pass a reactive data.table
to my Rmarkdown document that will sort the table and print the top, say 5, sorted entries.
I keep running into "Error : x must be a data.frame or data.table" at setorderv
. I suspect the reactive is upsetting the is.data.table
checks.
How do I simply pass a copy of the data to the Rmd document? And remove the reactivity wrapper?
Here is a simplified example cobbled from reactivity and downloadHandler stock examples. I took at look at this on SO which suggested using observe but I am not sure how to implement this. Thanks I appreciate some help on this.
RMARKDOWN - SOtestreport.Rmd
---
title: "Top in Segment Report"
output: html_document
params:
n: 5
dt: NA
top.field: NA
---
```{r setup, echo = FALSE}
library(data.table)
library(knitr) # for kable
```
Data report as at: `r format(Sys.time(), "%a %b %d %Y %X")`
```{r, echo = FALSE}
table.str <- paste0("Showing Top ", params$n ," tables for these fields: ",
params$top.field)
# is this the best way of having dynamic labels?
```
`r table.str`
```{r, echo = FALSE}
# tried this
# test.dt <- copy(dt)
# normally a function GenerateTopTable with limit sort field etc.
setorderv(dt, params$top.field, -1) # -1 is descending. THIS IS WHERE IT CRASHES
out <- dt[1:params$n,]
```
```{r toptable, echo = FALSE}
kable(out, digits = 3)
```
app.R
# SO test report
# mini example based on https://shiny.rstudio.com/gallery/reactivity.html
library(shiny)
library(datasets)
server <- function(input, output) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars)
})
output$caption <- renderText({
input$caption
})
output$summary <- renderPrint({
dataset <- datasetInput()
summary(dataset)
})
output$view <- renderTable({
head(datasetInput(), n = input$obs)
})
# PROBLEM BIT WHERE I AM ADDING ON GALLERY EXAMPLE
# handler from https://stackoverflow.com/questions/37347463/generate-report-with-shiny-app-and
output$topreport <- downloadHandler(
filename = "topreport.html",
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path(tempdir(), "SOtestreport.Rmd")
file.copy("SOtestreport.Rmd", tempReport, overwrite = TRUE)
# Set up parameters to pass to Rmd document
# TRIED THIS TOO
# my.dt <- as.data.table(datasetInput())
my.dt <- datasetInput()
my.params <- list(n = input$obs,
dt = my.dt,
top.field = names(my.dt)[1])
rmarkdown::render(tempReport, output_file = file,
params = my.params,
envir = new.env(parent = globalenv())
)
}
)
Upvotes: 3
Views: 5307
Reputation: 5206
I fixed this example - dt
in Rmd was not prefaced with params$
!
setorderv(params$dt, params$top.field, -1) # -1 is descending
out <- params$dt[1:params$n,]
I still looking for answers on whether this is the right approach above (in passing parameters in Shiny to RMarkdown apps).
I also want to point out to others that these answers were also useful:
use of ReactiveValues by @NicE https://stackoverflow.com/a/32295811/4606130
What's the difference between Reactive Value and Reactive Expression?
I also made use of copying the dataset to break the reactivity, i.e.
my.dt <- copy(params$dt)
#do this before passing into render params list
Another tip in RStudio is not to use the internal Viewer Pane but to run externally in the browser. This fixed where the temporary file was saved issues. You can choose to always Run Externally under Run App in image below:
Upvotes: 5