3

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()
  })
4
  • 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! Commented Sep 20, 2018 at 6:58
  • 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 Commented Sep 20, 2018 at 7:01
  • 1
    @SalmanLashkarara I've added the correct code! Do check it out, hopefully it can be improved! It looks bad Commented Sep 20, 2018 at 7:23
  • i got the answer Commented Sep 20, 2018 at 8:26

2 Answers 2

2

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()
})
Sign up to request clarification or add additional context in comments.

2 Comments

wow this is great! thanks so much for sharing your knowledge!
Happy to help :)
1

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()

      })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.