0
votes

I am trying to build an R Shiny app that will display custom scatterplots. I let the user choose which variables from the dataset to place on the x and y axis with select boxes. Furthermore (this is where the trouble starts) I would like the ability to limit the range of values from each variable plotted in the graph by means of a custom slider for each selected variable. So, basically the user specifies a min and max value for each variable. I accomplish this with the uiOutput and renderUi functions. So far, the sliders appear to be working just fine.

Now, the problem: Once I subset the data based on the input values and try to plot the result, I get the error:

"incorrect length(32), expecting 29".

What could be going wrong here?

The dataset I intend to run this with is fairly large, however for the sample code I used the mtcars dataset (same problem).

library(shiny);library(ggplot2);library(dplyr)

#load data
data(mtcars)

ui <- shinyUI(fluidPage(

   # Application title
   titlePanel("Mtcars Data"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
         selectInput(inputId = "x",
                     label = "x variable:",
                     choices = names(mtcars),
                     selected = names(mtcars)[1]),
         uiOutput("xslider"),
         selectInput(inputId = "y",
                     label = "y variable:",
                     choices = names(mtcars),
                     selected = names(mtcars)[4]),
         uiOutput("yslider")
      ),

      mainPanel(
         plotOutput("scatterPlot")
      )
   )
))

# Define server logic required to draw scatterplot
server <- shinyServer(function(input, output) {
   #Get summary stats for x and y variables,
   #this is used to set the parameters for the sliders in renderUI
   summary.x <- reactive({
           summary(mtcars[,input$x])
   })
   summary.y <- reactive({
           summary(mtcars[,input$y])
   })

   output$xslider <- renderUI({
           sliderInput(inputId = "xlim",
                       label = "limit x axis:",
                       min = summary.x()[1],
                       max = summary.x()[6],
                       value = c(summary.x()[1], summary.x()[6]),
                       step = .01)
   })

   output$yslider <- renderUI({
           sliderInput(inputId = "ylim",
                       label = "limit y axis:",
                       min = summary.y()[1],
                       max = summary.y()[6],
                       value = c(summary.y()[1], summary.y()[6]),
                       step = .01)
   })

   output$scatterPlot <- renderPlot({
           #Now subset data so values of x variable 
           #are within the range specified by input$xlim
           #and values of y are within range of input$ylim
           subdata <- filter(mtcars, mtcars[,input$x] < input$xlim[2],
                          mtcars[,input$x] > input$xlim[1])
           subdata <- filter(subdata, mtcars[,input$y] < input$ylim[2],
                             mtcars[,input$y] > input$ylim[1])
           #display the scatterplot        
           ggplot(subdata, aes_string(input$x,input$y)) + geom_point()

   })
})

# Run the application 
shinyApp(ui = ui, server = server)
1

1 Answers

0
votes

Your second subdata <- refers to different length structures in subdata and in mtcars. Make it one expresssion:

subdata <- filter(mtcars,
                  mtcars[,input$x] < input$xlim[2],
                  mtcars[,input$x] > input$xlim[1],
                  mtcars[,input$y] < input$ylim[2],
                  mtcars[,input$y] > input$ylim[1])