Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Input Selector Based on Uploaded Data

Thanks in advance for your help. I understand how to manipulate dynamic inputs based off of other inputs for pre-defined datasets. i.e. Load a car dataset. User selects Radio button to say they only want to look at blue cars. This changes the options in some Input Selector on the UI.

However, if I want to allow a user to upload a csv file, how do I dynamically update all of the relevant widgets. i.e. User uploads their data, an Input Selector displays all variables in the dataset for plots and regressions.

The italicized part is my trouble.

ui.r

library(shiny)

# Define UI for application that draws a histogram
shinyUI(fluidPage(

  titlePanel("My R Shiny App"),

  sidebarPanel(
    fileInput('file', 'Choose file to upload.'),
    #Select Box: y
    selectInput("y_input", label = h5("Select Time Series/Response Variable"),
                choices = names(myData),
                selected = NULL)

  )
) 
)

server.r

library(shiny)

#Run once when app is launched
#Load data

shinyServer(function(input, output) {

  #Run once each time a user visits the app
  #Put code to build a distinct set of reactive objects for user


  output$Variable_Selector <- renderUI({
    if(is.null(input$file))
      return(NULL)
    inFile <- input$file
    myData <- read.csv(inFile$datapath)
    if (is.null(myData))
      return(NULL)
  })
})

global.r

myData = NULL

Thanks!

like image 403
sbanders Avatar asked Feb 12 '23 02:02

sbanders


1 Answers

Here's one solution using the functions observe and updateSelectInput - with some other minor modifications to your code. To demonstrate I made the following two csv files with different column names:

Df1 <- data.frame(
  x=1:5,
  y=2*(1:5),
  z=3*(1:5))
##
Df2 <- data.frame(
  a=6:10,
  b=2*(6:10),
  c=3*(6:10),
  d=letters[1:5],
  stringsAsFactors=F)
##
write.csv(Df1,file="~/tempfiles/Df1.csv",row.names=F)
##
write.csv(Df2,file="~/tempfiles/Df2.csv",row.names=F)

ui.R:

library(shiny)

shinyUI(fluidPage(

  titlePanel("My R Shiny App"),

  sidebarPanel(

    fileInput(
      'file', 
      'Choose file to upload.'
    ),

    selectInput(
      "y_input", 
      label = h5("Select Time Series/Response Variable"),
      ""
    )

  )

))

server.R:

library(shiny)

shinyServer(function(input, output, session) {

  inFile <- reactive({
    if (is.null(input$file)) {
      return(NULL)
    } else {
      input$file
    }
  })

  myData <- reactive({
    if (is.null(inFile())) {
      return(NULL)
    } else {
      read.csv(inFile()$datapath)
    }
  })

  observe({
    updateSelectInput(
      session,
      "y_input",
      choices=names(myData()))

  })

})

global.R:

myData <- NULL

And here are a couple of screenshots showing how the UI changes based on the uploaded file:

Uploading <code>Df1.csv</code>

Uploading <code>Df2.csv</code>

like image 159
nrussell Avatar answered Feb 24 '23 00:02

nrussell