Confused with Shiny Modules and renderUI - r

I am trying to plot a dygraph in my Shiny App but I can't seem to get the output working. I would like to do it using modules.
Comprar = purchase and Alquiler = Rental.
I randomly create some price data and some dates
Generate some summary statistics for the average price and number of observations in the data comprar_stats and alquiler_stats
I store some metrics in a list that I would like to call throughout the App.
Then in ui_dygraph I try to generate the dropdown module for each option on my data comprar_main, alquiler_main and price_to_rent. I am able to generate a dropdown but not an output of the dygraph...
How I can I obtain the output of the dygraph? - This code is a mix of some Shiny code I took from the Appsilon "Enterprice Shiny" App - I would like to try and modularise my Apps.
Expected Output: Obtain the dygraph outputs depending on the dropdown.
Shiny App:
library(bslib)
library(shiny)
library(tidyverse)
library(dygraphs)
library(zoo)
################################################################################
startDate <- as.Date("2023-01-01")
endDate <- as.Date("2023-06-01")
dates <- rep(dates, each = 10)
propertyPrices <- round(rnorm(length(dates), mean = 100000, sd = 20000), 2)
comprar_main <- data.frame(collectionDate = dates, price = propertyPrices)
propertyRentals <- round(rnorm(length(dates), mean = 1000, sd = 200), 2)
alquiler_main <- data.frame(collectionDate = dates, price = propertyRentals)
################################################################################
################################################################################
comprar_stats = comprar_main %>%
filter(collectionDate > as.Date("2022-09-27")) %>% # accidently have rental data before this date
filter(price < 1000000) %>%
filter(price > 100000) %>%
group_by(collectionDate) %>%
summarise(
mean_price = mean(price),
mean_price = round(mean_price, 0),
propertiesListed = n()
) %>%
ungroup() %>%
mutate(
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0)
) %>%
add_column(
type = "comprar_main"
)
alquiler_stats = alquiler_main %>%
filter(collectionDate > as.Date("2022-09-27")) %>%
filter(price < 2500) %>%
filter(price > 200) %>%
group_by(collectionDate) %>%
summarise(
mean_price = mean(price),
mean_price = round(mean_price, 0),
propertiesListed = n()
) %>%
ungroup() %>%
mutate(
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0)
) %>%
add_column(
type = "alquiler_main"
)
stats = bind_rows(comprar_stats, alquiler_stats)
stats_price_to_rent = full_join(comprar_stats, alquiler_stats, by = "collectionDate") %>%
mutate(
mean_price = mean_price.x / (mean_price.y * 12), # annualise the rent
mean_price = round(mean_price),
rolling_average = rollapply(mean_price, fill=NA, width = 14, mean, align = "right"),
rolling_average = round(rolling_average, 0),
propertiesListed = propertiesListed.y / propertiesListed.x,
propertiesListed = round(propertiesListed, 2)
) %>%
add_column(type = "price_to_rent_main") %>%
select(c(collectionDate, mean_price, propertiesListed, rolling_average, type))
################################################################################
metrics_list <- list(
comprar_main = list(
id = "comprar_main",
title = "Comprar (All Spain)",
currency = "€",
category = "comprar",
legend = "Purchase Spain",
legend2 = "# of properties"
),
alquiler_main = list(
id = "alquiler_main",
title = "Alquiler (All Spain)",
currency = "€",
category = "alquiler",
legend = "Rental Spain",
legend2 = "# of properties"
),
price_to_rent_main = list(
id = "price_to_rent_main",
title = "Price to Rent (All Spain)",
currency = "€",
category = "misc",
legend = "Price To Rent",
legend2 = "# of rentals / # of purchases",
caption = "Some info here"
)
)
################################################################################
################################################################################
########################### User interfaces ####################################
ui_dygraph <- function(id) {
ns <- NS(id)
# Add all available metrics to dygraph chart
choices <- names(metrics_list)
tagList(
tags$div(
class = "panel-header",
selectInput(
ns("metric"), "Select metric for the time chart",
choices,
width = NULL,
selectize = TRUE,
selected = choices[[1]]
)
),
tags$div(
class = "chart-time-container",
dygraphOutput(ns("dygraph"), height = "240px")
)
)
}
################################################################################
ui <- navbarPage(
fluidPage(
theme = bs_theme(bootswatch = "minty"),
title = "hi",
ui_dygraph("dygraph"),
renderUI(output$dygraph)
)
)
server <- function(input, output, session, df) {
metric <- reactive({ metrics_list[[input$metric]] })
output$dygraph <- renderDygraph({
data = df
metric_suffix <- ifelse(!is.null(metric()$currency), glue::glue(" ({metric()$currency})"), "")
metric_legend <- paste0(metric()$legend, metric_suffix)
metric_legend2 <- paste0(metric()$legend2)
if(metric()$id == "comprar_main") {
dyAxisValueRange = c(220000, 310000)
dy2AxisValueRange = c(0, 15000)
} else if (metric()$id == "alquiler_main") {
dyAxisValueRange = c(0, 2700)
dy2AxisValueRange = c(0, 4000)
} else { # price_to_rent_main axis
dyAxisValueRange = c(15, 35)
dy2AxisValueRange = c(0, 3.5)
}
if (metric()$id == "comprar_main") {
data = stats
} else if (metric()$id == "alquiler_main") {
data = stats
} else {
data = stats_price_to_rent
}
data %>%
filter(type == metric()$id) %>%
select(-c(type)) %>%
column_to_rownames("collectionDate") %>%
as.xts() %>%
# as.xts(order.by = .$collectionDate)
dygraph(main = glue::glue("{metric()$title}")) %>%
dySeries("mean_price", label = metric_legend, drawPoints = FALSE, color = "#0099F9") %>%
dySeries("rolling_average", label = "Rolling Average (14 days)", drawPoints = FALSE, color = "#15354A") %>%
dyAxis("y", label = "Price", valueRange = dyAxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dyAxis("y2", label = metric_legend2, valueRange = dy2AxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dySeries("propertiesListed", label = metric_legend2, stepPlot = TRUE, fillGraph = TRUE, color = "#bdc2c6", axis=('y2')) %>%
dyOptions(
includeZero = FALSE,
axisLineColor = "#585858",
gridLineColor = "#bdc2c6",
axisLabelFontSize = 12,
axisLabelColor = "#585858",
disableZoom = TRUE
)
})
}
shinyApp(ui = ui, server = server)

As mentioned by #YBS in the comments the issue is that your digraph module misses a moduleServer. Moving you code from the main server to a module server will fix your issue:
library(xts)
library(bslib)
library(shiny)
library(tidyverse)
library(dygraphs)
ui_dygraph <- function(id) {
ns <- NS(id)
choices <- names(metrics_list)
tagList(
tags$div(
class = "panel-header",
selectInput(
ns("metric"), "Select metric for the time chart",
choices,
width = NULL,
selectize = TRUE,
selected = choices[[1]]
)
),
tags$div(
class = "chart-time-container",
dygraphOutput(ns("dygraph"), height = "240px")
)
)
}
server_dygraph <- function(id) {
moduleServer(id, function(input, output, session) {
metric <- reactive({
metrics_list[[input$metric]]
})
output$dygraph <- renderDygraph({
data <- df
metric_suffix <- ifelse(!is.null(metric()$currency), glue::glue(" ({metric()$currency})"), "")
metric_legend <- paste0(metric()$legend, metric_suffix)
metric_legend2 <- paste0(metric()$legend2)
if (metric()$id == "comprar_main") {
dyAxisValueRange <- c(220000, 310000)
dy2AxisValueRange <- c(0, 15000)
} else if (metric()$id == "alquiler_main") {
dyAxisValueRange <- c(0, 2700)
dy2AxisValueRange <- c(0, 4000)
} else {
dyAxisValueRange <- c(15, 35)
dy2AxisValueRange <- c(0, 3.5)
}
if (metric()$id == "comprar_main") {
data <- stats
} else if (metric()$id == "alquiler_main") {
data <- stats
} else {
data <- stats_price_to_rent
}
data %>%
filter(type == metric()$id) %>%
select(-c(type)) %>%
column_to_rownames("collectionDate") %>%
as.xts() %>%
dygraph(main = glue::glue("{metric()$title}")) %>%
dySeries("mean_price", label = metric_legend, drawPoints = FALSE, color = "#0099F9") %>%
dySeries("rolling_average", label = "Rolling Average (14 days)", drawPoints = FALSE, color = "#15354A") %>%
dyAxis("y",
label = "Price", valueRange = dyAxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dyAxis("y2",
label = metric_legend2, valueRange = dy2AxisValueRange, independentTicks = TRUE,
valueFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}',
axisLabelFormatter = 'function(d){return d.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",");}'
) %>%
dySeries("propertiesListed", label = metric_legend2, stepPlot = TRUE, fillGraph = TRUE, color = "#bdc2c6", axis = ("y2")) %>%
dyOptions(
includeZero = FALSE,
axisLineColor = "#585858",
gridLineColor = "#bdc2c6",
axisLabelFontSize = 12,
axisLabelColor = "#585858",
disableZoom = TRUE
)
})
})
}
ui <- navbarPage(
fluidPage(
theme = bs_theme(bootswatch = "minty"),
title = "hi",
ui_dygraph("dygraph")
)
)
server <- function(input, output, session, df) {
server_dygraph("dygraph")
}
shinyApp(ui = ui, server = server)

Related

Reproducible Example Included - How can create a rshiny drilldown highcharter pie chart that links out to urls for each segment?

My drilldown was working, then I added urls for the user to be linked out when they click on each segment. Here is the reproducible example (I had to comment out the urls as that causes an error). It seems that having a tibble dataframe as the main dataframe the pie chart is using is the only way to have a drilldown capability, but tibble doesn't accept a url column.
library(shiny)
library(DBI)
library(sparklyr)
library(readr)
library(data.table)
library(dplyr)
library(shinyWidgets)
library(DT)
library(highcharter)
library(httr)
library(purrr)
ui <- fluidPage(
fluidRow(
div(style="display: inline-block;vertical-align:top;padding-left: 35%",
highchartOutput("hccontainer_donutchart", height = "475px", width = "475px"))
),
)
server <- function(input, output) {
click_js <- JS("function(event) {Shiny.onInputChange('pieclick',event.point.name);}")
drilldown1_dat <- data.frame(
name = c("Talent", "Quality", "Safety"),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# ),
value = c(25, 25, 25)
)
drilldown1_piecolors <- c("#4169e1", "#4169e1", "#4169e1")
drilldown2_dat <- data.frame(
name = c("Base", "Energy", "Facilities"),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# ),
value = c(20, 20, 20)
)
drilldown2_piecolors <- c("#4169e1", "#4169e1", "#4169e1")
drilldown1_parsed <- list_parse2(drilldown1_dat)
drilldown2_parsed <- list_parse2(drilldown2_dat)
df <- tibble(
name = c("Allies", "Log", "Financials", "People", "Digital", "Operational", "Modernization", "Infrastructure"),
y = c(12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5),
# url = c(
# "https://weather.com/",
# "https://finance.yahoo.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# "https://msnbc.com/",
# ),
drilldown = name
)
df_piecolors <- c("#929292", "#929292", "#929292", "#4169e1", "#929292", "#929292", "#929292", "#4169e1")
# DONUT DRILLDOWN FUNCTION
donut_drilldown <- function(donut_data, piecolors, donut_title, hc_name) {
hc_name <- renderHighchart({
highchart() %>%
hc_plotOptions(
series = list(
cursor = "pointer",
point = list(
events = list(
click = JS( "function () { location.href = window.open(this.options.key, '_blank').foucs(); }")
)
)
)
) %>%
hc_tooltip(enabled = FALSE) %>%
hc_chart(type = "pie") %>%
hc_colors(piecolors) %>%
hc_title(
verticalAlign = 'middle',
text = donut_title,
#marginTop = -50,
floating = TRUE,
style = list(fontWeight='bold', fontSize='12px')
) %>%
hc_add_series(
data = donut_data, type = "pie", innerSize='30%', size='100%',
mapping = hcaes(name = name, y = y),
name = "DAF Focus Areas",
colorByPoint = TRUE,
dataLabels = list(enabled = TRUE,
distance = -55,
color = 'white',
crop = FALSE)
) %>%
hc_drilldown(
allowPointDrilldown = TRUE,
series = list(
list(
id = "People",
type = "pie",
innerSize = '30%', size = '100%',
data = drilldown1_parsed,
dataLabels = list(enabled = TRUE,
distance = -52,
crop = FALSE)
),
list(
id = "Infrastructure",
type = "pie",
innerSize = '30%', size = '100%',
data = drilldown2_parsed,
#mapping = hcaes(name = name, y = value, key = url),
dataLabels = list(enabled = TRUE,
distance = -52,
crop = FALSE)
)
)
) %>%
hc_chart(type = "pie", events = list(
load = JS("function() {console.log(this)}"),
drilldown = JS("function(e) {this.update({title: {text: e.seriesOptions.id}})}"),
drillup = JS("function() {this.update({title: {text: 'Main Donut' }})}")
)) %>%
hc_plotOptions(series = list(events = list(click = click_js)))
})
}
output$clicked <- renderText({
input$pieclick
})
output$hccontainer_donutchart = donut_drilldown(df, df_piecolors, "Donut", "hccontainer_donutchart")
}
# Run the application
shinyApp(ui = ui, server = server)

How to change chart based on toggle checkbox in r shiny?

I am new to shiny and trying to change chart variable based on toggle switch input but getting error.
I have used the toggleid inside the observe({}) but not sure if that's how it is done.
Based on condition I have stored the required variable name in Case_selected which I have tried to use with !!Case_selected to get the variable name out from it.
ui code:
fluidRow(
style = "border: 1px solid gray;",
h3("Top Countries with Confirmed Cases"),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmedtotal",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_total", height = "650px")),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmeddaily",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_daily", height = "650px")),
column(6,
h4("Latest 1 week Top Countries by Daily Confirmed Cases"),
plotOutput("lastweek_confirmed_daily", height = "650px")
)
),
server code:
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (is.null(x))
Case_selected <- "Confirmed"
else
Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = !! Case_selected, n = 10) %>% # Confirmed
ggplot(aes( x = !! Case_selected, y = reorder(Country.Region, !! Case_selected),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
#scale_fill_tableau(palette = "Tableau 20")
})
Error: object 'Case_selected' not found
I have also tried with !! rlang::sym() but not sure why none of this is working.
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = !! rlang::sym(Case_selected) , n = 10) %>% # Confirmed
ggplot(aes( x = !! rlang::sym(Case_selected), y = reorder(Country.Region, !! rlang::sym(Case_selected)),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
Original Code that works without using any variable toggle option:
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = Confirmed, n = 10) %>%
ggplot(aes( x = Confirmed, y = reorder(Country.Region, Confirmed),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
#scale_fill_tableau(palette = "Tableau 20")
})
Update ts_all_long
Update for reproduce able example:
library(tidyverse)
library(lubridate)
file_url1 <- "https://raw.githubusercontent.com/johnsnow09/covid19-df_stack-code/main/ts_all_long4.csv"
ts_all_long <- read.csv(url(file_url1))
ts_all_long <- ts_all_long %>%
mutate(date = as.Date(date))
ui.R
library(shiny)
library(shinydashboard)
library(shinythemes)
library(shinyWidgets)
library(highcharter)
shinyUI(fluidPage(
theme=shinytheme("lumen"),
themeSelector(),
navbarPage(
title = "Covid19 Dashboard",
id = "Covid19_Dashboard",
tabPanel("By Confirmed Cases",
# Application title
titlePanel("Global level"),
# fluidRow(h5("(this Page may take some time, kindly wait to load!!)",
# col = "gray30", align = "center")),
fluidRow(
style = "border: 1px solid gray;",
h3("Top Countries with Confirmed Cases"),
column(3, style = "border: 1px solid gray;",
materialSwitch(
inputId = "id_switch_confirmedtotal",
label = "Death Cases",
value = FALSE,
status = "danger"
),
plotOutput("top_confirmed_total", height = "650px")
)
)
)))
server.R
library(shiny)
library(tidyverse)
library(ggthemes)
library(covid19.analytics)
library(tidytext)
library(scales)
library(lubridate)
library(glue)
library(highcharter)
library(shinyWidgets)
shinyServer(function(input, output) {
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (is.null(x))
Case_selected <- "Confirmed"
else
Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = .data[[Case_selected]], n = 10) %>% # Confirmed
ggplot(aes( x = .data[[Case_selected]],
y = reorder(Country.Region, .data[[Case_selected]]),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
})
You need to define Case_selected as reactive so that you can use it throughout the app. Also use .data to refer to column name.
shinyServer(function(input, output) {
rv <- reactiveValues()
observe({
x <- input$id_switch_confirmedtotal
# condition tested
if (!x) rv$Case_selected <- "Confirmed"
else rv$Case_selected <- "Death"
})
output$top_confirmed_total <- renderPlot({
ts_all_long %>%
filter(date == max(date, na.rm = TRUE)) %>%
slice_max(order_by = .data[[rv$Case_selected]], n = 10) %>% # Confirmed
ggplot(aes( x = .data[[rv$Case_selected]],
y = reorder(Country.Region, .data[[rv$Case_selected]]),
fill = Country.Region)) +
geom_col(show.legend = FALSE) +
scale_x_continuous(label = unit_format(scale = 1e-6, unit = "M")) +
scale_fill_tableau(palette = "Tableau 20") +
labs(title = "Top10 TotalConfirmed Countries",
subtitle = glue("as of {max(ts_all_long$date)}"),
y = "", x = "Total Confirmed Cases",
caption = "Data source: covid19.analytics
Created by: ViSa")
})
})

R Shiny error - cannot coerce type 'closure' to vector of type 'character'

I know this question has been asked many times before, but none of the solutions that I've read seem to work for me.
I have an R shiny app that works perfectly on my computer, but when I try to deploy it to an online server, I get the error "cannot coerce type 'closure' to vector of type 'character'". Here is my code (I have it all combined in app.R):
ui <- navbarPage(title = 'COVID Tweets',
tabPanel(
# App title ----
title = "US",
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "dateUS",
label = "Date:",
min = as.Date('2020-01-21'),
max = as.Date('2020-05-02'),
value = as.Date('2020-03-12'),
animate = animationOptions(interval = 2000)
),
radioButtons(inputId = 'sentimentUS',
label = 'Sentiment measure',
choices = c('Anxiety' = 'mean_anx',
'Sadness' = 'mean_sad',
'Anger' = 'mean_anger')
),
radioButtons(inputId = 'covid_measure',
label = 'COVID-19 measure',
choices = c('New Cases' = 'new_cases_mean_log10_no0',
'New Deaths' = 'new_deaths_mean_log10_no0',
'% New Cases' = 'pct_new_cases_mean')
)
),
mainPanel(
plotOutput(outputId = "my_plot")
)
)
),
tabPanel(
# App title ----
title = "State",
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
sliderInput(inputId = "date",
label = "Date:",
min = as.Date('2020-01-21'),
max = as.Date('2020-05-02'),
value = as.Date('2020-03-12'),
animate = animationOptions(interval = 2000)
),
radioButtons(inputId = 'sentiment',
label = 'Sentiment measure',
choices = c('Anxiety' = 'mean_anx',
'Sadness' = 'mean_sad',
'Anger' = 'mean_anger')
),
selectInput(inputId = 'state',
label = 'State Spotlight',
choices = fips,
selected = 36
),
radioButtons(inputId = 'curve_measure',
label = 'COVID-19 measure',
choices = c('New Cases' = 'new_cases_mean_curve',
'New Deaths' = 'new_deaths_mean_curve',
'% New Cases' = 'pct_new_cases_mean_curve')
)
),
mainPanel(
plotOutput(outputId = "state_plot")
)
)
)
)
# SERVER FUNCTION ---------------------------------------------------------
server_function <- shinyServer(function(input, output) {
output$my_plot <- renderPlot({
colorUS <- case_when(input$sentimentUS == 'mean_anx'~'darkorchid3',
input$sentimentUS == 'mean_sad'~'dodgerblue3',
input$sentimentUS == 'mean_anger'~'firebrick3')
df_sent <- sentiment_bystate %>%
filter(date == input$dateUS,
input$sentimentUS > 0) %>%
select(date, fips, input$sentimentUS)
li_sent <- c(0,df_sent %>%
filter(input$sentimentUS > 0) %>%
pull(input$sentimentUS) %>% max())
df_covid <- states_df %>%
filter(date == input$dateUS) %>%
select(date, fips, input$covid_measure)
li_covid <- c(0,df_covid %>%
filter(input$covid_measure > 0) %>%
pull(input$covid_measure) %>% max())
# create the plot
plot_sentiment <- plot_usmap(data = df_sent,
values = input$sentimentUS) +
theme(legend.position = 'right') +
scale_fill_continuous(name = 'Sentiment\n(%)',
low = 'white',
high = colorUS,
limits = li_sent) +
ggtitle('Sentiment Measure') +
theme(plot.title = element_text(hjust = 0.5,
size = 24),
legend.title = element_text(size = 14),
legend.text = element_text(size = 10),
legend.title.align = .5)
plot_covid <- plot_usmap(data = df_covid,
values = input$covid_measure) +
theme(legend.position = 'right') +
scale_fill_continuous(name = 'Number',
low = 'white',
high = 'tomato4',
limits = li_covid) +
ggtitle('COVID-19 Measure') +
theme(plot.title = element_text(hjust = 0.5,
size = 24),
legend.title = element_text(size = 14),
legend.text = element_text(size = 10),
legend.title.align = .5)
# Display the plot
gridExtra::grid.arrange(plot_sentiment,plot_covid, ncol = 1)
})
output$state_plot <- renderPlot({
color <- case_when(input$sentiment == 'mean_anx'~'darkorchid3',
input$sentiment == 'mean_sad'~'dodgerblue3',
input$sentiment == 'mean_anger'~'firebrick3')
df_sentstate <- sentiment_bystate %>%
filter(date == input$date,
fips == input$state) %>%
select(date, fips, input$sentiment)
df_senttime <- sentiment_bystate %>%
filter(fips == input$state,
date >= states_df %>% filter(fips %in% input$state) %>%
pull(date) %>% min())
state_map <- plot_usmap(include = input$state,
data = df_sentstate,
values = input$sentiment) +
scale_fill_continuous(name = input$sentiment,
low = 'white',
high = color,
limits = c(0,sentiment_bystate %>%
filter(fips == input$state) %>%
pull(input$sentiment) %>% max())) +
theme(legend.position = "right")
state_curve <- ggplot(data = states_df %>%
filter(fips == input$state)) +
geom_line(aes(x = date, y = states_df %>%
filter(fips == input$state) %>%
pull(input$curve_measure)), color = 'black',size = 2) +
geom_point(data = df_senttime,
aes(x = date, y = df_senttime %>%
pull(input$sentiment)*(states_df %>%
filter(fips == input$state) %>%
pull(input$curve_measure) %>% max(na.rm = TRUE)/df_senttime
%>% pull(input$sentiment) %>% max())),
color = color, size = 2) +
geom_vline(xintercept = input$date) +
labs(x = 'Date', y = 'Severity') +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5,
size = 18),
legend.title = element_text(size = 12))
gridExtra::grid.arrange(state_map,state_curve,ncol = 1)
})
})
# SHINY APP CALL --------------------------------------------------------------
shinyApp(ui = ui, server = server_function)

