3
votes

I am trying to renderplot using ggplot2 instead of the base R's plot function.

However I've encountered some problems when using reactive dataset in ggplot2.

Below is the code that works with base R's plot:

library(shiny)
library(ggplot2)

# Define UI for application that draws a histogram
ui <- fluidPage(

  # Application title
  titlePanel("Javier Test"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(

      # Input: Select a file ----
      fileInput('file1', 'Choose CSV File',
                accept=c('text/csv', 
                         'text/comma-separated-values,text/plain', 
                         '.csv')),

      # Horizontal line ----
      tags$hr(),

      checkboxInput('header', 'Header', TRUE),
      radioButtons('sep', 'Separator',
                   c(Comma=',',
                     Semicolon=';',
                     Tab='\t'),
                   ','),
      radioButtons('quote', 'Quote',
                   c(None='',
                     'Double Quote'='"',
                     'Single Quote'="'"),
                   '"'),

      #implementing dropdown column 
      selectInput('xcol', 'X Variable', ""),
      selectInput('ycol', 'Y Variable', "", selected = "")),

    # Show a plot of the generated distribution
    mainPanel(
      # Output: Data file ----
      plotOutput('MyPlot')
    )
  )
)

# Define server logic required to draw a histogram
server <- shinyServer(function(input, output, session) {
  # added "session" because updateSelectInput requires it


  data <- reactive({ 
    req(input$file1) ## ?req #  require that the input is available

    inFile <- input$file1 

    # tested with a following dataset: write.csv(mtcars, "mtcars.csv")
    # and                              write.csv(iris, "iris.csv")
    df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
                   quote = input$quote)


    # Update inputs (you could create an observer with both updateSel...)
    # You can also constraint your choices. If you wanted select only numeric
    # variables you could set "choices = sapply(df, is.numeric)"
    # It depends on what do you want to do later on.

    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$MyPlot <- renderPlot({
    x <- data()[,c(input$xcol, input$ycol)]
    plot(x)
  })
})

shinyApp(ui, server)

This is the part where I'm trying to change to ggplot2 render plot instead:

  output$MyPlot <- renderPlot({
    ggplot(data, aes(x=input$xcol, y=input$ycol)) + geom_point()
  })

Error: ggplot2 doesn't know how to deal with data of class reactiveExpr/reactive

Any idea how do I use a reactive data set for ggplot2?

Thank you so much!

Update

Here's the code! I've figured it out. Not very nice, is there a better way to represent it?

  output$MyPlot <- renderPlot({
    x <- data()[,c(input$xcol, input$ycol)]
    ggplot(x, aes(x=x[,1], y=x[,2])) + geom_point()
  })
2
Hi @SalmanLashkarara, Yes I can load data into df. If you run the first code with base R plot, the app works. Just trying to use ggplot2 instead! - Javier
Yes that is correct. The code works like I mentioned. It is reproducible if you plug it into R and use any .csv file. Just unsure about the parameters I should be using for ggplot2 - Javier
@SalmanLashkarara I've added the correct code! Do check it out, hopefully it can be improved! It looks bad - Javier
i got the answer - Jimmy

2 Answers

2
votes

Instead of sub-setting the data multiple times in the renderPlot function, you could instead of using aes function you would use aes_string function from ggplot package. So the one liner solution will be:

output$MyPlot <- renderPlot({
ggplot(data = data(), aes_string(x = input$xcol, y = input$ycol)) + geom_point()
})
1
votes

It works well now:

  output$MyPlot <- renderPlot({
       x <- data()[,c(input$xcol, input$ycol)]

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

      })