Home > Enterprise >  Pass the choices from selectInput on server side inside group_by function in Shiny app
Pass the choices from selectInput on server side inside group_by function in Shiny app

Time:06-23

I would like to pass the user selection to a group_by function in Shiny apps! The following code does not work, since the input$bearkdown is considered as a character!

How I could fix that?

dat = structure(list(year = c(2000, 2000, 2000, 2000, 2000, 2000, 2000, 
    2000, 2000, 2000, 2000, 2000, 2001, 2001, 2001, 2001, 2001, 2001, 
    2001, 2001), month = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
    1, 2, 3, 4, 5, 6, 7, 8), Quarter = c(1L, 1L, 1L, 2L, 2L, 2L, 
    3L, 3L, 3L, 4L, 4L, 4L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L), project = c("DKF", 
    "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", 
    "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", "DKF", 
    "DKF"), value = c(135.172264747094, 128.304968251943, 124.552331218312, 
    72.9910740042406, 78.3565950925784, 93.7813954394283, 65.906459417623, 
    67.4455518391957, 100.287050913478, 96.6700531783534, 106.789122585464, 
    91.1228414774245, 88.8192557763821, 100.949844928465, 92.3481876481075, 
    82.5695257044659, 78.2314855696782, 58.656187528325, 59.863983014387, 
    91.5297764110538)), row.names = c(NA, 20L), class = "data.frame")




library(shiny)
library(dplyr)

ui <- fluidPage(


    sidebarLayout(
        sidebarPanel(
          selectInput(inputId = 'breakdown',
                      label = 'Breakdown',
                      choices = c("Yearly"="year","Quarterly"="Quarter","Monthly"="month"),selected="Monthly")
        ),

        mainPanel(
           DT::dataTableOutput("datTB")
        )
    )
)


server <- function(input, output) {

    output$datTB <- DT::renderDataTable({
      
      df <- dat%>%
        group_by(input$breakdown)%>%
        mutate(LongTermWI = mean(value,na.rm = T))
    })
}


shinyApp(ui = ui, server = server)

CodePudding user response:

One option would be to use dplyr::across and a second option would be to use the .data pronoun from the rlang package:

Using across:

group_by(across(input$breakdown)))

Using .data:

group_by(.data[[input$breakdown]])

Example code using across:

library(shiny)
library(dplyr)

ui <- fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = 'breakdown',
                  label = 'Breakdown',
                  choices = c("Yearly"="year","Quarterly"="Quarter","Monthly"="month"),selected="Monthly")
    ),
    
    mainPanel(
      DT::dataTableOutput("datTB")
    )
  )
)


server <- function(input, output) {
  
  output$datTB <- DT::renderDataTable({
    
    df <- dat%>%
      group_by(across(input$breakdown)) %>%
      mutate(LongTermWI = mean(value,na.rm = T))
  })
}


shinyApp(ui = ui, server = server)
#> 
#> Listening on http://127.0.0.1:3069

CodePudding user response:

There are a couple of problems with your renderDataTable in addition to the one you identify.

First, your version asigns the mutated table to an object but doesn't return it. Next, you use mutate rather than summairise.

I think this gets you close to what you want:

  output$datTB <- DT::renderDataTable({
    dat%>%
      group_by(!! as.symbol(input$breakdown))%>%
      summarise(LongTermWI = mean(value,na.rm = T))
  })

If you want to group by month or quarter within year, then you have a bit more work to do.

  • Related