how to create two independent drill down plot using Highcharter?

I'm working on shiny app that contains two drill down charts, both read from same data file the only difference is the first chart excute summation, while the second one gets averages, the issue is whatever the change I make both charts still conflicting , here is the used code
cate<-c("Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries")
Sub_Product<-c("nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug")
Main_Product<-c("outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor ","indoor ","indoor ","indoor ","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor ","indoor ","indoor ","indoor ","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o")
Product<-c("abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe")
sum1<-c(43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25)
sum2<-c(14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905)
avg1<-c(48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36)
avg2<-c(6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540)
dat<-data.frame(cate,Sub_Product,Main_Product,Product,sum1,sum2,avg1,avg2)
all_products<-c("Furniture","drinks","groceries","dairy","technology")
ACClist<-c("sum1","sum2")
AVGlist<-c("avg1","avg2")
library (shinyjs)
library (tidyr)
library (data.table)
library (highcharter)
library (dplyr)
library (shinydashboard)
library (shiny)
library (shinyWidgets)
header <-dashboardHeader()
body <- dashboardBody(fluidRow(
column(width = 12,
radioGroupButtons(
inputId = "l1PAD", label = NULL,size = "lg",
choices = all_products, justified = TRUE,
individual = TRUE)
)),
fluidRow(
highchartOutput("accuPA",height = "300px"),
highchartOutput("avgPA",height = "300px")
))
sidebar <- dashboardSidebar(collapsed = T,
radioGroupButtons(
"accuselectPA","sum",choices=ACClist,
direction = "vertical",width = "100%",justified = TRUE
),
br(),
radioGroupButtons(
"avgselectPA","Average ",choices=AVGlist,
direction = "vertical",width = "100%",justified = TRUE
))
ui <- dashboardPage(header, sidebar, body)
server <- function(input, output, session) {
observe({
print(input$l1PAD)
datz<-reactive({
dat%>%filter(cate==input$l1PAD)
})
print(datz())
str(datz())
output$accuPA <- renderHighchart({
summarized <- datz() %>%
group_by(Main_Product) %>%
summarize(Quantity = sum(!!sym(input$accuselectPA)))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$Main_Product, y = summarized$Quantity)
drilldownHandler <- JS("function(event) {Shiny.onInputChange('ClickedInput', event.point.drilldown);}")
installDrilldownReceiver <- JS("function() {
var chart = this;
Shiny.addCustomMessageHandler('drilldown', function(message) {
var point = chart.get(message.point)
chart.addSeriesAsDrilldown(point, message.series);
});
}")
highchart() %>%
hc_chart(events = list(load = installDrilldownReceiver, drilldown = drilldownHandler)) %>%
hc_xAxis(type = "category") %>%
hc_add_series(tibbled, "column", hcaes(x = name, y = y, drilldown = name, id = name), color = "#e6b30a") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(allowPointDrilldown = TRUE)
})
observeEvent(input$ClickedInput, {
levels <- strsplit(input$ClickedInput, "_", fixed = TRUE)[[1]]
resemblences <- c("Main_Product", "Product", "Sub_Product")
dataSubSet <- datz()
for (i in 1:length(levels)) {
dataSubSet <- datz()[datz()[[resemblences[i]]] == levels[i],]}
print(dataSubSet)
str(dataSubSet)
normalized <- data.frame(category = dataSubSet[[resemblences[length(levels) + 1]]],amount= dataSubSet[, input$accuselectPA])
print(normalized)
str(normalized)
summarized <- normalized %>%group_by(category) %>% summarize(Quantity = sum(amount))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$category, y = summarized$Quantity)
nextLevelCodes = lapply(tibbled$name, function(fac) {paste(c(levels, as.character(fac)), collapse = "_")
}) %>% unlist
tibbled$id = nextLevelCodes
if (length(levels) < length(resemblences) - 1) {
tibbled$drilldown = nextLevelCodes
}
session$sendCustomMessage("drilldown", list(
series = list(type = "column",name = paste(levels, sep = "_"),data = list_parse(tibbled)
),
point = input$ClickedInput
))
})
output$trial <- renderText({input$ClickedInput})
})
observe({
print(input$l1PAD)
datz2<-reactive({
dat%>%filter(cate==input$l1PAD)
})
print(datz2())
str(datz2())
output$avgPA <- renderHighchart({
summarized2 <- datz2() %>%
group_by(Main_Product) %>%
summarize(Quantity2 = mean(!!sym(input$avgselectPA)))
summarized2 <- arrange(summarized2, desc(Quantity2))
tibbled2 <- tibble(name = summarized2$Main_Product, y = summarized2$Quantity2)
drilldownHandler2 <- JS("function(event) {Shiny.onInputChange('ClickedInput2', event.point.drilldown);}")
installDrilldownReceiver2 <- JS("function() {
var chart = this;
Shiny.addCustomMessageHandler('drilldown', function(message) {
var point = chart.get(message.point)
chart.addSeriesAsDrilldown(point, message.series);
});
}")
highchart() %>%
hc_chart(events = list(load = installDrilldownReceiver2, drilldown = drilldownHandler2)) %>%
hc_xAxis(type = "category") %>%
hc_add_series(tibbled2, "column", hcaes(x = name, y = y, drilldown = name, id = name), color = "#e6b30a") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(allowPointDrilldown = TRUE)
})
observeEvent(input$ClickedInput2, {
levels2 <- strsplit(input$ClickedInput2, "_", fixed = TRUE)[[1]]
resemblences2 <- c("Main_Product", "Product", "Sub_Product")
dataSubSet2 <- datz2()
for (i in 1:length(levels2)) {
dataSubSet2 <- datz2()[datz2()[[resemblences2[i]]] == levels2[i],]}
print(dataSubSet2)
str(dataSubSet2)
normalized2 <- data.frame(category = dataSubSet2[[resemblences2[length(levels2) + 1]]],amount= dataSubSet2[, input$avgselectPA])
print(normalized2)
str(normalized2)
summarized2 <- normalized2 %>%group_by(category) %>% summarize(Quantity2 = mean(amount))
summarized2 <- arrange(summarized2, desc(Quantity2))
tibbled2 <- tibble(name = summarized2$category, y = summarized2$Quantity2)
nextLevelCodes2 = lapply(tibbled2$name, function(fac) {paste(c(levels2, as.character(fac)), collapse = "_")
}) %>% unlist
tibbled2$id = nextLevelCodes2
if (length(levels2) < length(resemblences2) - 1) {
tibbled2$drilldown = nextLevelCodes2
}
session$sendCustomMessage("drilldown", list(
series = list(type = "column",name = paste(levels2, sep = "_"),data = list_parse(tibbled2)
),
point = input$ClickedInput2
))
})
output$trial <- renderText({input$ClickedInput2})
})
}
shinyApp(ui, server)
all needed is just copy and paste the code above and try to drill down in the first chart to see the breakdown of total count it will not respond while chart 2 will respond to the click on chart one column
the hover text on each column shows the difference between two charts
as how the first one show the summation while the second one shows the average value.
the data frame might be long but it is a sample of my dataset
minor request, I need only the 3rd level on both plots to be line chart
update another unsuccessful trial ------------------
cate<-c("Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries")
Sub_Product<-c("nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug")
Main_Product<-c("outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor ","indoor ","indoor ","indoor ","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor ","indoor ","indoor ","indoor ","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o")
Product<-c("abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe")
sum1<-c(43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25)
sum2<-c(14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905)
avg1<-c(48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36)
avg2<-c(6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540)
dat<-data.frame(cate,Sub_Product,Main_Product,Product,sum1,sum2,avg1,avg2)
all_products<-c("Furniture","drinks","groceries","dairy","technology")
ACClist<-c("sum1","sum2")
AVGlist<-c("avg1","avg2")
library (shinyjs)
library (tidyr)
library (data.table)
library (highcharter)
library (dplyr)
library (shinydashboard)
library (shiny)
library (shinyWidgets)
header <-dashboardHeader()
body <- dashboardBody(fluidRow(
column(width = 12,
radioGroupButtons(
inputId = "l1PAD", label = NULL,size = "lg",
choices = all_products, justified = TRUE,
individual = TRUE)
)),
fluidRow(
highchartOutput("accuPA",height = "300px"),
highchartOutput("avgPA",height = "300px")
))
sidebar <- dashboardSidebar(collapsed = T,
radioGroupButtons(
"accuselectPA","sum",choices=ACClist,
direction = "vertical",width = "100%",justified = TRUE
),
br(),
radioGroupButtons(
"avgselectPA","Average ",choices=AVGlist,
direction = "vertical",width = "100%",justified = TRUE
))
ui <- dashboardPage(header, sidebar, body)
server <- function(input, output, session) {
observe({
print(input$l1PAD)
datz<-reactive({
dat%>%filter(cate==input$l1PAD)
})
TYT<-reactive({
datz()%>%select(1:4)
})
nont<-reactive({
datz()%>%pull(input$avgselectPA)
})
print(datz())
str(datz())
print(nont())
str(nont())
urt<-reactive({
data_frame(TYT(),nont())
})
print(urt())
str(urt())
output$accuPA <- renderHighchart({
summarized <- datz() %>%
group_by(Main_Product) %>%
summarize(Quantity = sum(!!sym(input$accuselectPA)))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$Main_Product, y = summarized$Quantity)
drilldownHandler <- JS("function(event) {Shiny.onInputChange('ClickedInput', event.point.drilldown);}")
installDrilldownReceiver <- JS("function() {
var chart = this;
Shiny.addCustomMessageHandler('drilldown', function(message) {
var point = chart.get(message.point)
chart.addSeriesAsDrilldown(point, message.series);
});
}")
highchart() %>%
hc_chart(events = list(load = installDrilldownReceiver, drilldown = drilldownHandler)) %>%
hc_xAxis(type = "category") %>%
hc_add_series(tibbled, "column", hcaes(x = name, y = y, drilldown = name, id = name), color = "#e6b30a") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(allowPointDrilldown = TRUE)
})
observeEvent(input$ClickedInput, {
levels <- strsplit(input$ClickedInput, "_", fixed = TRUE)[[1]]
resemblences <- c("Main_Product", "Product", "Sub_Product")
dataSubSet <- datz()
for (i in 1:length(levels)) {
dataSubSet <- datz()[datz()[[resemblences[i]]] == levels[i],]}
print(dataSubSet)
str(dataSubSet)
normalized <- data.frame(category = dataSubSet[[resemblences[length(levels) + 1]]],amount= dataSubSet[, input$accuselectPA])
print(normalized)
str(normalized)
summarized <- normalized %>%group_by(category) %>% summarize(Quantity = sum(amount))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$category, y = summarized$Quantity)
nextLevelCodes = lapply(tibbled$name, function(fac) {paste(c(levels, as.character(fac)), collapse = "_")
}) %>% unlist
tibbled$id = nextLevelCodes
if (length(levels) < length(resemblences) - 1) {
tibbled$drilldown = nextLevelCodes}
session$sendCustomMessage("drilldown", list(
series = list(type = "column",name = paste(levels, sep = "_"),data = list_parse(tibbled)
),
point = input$ClickedInput
))
})
output$avgPA<-renderHighchart({
datSum <- urt() %>%
group_by(Main_Product) %>%
summarize(Quantity = mean('nont')
)
datSum <- arrange(datSum,desc(Quantity))
Lvl1dfStatus <- tibble(name = datSum$Main_Product, y = datSum$Quantity, drilldown = tolower(name))
#Second Tier # Generalized to not use one single input
# Note: I am creating a list of Drilldown Definitions here.
Level_2_Drilldowns <- lapply(unique(urt()$Main_Product), function(x_level) {
# x_level is what you called 'input' earlier.
datSum2 <- urt()[urt()$Main_Product == x_level,]
datSum2 <- datSum2 %>%
group_by(Product) %>%
summarize(Quantity = mean('nont')
)
datSum2 <- arrange(datSum2,desc(Quantity))
# Note: The "drilldown" variable has to be unique, this is why we use level 1 plus level 2 names.
Lvl2dfStatus <- tibble(name = datSum2$Product,y = datSum2$Quantity, drilldown = tolower(paste(x_level, name, sep = "_")))
list(id = tolower(x_level), type = "column", data = list_parse(Lvl2dfStatus))
})
#Third Tier # Generalized through all of level 2
# Note: Again creating a list of Drilldown Definitions here.
Level_3_Drilldowns <- lapply(unique(urt()$Main_Product), function(x_level) {
datSum2 <- urt()[urt()$Main_Product == x_level,]
lapply(unique(datSum2$Product), function(y_level) {
datSum3 <- datSum2[datSum2$Product == y_level,]
datSum3 <- datSum3 %>%
group_by(Sub_Product) %>%
summarize(Quantity = mean('nont')
)
datSum3 <- arrange(datSum3,desc(Quantity))
Lvl3dfStatus <- tibble(name = datSum3$Sub_Product,y = datSum3$Quantity)
# Note: The id must match the one we specified above as "drilldown"
list(id = tolower(paste(x_level, y_level, sep = "_")), type = "column", data = list_parse2(Lvl3dfStatus))
})
}) %>% unlist(recursive = FALSE)
highchart() %>%
hc_xAxis(type = "category") %>%
hc_add_series(Lvl1dfStatus, "column", hcaes(x = name, y = Product), color = "#E4551F") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(
allowPointDrilldown = TRUE,
series = c(Level_2_Drilldowns, Level_3_Drilldowns)
)
})
#THE NEXT }) is for observe
})
}
shinyApp(ui, server)
Here you go, both graphs operate independently of each other's drilldowns.
I simplified your code as well as you had a lot of observes and reactives that were not needed (in this example at least).
cate<-c("Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","Furniture","drinks","drinks","groceries","groceries","groceries","dairy","dairy","dairy","dairy","groceries","technology","technology","technology","technology","technology","technology","technology","technology","groceries")
Sub_Product<-c("nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","nov","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","oct","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","sept","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug","aug")
Main_Product<-c("outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o","outdoor","indoor","outdoor","indoor","indoor","outdoor","indoor","indoor","indoor","indoor","outdoor","outdoor","n&o","n&o","indoor","indoor","indoor","indoor","outdoor","indoor","outdoor","outdoor","outdoor","indoor","outdoor","indoor","outdoor","outdoor","indoor","outdoor","n&o")
Product<-c("abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe","abc","def","ghh","hig","lmn","opk","cba","dfw","ewr","csad","wer","casd","were","csad","rt","hgf","qeq","hgf","qer","qer2","erqerq","qdq","dwqer","qerqe","erqererq","e2342","ererq","qewrw","qrerqr","qreqw","qerqe")
sum1<-c(43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25,43,90,135,125,87,4,23,120,4,127,70,68,129,63,131,90,67,110,90,119,81,68,15,29,49,11,76,82,65,83,25)
sum2<-c(14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905,14567,11111,3287,3563,9633,11162,3044,8437,4382,11250,3932,5587,4175,9708,4970,8388,10673,4301,12475,13494,12519,5632,3898,12472,4381,14085,10041,4276,12953,11143,12905)
avg1<-c(48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36,48,132,115,83,84,77,111,102,113,96,136,97,89,97,66,18,123,29,37,118,66,87,52,11,97,25,144,21,40,6,36)
avg2<-c(6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540,6775,3142,3916,12828,9889,4025,11374,10594,4263,8871,11229,4787,7478,5316,5299,14068,3981,12993,12435,13845,4320,7472,14285,10221,11883,7783,13980,11426,13120,8632,14540)
dat<-data.frame(cate,Sub_Product,Main_Product,Product,sum1,sum2,avg1,avg2, stringsAsFactors = FALSE)
ACClist<-c("sum1","sum2")
AVGlist<-c("avg1","avg2")
library (shinyjs)
library (tidyr)
library (data.table)
library (highcharter)
library (dplyr)
library (shinydashboard)
library (shiny)
library (shinyWidgets)
header <-dashboardHeader()
body <- dashboardBody(fluidRow(
column(width = 12,
radioGroupButtons(
inputId = "l1PAD", label = NULL,size = "lg",
choices = unique(dat$cate), justified = TRUE,
individual = TRUE)
)),
fluidRow(
box(
title = "Summation of dataset", highchartOutput("accuPA",height = "300px")
),
box(
title = "Mean of dataset", highchartOutput("avgPA",height = "300px")
)
))
sidebar <- dashboardSidebar(collapsed = T,
radioGroupButtons(
"accuselectPA","sum",choices=ACClist,
direction = "vertical",width = "100%",justified = TRUE
),
br(),
radioGroupButtons(
"avgselectPA","Average ",choices=AVGlist,
direction = "vertical",width = "100%",justified = TRUE
))
ui <- dashboardPage(header, sidebar, body)
server <- function(input, output, session) {
#data set
dat_filtered <- reactive({
dat[dat$cate == input$l1PAD,]
})
#Acc/sum graph
output$accuPA<-renderHighchart({
#LEVEL 1
datSum <- dat_filtered() %>%
group_by(Main_Product) %>%
summarize(Quantity = mean(get(input$accuselectPA)))
datSum <- arrange(datSum,desc(Quantity))
Lvl1dfStatus <- tibble(name = datSum$Main_Product, y = datSum$Quantity, drilldown = tolower(name))
#LEVEL 2
Level_2_Drilldowns <- lapply(unique(dat_filtered()$Main_Product), function(x_level) {
datSum2 <- dat_filtered()[dat_filtered()$Main_Product == x_level,]
datSum2 <- datSum2 %>%
group_by(Product) %>%
summarize(Quantity = mean(get(input$accuselectPA)))
datSum2 <- arrange(datSum2,desc(Quantity))
Lvl2dfStatus <- tibble(name = datSum2$Product,y = datSum2$Quantity, drilldown = tolower(paste(x_level, name, sep = "_")))
list(id = tolower(x_level), type = "column", data = list_parse(Lvl2dfStatus))
})
#LEVEL 3
Level_3_Drilldowns <- lapply(unique(dat_filtered()$Main_Product), function(x_level) {
datSum2 <- dat_filtered()[dat_filtered()$Main_Product == x_level,]
lapply(unique(datSum2$Product), function(y_level) {
datSum3 <- datSum2[datSum2$Product == y_level,]
datSum3 <- datSum3 %>%
group_by(Sub_Product) %>%
summarize(Quantity = mean(get(input$accuselectPA)))
datSum3 <- arrange(datSum3,desc(Quantity))
Lvl3dfStatus <- tibble(name = datSum3$Sub_Product,y = datSum3$Quantity)
list(id = tolower(paste(x_level, y_level, sep = "_")), type = "column", data = list_parse2(Lvl3dfStatus))
})
}) %>% unlist(recursive = FALSE)
highchart() %>%
hc_xAxis(type = "category") %>%
hc_add_series(Lvl1dfStatus, "column", hcaes(x = name, y = y), color = "#E4551F") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(
allowPointDrilldown = TRUE,
series = c(Level_2_Drilldowns, Level_3_Drilldowns)
)
})
#Avg/Avg graph
output$avgPA<-renderHighchart({
#LEVEL 1
datSum <- dat_filtered() %>%
group_by(Main_Product) %>%
summarize(Quantity = mean(get(input$avgselectPA)))
datSum <- arrange(datSum,desc(Quantity))
Lvl1dfStatus <- tibble(name = datSum$Main_Product, y = datSum$Quantity, drilldown = tolower(name))
#LEVEL 2
Level_2_Drilldowns <- lapply(unique(dat_filtered()$Main_Product), function(x_level) {
datSum2 <- dat_filtered()[dat_filtered()$Main_Product == x_level,]
datSum2 <- datSum2 %>%
group_by(Product) %>%
summarize(Quantity = mean(get(input$avgselectPA)))
datSum2 <- arrange(datSum2,desc(Quantity))
Lvl2dfStatus <- tibble(name = datSum2$Product,y = datSum2$Quantity, drilldown = tolower(paste(x_level, name, sep = "_")))
list(id = tolower(x_level), type = "column", data = list_parse(Lvl2dfStatus))
})
#LEVEL 3
Level_3_Drilldowns <- lapply(unique(dat_filtered()$Main_Product), function(x_level) {
datSum2 <- dat_filtered()[dat_filtered()$Main_Product == x_level,]
lapply(unique(datSum2$Product), function(y_level) {
datSum3 <- datSum2[datSum2$Product == y_level,]
datSum3 <- datSum3 %>%
group_by(Sub_Product) %>%
summarize(Quantity = mean(get(input$avgselectPA)))
datSum3 <- arrange(datSum3,desc(Quantity))
Lvl3dfStatus <- tibble(name = datSum3$Sub_Product,y = datSum3$Quantity)
list(id = tolower(paste(x_level, y_level, sep = "_")), type = "column", data = list_parse2(Lvl3dfStatus))
})
}) %>% unlist(recursive = FALSE)
highchart() %>%
hc_xAxis(type = "category") %>%
hc_add_series(Lvl1dfStatus, "column", hcaes(x = name, y = y), color = "#E4551F") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(
allowPointDrilldown = TRUE,
series = c(Level_2_Drilldowns, Level_3_Drilldowns)
)
})
}
shinyApp(ui, server)

