简体   繁体   中英

R Shiny Help: Bar plot with 2+ filters

I've created a basic Shiny app that plots a numeric output to a bar plot using different filters; a filter that allows the user to select a "name" and a "type" associated with that name. The "name" filter is multi-select enabled, the "type" filter is not. Everything is working great, except I realize that the way I've structured my code does not allow me to plot all of the different combinations I'd like to.

#----df creation
name<-c("a","a","b","b","c","c")
type<-c("red","blue","blue","green","green","orange")
number<-c(30,20,42,16,23,62)
cbind(name,type,number)->df
as.data.frame(df)->df
unique(df$name)->name
unique(df$type)->type

#----shiny app
library(shiny)
library(dplyr)
library(ggplot2)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(
        inputId = "name",
        label = "Name Selection",
        choices = name,
        selected = "a",
        multiple = TRUE
      ),
      radioButtons(
        inputId = "type",
        label = "Type Select",
        choices = type,
        selected = "red"
      )
    ),
    mainPanel(
      plotOutput(
        outputId = "graph"
      )
    )
  )

)

server <- function(input, output) {

  output$graph <- renderPlot({

    filtered <- 
      df %>%
      filter(name == input$name) %>%
      filter(type == input$type)

    ggplot(filtered,aes(x=name,y=number)) + geom_bar(stat = "identity")

  })


 }

 shinyApp(ui = ui, server = server)

The above code allows me to select multiple names, and different types, however it appears as it it's order dependant. For example, try selecting "a" then "b", and then "blue" as the type. No graph. Now try the same in reverse: "b" then "a", "blue" as the type. The desired output is produced. Any idea what's going on here? Thanks all.

Since you are using a multiple select, you need to change your filter to use the %in% operator:

Checking for equality between two vectors results in pair-wise comparisons, recycling the shorter vector, if necessary. Notice the warning below that the shorter vector doesn't divide nicely into the larger:

a <- c(2,1)
b <- c(1,2,3)

a == b # [1] FALSE FALSE FALSE
       # Warning message:
       # In a == b : longer object length is not a multiple of shorter 
       # object length

a %in% b # [1] TRUE TRUE

Also, your assignment-to-the-right ( -> ) in lines 5-8, while not wrong, is generally frowned upon, although I'm sure people will defend its use.

I believe this does what you're looking for:

#----df creation
name<-c("a","a","b","b","c","c")
type<-c("red","blue","blue","green","green","orange")
number<-c(30,20,42,16,23,62)
cbind(name,type,number)->df
as.data.frame(df)->df
unique(df$name)->name
unique(df$type)->type

#----shiny app
library(shiny)
library(dplyr)
library(ggplot2)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(
        inputId = "name",
        label = "Name Selection",
        choices = name,
        selected = "a",
        multiple = TRUE
      ),
      radioButtons(
        inputId = "type",
        label = "Type Select",
        choices = type,
        selected = "red"
      )
    ),
    mainPanel(
      plotOutput(
        outputId = "graph"
      )
    )
  )

)

server <- function(input, output) {

  output$graph <- renderPlot({

    filtered <- 
      df %>%
      filter(name %in% input$name) %>%
      filter(type == input$type)

    ggplot(filtered,aes(x=name,y=number)) + geom_bar(stat = "identity")

  })


}

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM