0

I am using shiny and want to plot some things using only a certain subset and the whole dataset. Users can choose whether to plot the whole dataset or only a subset using selectInput.

So far I have this:

ui <- fluidPage(
selectInput(inputId = "select", label = "Choose subset of analysis", choices = levels(df$c), selected = "groupA"),
  verbatimTextOutput("summary")
)

server <- ({
datasetInput <- reactive({
    req(input$select)
    a <- subset(df, Haircolor %>% in levels(df$c))
    return(a)
  })

output$summary<- summary(datasetInput)
})

Subsetting the different levels of df$c works, but what can I do if do not want to subset, but include all observations in the analysis?

Thank you so much.

Phil.He
  • 144
  • 9

2 Answers2

1

Try this

ui <- fluidPage(
  selectInput(inputId = "select", label = "Choose subset of analysis", choices = c("All", unique(df$c)), selected = "groupA"),
  uiOutput("summary")
)

server <- ({
  datasetInput <- reactive({
    req(input$select)
    if (input$select=="All") { a <- df
    }else a <- subset(df, Haircolor %in% input$select)
    return(a)
  })
  
  output$summary<- renderUI({summary(datasetInput())})
})
YBS
  • 19,324
  • 2
  • 9
  • 27
  • Hi, sir, could you give me some advice for my question here: https://stackoverflow.com/questions/67103629/how-to-output-two-grid-plotsgrid-draw-togather-and-download-them-in-shinyapp?noredirect=1#comment118613010_67103629 – 花落思量错 Apr 15 '21 at 08:32
1

I think your code has several problems. Since we do not know the original data, I show an example with the iris dataset. It should be easily adaptable to your problem.

library(shiny)
library(dplyr)

myiris <- mutate(iris, Species = as.factor(Species))

shinyApp(
  ui = fluidPage(
      selectInput(inputId = "select",
                  label = "Choose subset of analysis",
                  choices = c("all", levels(myiris$Species)),
                  selected = "all"),
      verbatimTextOutput("summary")
    ),
  
    server = function(input, output) {
    
    datasetInput <- reactive({
    req(input$select)
    filter(myiris, input$select == "all" | Species == input$select)
    # alternatively `subset` works as well:
    # subset(myiris, input$select == "all" | Species == input$select)
    })

    output$summary <- renderText(summary(datasetInput()))
  })

Why does filter(myiris, input$select == "all" | Species == input$select) work?

filter and also subset take an expression as second argument. It is important that

  1. this can be any logical expression. The expression does not necessarily need to refer to a column name.
  2. the expression will be recylced if it does not match the number of rows of the data.frame. Notice that subset and filter have different recycling rules. However, both will recycle an expresison of length == 1 to the number of rows of the data.frame.
  3. The expression may contain boolean operators (&, | etc.)

With this in mind we can construct the expression: input$select == "all" | Species == input$select

Since input$select == "all" is of length == 1 it will be recycled to match the number of elements in Species == input$select which is the number of rows of the data.frame.

Since we use an OR operator |, the expression will be TRUE for every row when all is selected. If all is not selected, the expression Species == input$select will be TRUE for all rows that match the selected input$select.

TimTeaFan
  • 17,549
  • 4
  • 18
  • 39
  • 1
    Thanks so much, this worked! Can you please help me understand the code: How does R know to combine all of the levels when "all" is selected? How does the filter work? – Phil.He Apr 14 '21 at 10:12
  • 1
    @Phil.He: I added an explanation! – TimTeaFan Apr 14 '21 at 10:46