1

My Shiny Application's purpose is to upload a .csv file and plot a ggplot graph with its data. When I upload a .csv file on my Shiny Application, the default variable is "y" for both input variables. However, when I change "y" to "x" on the "X Variable" input, the App works fine. I just have to set "x" for "X Variable" input and "y" for "Y Variable" input as default when I upload the .csv file.

Here follows the app.R code with my comments and Error Message I get when I upload the file.

library(shiny)
library(datasets)
library(ggplot2)

ui <- shinyUI(fluidPage(
  titlePanel("Column Plot"),
  tabsetPanel(
    tabPanel("Upload File",
             titlePanel("Uploading Files"),
             sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'Choose CSV File',
                           accept=c('text/csv', 
                                    'text/comma-separated-values,text/plain', 
                                    '.csv')),

                 tags$br(),
                 checkboxInput('header', 'Header', TRUE),
                 radioButtons('sep', 'Separator',
                              c(Comma=',',
                                Semicolon=';',
                                Tab='\t'),
                              ','),

                 selectInput('xcol', 'X Variable', "", selected = NULL),
                 selectInput('ycol', 'Y Variable', "", selected = NULL)

               ),
               mainPanel(
                 tableOutput('contents'),
                 plotOutput('MyPlot')
               )
             )
    )
  )
)
)


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

  data <- reactive({ 
    req(input$file1)

    inFile <- input$file1 

    df <- read.csv(inFile$datapath, header = input$header, sep = input$sep)

    ## Update inputs
    ## I've already tried to change the selected = names(df) to selected = NULL on this part of the server code, but it didn't work.

    updateSelectInput(session, inputId = 'xcol', label = 'X Variable',
                      choices = names(df), selected = names(df))
    updateSelectInput(session, inputId = 'ycol', label = 'Y Variable',
                      choices = names(df), selected = names(df)[2])

    return(df)
  })

  output$contents <- renderTable({
    data()
  })

  output$MyPlot <- renderPlot({

    xy <- data()[, c(input$xcol, input$ycol)]
    ggplot(data = xy, aes(x, y)) +
      geom_line() +
      geom_point()

  })
})

shinyApp(ui, server)

The error message I get is:

"Error: object 'x' not found".

OTStats
  • 1,820
  • 1
  • 13
  • 22
  • Welcome to SO! My guess is that it's the `ggplot()` call, I bet there are not actually columns in `xy` with the names `x` and `y`. Maybe you could use `aes(as.name(input$xcol), as.name(input$ycol))` instead? Hard to say for sure without a full [reprex](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)... – Nate Nov 03 '19 at 23:09
  • Thank you! I've tried using `aes(as.name(input$xcol), as.name(input$ycol))` and it didn't work. I've also tried changing the call `xy` and also failed :( – Fernando Coelho Nov 04 '19 at 02:07
  • In aes() you have to match the names of the aesthetics with the names of the columns, try `aes_string(x = input$xcol, y = input$ycol`) – Simon Woodward Nov 04 '19 at 02:10

1 Answers1

1

and welcome to SO

Your issue here is that you update the selectInput() at the wrong time: the update is done once the server has finished computing, so here once the data() is done running.

So to be clear, you update your input after trying to select from it.

Other thing is that you need to sym() & !! the input$ to make it work with ggplot() (see : https://github.com/ColinFay/tidytuesday201942/blob/master/R/mod_dataviz.R#L184 for example)

Here is a working version:

library(shiny)
library(datasets)
library(ggplot2)
library(rlang)

ui <- shinyUI(fluidPage(
  titlePanel("Column Plot"),
  tabsetPanel(
    tabPanel("Upload File",
             titlePanel("Uploading Files"),
             sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'Choose CSV File',
                           accept=c('text/csv', 
                                    'text/comma-separated-values,text/plain', 
                                    '.csv')),

                 tags$br(),
                 checkboxInput('header', 'Header', TRUE),
                 radioButtons('sep', 'Separator',
                              c(Comma=',',
                                Semicolon=';',
                                Tab='\t'),
                              ','),

                 selectInput('xcol', 'X Variable', "", selected = NULL),
                 selectInput('ycol', 'Y Variable', "", selected = NULL)

               ),
               mainPanel(
                 tableOutput('contents'),
                 plotOutput('MyPlot')
               )
             )
    )
  )
)
)


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

  r <- reactiveValues(
    df = NULL
  )

  observe({
    req(input$file1$datapath)
    # req(input$xcol)
    # req(input$ycol)
    r$df <- read.csv(
      input$file1$datapath, 
      header = input$header, 
      sep = input$sep
    )
  })


  observeEvent( r$df   , {
    updateSelectInput(
      session, 
      inputId = 'xcol', 
      label = 'X Variable',
      choices = names(r$df), 
      selected = names(r$df)[1]
    )
    updateSelectInput(
      session, 
      inputId = 'ycol', 
      label = 'Y Variable',
      choices = names(r$df),
      selected = names(r$df)[2]
    )
  }, ignoreInit = TRUE)


  output$contents <- renderTable({
    req(r$df)
    head(r$df)
  })

  output$MyPlot <- renderPlot({
    req(r$df)
    req(input$xcol)
    req(input$ycol)
    ggplot(
      data = r$df, 
      aes(!!sym(input$xcol), !!sym(input$ycol))
    ) +
      geom_line() +
      geom_point()

  })
})

shinyApp(ui, server)

enter image description here

Colin FAY
  • 4,849
  • 1
  • 12
  • 29