Quantcast
Channel: Active questions tagged r - Stack Overflow
Viewing all articles
Browse latest Browse all 201867

modularize Shiny app: CSV and Chart modules

$
0
0

I want to create a modularized Shiny app where one module, dataUpload, is used to import a CSV and another module, chart, is used to

  1. Create dynamic x and y dropdowns based on the column names within the CSV THIS WORKS
  2. Create a plot based on the selected input$xaxis, input$yaxis This produces the error invalid type/length (symbol/0) in vector allocation

I think the issue is with my reactive ggplot in chart.R and I'd love any help - I added all the info here but I also have a github repo if that's easier I think this could be a really great demo into the world of interacting modules so I'd really appreciate any help!!

App.R

library(shiny)
library(shinyjs)
library(tidyverse)

source("global.R")

ui <- 
  tagList(
    navbarPage(
      "TWO MODULES",
      tabPanel(
        title = "Data",
          dataUploadUI("datafile", "Import CSV")
      ),
      tabPanel(
        title = "Charts",
          chartUI("my_chart")
      )
    )
  )

server <- function(input, output, session) {

  datafile <- callModule(dataUpload, "datafile", stringsAsFactors = FALSE)
  output$table <- renderTable({ datafile() })

  # PASS datafile WITHOUT () INTO THE MODULE 
  my_chart <- callModule(chart, "my_chart", datafile = datafile)
  output$plot <- renderPlot({ my_chart() })

}

shinyApp(ui, server)

dataUpload.R

dataUpload <- function(input, output, session, stringsAsFactors) {
  # The selected file, if any
  userFile <- reactive({
    # If no file is selected, don't do anything
    # input$file == ns("file")
    validate(need(input$file, message = FALSE))
    input$file
  })

  # The user's data, parsed into a data frame
  dataframe <- reactive({
    read.csv(userFile()$datapath,
             stringsAsFactors = stringsAsFactors)
  })

  # We can run observers in here if we want to
  observe({
    msg <- sprintf("File %s was uploaded", userFile()$name)
    cat(msg, "\n")
  })

  # Return the reactive that yields the data frame
  return(dataframe)

}

dataUploadUI.R

# The first argument is the id -- the namespace for the module
dataUploadUI <- function(id, label = "CSV file") {
  # Create a namespace function using the provided id
  #ALL UI FUNCTION BODIES MUST BEGIN WITH THIS
  ns <- NS(id)
  # Rather than fluidPage use a taglist
  # If you're just returning a div you can skip the taglist
  tagList(
  sidebarPanel(
    fileInput(ns("file"), label)),

  mainPanel(tableOutput("table"))
  )
}

chart.R

I believe this is the file that needs some minor changing in order to have the plot properly render?

chart <- function(input, output, session, datafile = reactive(NULL)) {

  # SINCE DATAFILE IS A REACTIVE WE ADD THE PRERENTHESIS HERE
  # WHERE/HOW CAN I ACCESS input$xaxis?
  # Do I need to use ns? Can you do that in the server side of a module?
  output$XAXIS <- renderUI(selectInput("xaxis", "X Axis", choices = colnames(datafile())))
  output$YAXIS <- renderUI(selectInput("yaxis", "Y Axis", choices = colnames(datafile())))

  # NOT WORKING
  # Use the selectInput x and y to plot
  p <- reactive({
    req(datafile)
    # WORKS: ggplot(datafile(), aes(x = Sepal_Length, y = Sepal_Width))
    # DOES NOT WORK:
    ggplot(datafile(), aes_(x = as.name(input$xaxis), y = as.name(input$yaxis))) +
      geom_point()
  })

  return(p)
}

chartUI.R

chartUI <- function(id, label = "Create Chart") {

  ns <- NS(id)
  tagList(
    sidebarPanel(
      uiOutput(ns("XAXIS")),
      uiOutput(ns("YAXIS"))
    ),
    mainPanel(plotOutput("plot"))
  )
}

Viewing all articles
Browse latest Browse all 201867

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>