Search code examples
rshinyrstudior-markdownshiny-server

shinyApp not rendering Rmarkdown file as RStudio


I'm struggling to understand why shinyApp does not render a Rmarkdown file as done by RStudio, even when Rmarkdown is explicitly defined in app.R.

The Rmd file below has been written in RStudio, and when the "Run document" button is clicked an HTML document is generated with a friendly web of the application, the sidebar, pages, and plots. However, if this is hosted together with an app.R file in shiny-server, some errors are returned and the file rendered lacks of the structure of the original document (eg. sidebar, pages, etc..). This can be generated also by running Rscript --vanilla app.R and going to localhost:port.

Here are the files I'm using:

example.Rmd

---
title: "Example file"
runtime: shiny
theme: simplex
vertical_layout: fill
output:
  flexdashboard::flex_dashboard:
    orientation: rows
---

```{r setup, include=FALSE}
library(shiny)
library(tidyverse)
library(plotly)
```

Sidebar {.sidebar}
======================================================================

**Options**

```{r opt_general, echo = FALSE}
selectInput("opt_cyl",
            label = "Select cyl",
            choices = mtcars %>% .$cyl %>% unique %>% sort,
            multiple = TRUE,
            selected = "4")

sliderInput("opt_qsec", label = "Qsec", min = mtcars$qsec %>% min, max = mtcars$qsec %>% max, value = mtcars$qsec %>% max, step = 0.01)
```

**More options**

```{r opt_dist, echo = FALSE}
checkboxInput("opt_log", label = "Log scale (qsec)", value = FALSE)
```

Explore
======================================================================

```{r global, echo=FALSE}
 mtcars$cyl <- as.character(mtcars$cyl)
 ```

 ```{r reactive_global, echo=FALSE}
rcars <- reactive({
   C <- dplyr::filter(mtcars, cyl==input$opt_cyl, qsec <= input$opt_qsec)
  return(C)
})
 ```

Row
------------------------

### One nice plot

```{r plot1a, echo = FALSE}
    uiOutput("r1a")

output$r1a <- renderUI({
  plotlyOutput("p1a")
})

output$p1a <- renderPlotly({
  P <- mtcars %>% ggplot() + geom_point(aes(x=cyl, y=qsec))
  ggplotly(P)
})
```

### Another nice plot

```{r plot1b, echo = FALSE}
uiOutput("r1b")

output$r1b <- renderUI({
  plotlyOutput("p1b")
})

output$p1b <- renderPlotly({
  P <- rcars() %>% ggplot() + geom_point(aes(x=cyl, y=qsec))
  ggplotly(P)
})
```

Row
------------------------

### Second row plot

```{r plot2, echo = FALSE}
uiOutput("r2")

output$r2 <- renderUI({
  plotlyOutput("p2")
})

output$p2 <- renderPlotly({
  C <- rcars()
  if (input$opt_log) C$qsec <- log(C$qsec)
  P <- C %>% ggplot() + geom_point(aes(x=mpg, y=qsec))
  ggplotly(P)
})
```

About
======================================================================

Some nice README

The corresponding app.R file is:

library(shiny)
library(knitr)

ui <- shinyUI(
  fluidPage(
    uiOutput('markdown')
  )
)

server <-function (input, output) {
  output$markdown <- renderUI({
    HTML(markdown::markdownToHTML(knit('example.Rmd', quiet = TRUE)))
  })
}

shinyApp(ui, server)

The error returned in the log file is:

Listening on http://127.0.0.1:44229 Warning: Error in : Result must have length 32, not 0 125: Warning: Error in : Result must have length 32, not 0 100:

Does someone can give me a pointer on why this is happening? Thank you


Solution

  • You can try to mimic the function rmarkdown::run by changing the app.R as below.

    library(shiny)
    
    file <- 'example.Rmd'
    dir <- dirname(file)
    
    ui <- rmarkdown:::rmarkdown_shiny_ui(dir, file)
    render_args <- list()
    render_args$envir <- parent.frame()
    server <- rmarkdown:::rmarkdown_shiny_server(dir, file, 'UTF-8', T, render_args)
    
    shinyApp(ui, server)