I have this dataframe:
df <-
data.frame(
w = seq(1, 5),
m = seq(6, 10),
y = seq(11, 15)
)
And this switch
grp <-
switch ("W",
"W" = c("w", "m"),
"M" = c("m", "y"),
"Y" = c("y", "w")
)
According variable from grp dataframe is grouped by two columns and summarized in by following function.
summariser <-
function(.data) {
return(
.data %>%
group_by(across(all_of(grp))) %>%
summarize(n = n()) %>%
ungroup() %>%
group_by(across(grp[1])) %>%
mutate(mean = mean(n)) %>%
ungroup()
)
}
According value I insert to switch it returns two columns that will be grouped and summarized. I can simply do it this way.
df %>%
summariser()
I’d like to achieve the same thing in Rshiny, value will be selected by selectInput according current value. I tried several modifications but, my function doesn’t work. Also it is very important for me to have summariser function in external file because it is used by several projects and also it is often modified. I also prefer to have grp switch in external file because it is often modified too.
ui <- fluidPage(
titlePanel("Simple Shiny App"),
sidebarLayout(
selectInput("type",
"Choose an option",
choices = c("W", "M", "Y")),
mainPanel(
tableOutput("dataTable")
)
)
)
server <- function(input, output) {
output$dataTable <- renderTable({
df
})
}
shinyApp(ui = ui, server = server)
>Solution :
Thoughts:
- Your
summariserfunction is breaking scope by assuming thatgrpis found in the calling environment or search path; this is bad practice for several reasons, I suggest you make it an explicit argument to the function. - We need to add the
grpswitch functionality to a new reactive.
library(dplyr)
summariser <-
function(.data, grp) {
.data %>%
summarize(n = n(), .by = all_of(grp)) %>%
mutate(mean = mean(n), .by = all_of(grp[1]))
}
library(shiny)
ui <- fluidPage(
titlePanel("Simple Shiny App"),
sidebarLayout(
selectInput("type",
"Choose an option",
choices = c("W", "M", "Y")),
mainPanel(
tableOutput("dataTable")
)
)
)
server <- function(input, output) {
groups <- reactive({
req(input$type)
switch(input$type, "W" = c("w", "m"), "M" = c("m", "y"), "Y" = c("y", "w"))
})
output$dataTable <- renderTable({
req(groups())
summariser(df, groups())
})
}
shinyApp(ui = ui, server = server)