I used an example from the official documentation of selectizeGroup-module I just replaced the data with my own. I use the same data transformations in renderplotly
and renderDataTable
as indicated in the example. I would like to change this so that the code doesn't repeat itself, I tried to use a recative
function but it doesn't work.
My code below:
if (interactive()) {
library(shiny)
library(shinyWidgets)
library(plotly)
library(magrittr)
library(dplyr)
library(DT)
library(lubridate)
library(tidyr)
DATE = rep(seq(as.Date('2018/01/01'), as.Date('2018/03/01'), by = "day"), each = 4, 3)
CATEGORY = rep(c('aa', 'bb'), each = 360)
SOURCE = rep(c("A", "B", "C", "D"), 180)
REVENUE = as.numeric(sample(c(1000:2000), 720, replace = T))
PLAN = 1500
MONTH = months(DATE)
df <- data.frame(DATE, MONTH, CATEGORY, SOURCE, REVENUE, PLAN)
ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
selectizeGroupUI(
id = "my-filters",
params = list(
MONTH = list(inputId = "MONTH", title = "MONTH:"),
CATEGORY = list(inputId = "CATEGORY", title = "CATEGORY:"),
SOURCE = list(inputId = "SOURCE", title = "SOURCE:")
)
), status = "primary"
),
DT::dataTableOutput(outputId = "table"),
plotlyOutput("plot")
)
)
)
server <- function(input, output, session) {
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = df,
vars = c("MONTH", "CATEGORY", "SOURCE")
)
output$table <- DT::renderDataTable({
req(res_mod())
#I'd like to change this part to a shorter unique solution
mod_data <- res_mod()
mod_data%>%
group_by(DATE, MONTH) %>%
summarise(Revenue = sum(REVENUE),
Plan = sum(PLAN)) %>%
ungroup() %>%
mutate(Revenue_cum = cumsum(Revenue),
Plan_cum = cumsum(Plan))
######################################################
})
output$plot <- renderPlotly({
mod_data <- res_mod()
#I'd like to change this part to a shorter unique solution
mod_data%>%
group_by(DATE, MONTH) %>%
summarise(Revenue = sum(REVENUE),
Plan = sum(PLAN)) %>%
ungroup() %>%
mutate(Revenue_cum = cumsum(Revenue),
Plan_cum = cumsum(Plan))%>%
######################################################
plot_ly(
x = ~ DATE,
y = ~ as.numeric(Revenue_cum),
type = 'scatter',
mode = 'lines markers'
) %>%
add_trace(y = ~ as.numeric(Plan_cum),
mode = 'lines markers')
})
}
shinyApp(ui, server)
}
CodePudding user response:
As you already tried or guessed you can move the whole data wrangling part into a reactive
which could then be reused in both renderDataTable
and renderPlotly
:
``` r
library(shiny)
library(shinyWidgets)
library(plotly)
library(dplyr)
library(DT)
server <- function(input, output, session) {
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = df,
vars = c("MONTH", "CATEGORY", "SOURCE")
)
dat <- reactive({
req(res_mod())
res_mod() %>%
group_by(DATE, MONTH) %>%
summarise(Revenue = sum(REVENUE),
Plan = sum(PLAN)) %>%
ungroup() %>%
mutate(Revenue_cum = cumsum(Revenue),
Plan_cum = cumsum(Plan))
})
output$table <- DT::renderDataTable({
dat()
})
output$plot <- renderPlotly({
plot_ly(
dat(),
x = ~ DATE,
y = ~ as.numeric(Revenue_cum),
type = 'scatter',
mode = 'lines markers'
) %>%
add_trace(y = ~ as.numeric(Plan_cum),
mode = 'lines markers')
})
}
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:3563
#> `summarise()` has grouped output by 'DATE'. You can override using the
#> `.groups` argument.