Ben G
Ben G

Reputation: 4328

Shiny output not rendering in rmarkdown website

We use rmarkdowns to make websites, at this point with static html. However, we'd like to add shiny content. Yet, the only way I've figured out how to do this is with an iframe (https://datasciencegenie.com/how-to-embed-a-shiny-app-on-website/). When I try to code the shiny app either directly in the rmarkdown chunk or refer to it with shinyAppDir I get this error:

Error: path for html_dependency not provided

I've tried changing the runtime of the individual rmd but that fails with the same error.

Is there a way to imbed shiny apps in rmarkdown website without separately publishing them and referring to them as iframes?

Here's a github repo with a minimally repeatable example. In this case I don't get the same error, but the shiny will not render in the website.

https://github.com/bpbraun/shiny-doesnt-work-in-website

Upvotes: 0

Views: 1055

Answers (1)

Daniel_j_iii
Daniel_j_iii

Reputation: 3242

With Rmarkdown websites, you need 2 files located in the same directory. This is why I love Rmarkdown and Shiny, they allow you so much creative control.

index.Rmd

---
title: ""
runtime: shiny
---


```{r echo = FALSE}

library(shiny)
library(networkD3)
library(dplyr)

shinyApp(
ui <- fluidPage(
    selectInput(inputId = "school",
                label   = "School",
                choices =  c("alpha", "echo")),
    
    sankeyNetworkOutput("diagram")
),

server <- function(input, output) {
    
    dat <- data.frame(schname = c("alpha", "alpha", "alpha", "echo"),
                      next_schname = c("bravo", "charlie", "delta", "foxtrot"),
                      count = c(1, 5, 3, 4))
    
    links <- data.frame(source = dat$schname,
                        target = dat$next_schname,
                        value  = dat$count)
    nodes <- data.frame(name = c(as.character(links$source),
                                 as.character(links$target)) %>%
                            unique)
    
    links$IDsource <- match(links$source, nodes$name) - 1
    links$IDtarget <- match(links$target, nodes$name) - 1
    
    links2 <-reactive({
        links %>%
            filter(source == input$school)
    })
    
    
    output$diagram <- renderSankeyNetwork({
        sankeyNetwork(
            Links = links2(),
            Nodes = nodes,
            Source = "IDsource",
            Target = "IDtarget",
            Value = "value",
            NodeID = "name",
            sinksRight = FALSE
        )
    })
}

)

and "_site.yml", which is the YAML file that helps Rmarkdown render a navbar and gives it a webpage feel and functionality.

_site.yml

name: ""                                # CHANGE HERE 
output_dir: "."
navbar:
  title: ""                             # CHANGE HERE 
  type: inverse
  right:
    - text: "Contact me"
      icon: fa-envelope-o
      href: mailto:[email protected]               # CHANGE HERE 
    - text: "GitHub"
      icon: fa-github
      href: https://github.com/ 
    - text: "Stackoverflow"
      icon: fa-stack-overflow
      href: https://stackoverflow.com/users/
    - text: "Youtube"
      icon: fa-youtube
      href: https://www.youtube.com/channel/
    - text: "Instagram"
      icon: fa-instagram
      href: https://www.instagram.com/
    - text: "Twitter"
      icon: fa-twitter
      href: https://twitter.com/
output: html_document

Notice the Shiny code in the index.Rmd in the R chunk

Shiny code

library(shiny)
library(networkD3)
library(dplyr)

shinyApp(
ui <- fluidPage(
    selectInput(inputId = "school",
                label   = "School",
                choices =  c("alpha", "echo")),
    
    sankeyNetworkOutput("diagram")
),

server <- function(input, output) {
    
    dat <- data.frame(schname = c("alpha", "alpha", "alpha", "echo"),
                      next_schname = c("bravo", "charlie", "delta", "foxtrot"),
                      count = c(1, 5, 3, 4))
    
    links <- data.frame(source = dat$schname,
                        target = dat$next_schname,
                        value  = dat$count)
    nodes <- data.frame(name = c(as.character(links$source),
                                 as.character(links$target)) %>%
                            unique)
    
    links$IDsource <- match(links$source, nodes$name) - 1
    links$IDtarget <- match(links$target, nodes$name) - 1
    
    links2 <-reactive({
        links %>%
            filter(source == input$school)
    })
    
    
    output$diagram <- renderSankeyNetwork({
        sankeyNetwork(
            Links = links2(),
            Nodes = nodes,
            Source = "IDsource",
            Target = "IDtarget",
            Value = "value",
            NodeID = "name",
            sinksRight = FALSE
        )
    })
}

)

This renders me a shiny app of the Rmardown file, creating a webpage/webapp hybrid

enter image description here

Upvotes: 1

Related Questions