Rda objects and reactivity in Shiny, R

I have a graph that should be updated by a dateInput in shiny. However, my app requires data to be loaded at the start. This messes with reactivity, and ensures that my graph cannot be updated, here is my script that works:
ui <- fluidPage(
#For Date of Update, days of unemployment
dateInput("updatedate", "Select Date", value = "2015-06-01", min = "2015-05-20", max = "2015-07-13", format = "yyyy-mm-dd", startview = "month", weekstart = 0, language = "en"),
ggvisOutput("duration")
)
server <- function(input, output) {
Durationdata<-reactive({
selectedupdate<-with(zoomlastupdate, zoomlastupdate[(Lastupdate == as.Date(input$updatedate, '%Y-%m-%d')),])
selectedupdate<-with(selectedupdate, selectedupdate[(Unemployed == 1),])
selectedupdate<-na.omit(selectedupdate)
count1<- selectedupdate[,1:2]
tabcount1<- data.frame(Duration=count(count1, 'spell')[,1], Unemployed=count(count1, 'spell')[,2])
tabcount1
})
all_values <- function(x) {
if(is.null(x)) return(NULL)
paste0(c("Duration","Unemployed"), ": ", format(x)[c(1,3)], collapse = "<br />")
}
add_title <- function(vis, ..., x_lab = "X units",y_lab="Y units", title = "Plot Title")
{
add_axis(vis, "x", title = x_lab) %>%
add_axis("x", orient = "top", ticks = 0, title = title,
properties = axis_props(
axis = list(stroke = "white"),
labels = list(fontSize = 0)
), ...) %>% add_axis("y", title=y_lab)
}
Durationdata %>% ggvis(x=~Duration, y =~Unemployed, fill := "#fff8dc") %>% layer_bars(width=0.5) %>% add_tooltip(all_values, "hover") %>% add_title(title = "Unemployment Duration", x_lab="Duration of Unemployment (Months)", y_lab="Number of Unemployed Persons") %>% set_options(width = 1000, height = 600, keep_aspect = NULL, resizable = TRUE) %>% bind_shiny("duration")
}
when I put the following code on top of it:
load("lastupdateemp.Rda")
load("zoomlastupdate.Rda")
load("lastupdateworkexp.Rda")
The reactive graph fails to update with the data input. How do I overcome this issue?

Resources