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

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")
})
})

Related

Confused with Shiny Modules and renderUI

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)

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)

RShiny: why does ggplot geom_rect fail with reactive faceting?

I am trying to create interactive plots with Shiny where the user can select faceting variables. I also want to plot temperature data underneath the point/line data. This all works fine until I try to incorporate a reactive faceting function AND add a geom_rect call, when I get the error:
Warning: Error in : Assigned data `layout$PANEL[match(keys$x, keys$y)]` must be compatible with existing data.
x Existing data has 1094 rows.
x Assigned data has 32 rows.
i Only vectors of size 1 are recycled.
I'm assuming that I've done something wrong with my faceting function, but I'm on week 2 of being unable to solve this issue, so it's time to ask for help!
Here is a simplified mock-up of the app. I can add two facets, OR I can add the temperature underlay, but trying both results in the error above.
library(shiny)
library(shinydashboard)
library(lubridate)
library(tidyr)
library(readr)
{ # Setup ----
# Create a dummy data frame
sitename <- rep(c("A", "B", "C", "D", "E", "F", "G", "H"), times = 4)
region <- rep(c("North", "South", "East", "West"), times = 8)
elevation <- rep(c("High", "Low"), each = 4, length.out = 32)
date <- as.Date(rep(c("2015-01-01", "2016-01-01", "2017-01-01", "2018-01-01"), each = 8))
affected <- runif(32, min = 0, max = 1)
sitedata <- data.frame(date, sitename, region, elevation, affected)
# Load and process external temperature data
noaacrw <- read_table2("http://coralreefwatch.noaa.gov/product/vs/data/guam.txt", skip = 21)
noaacrw <- noaacrw %>%
mutate(DateStart = as.Date(ISOdate(noaacrw$YYYY, noaacrw$MM, noaacrw$DD))) %>%
mutate(DateEnd = as.Date(DateStart + (as.Date(DateStart) - lag(as.Date(DateStart), default = first(DateStart))))) %>%
mutate(SST_AVG = `SST#90th_HS`) %>%
select(DateStart, DateEnd, SST_AVG) %>%
filter(DateStart > as.Date("2015-01-01")) %>%
filter(DateEnd < as.Date("2018-01-01"))
}
# UI ----
ui <- fluidPage(
fluidRow(
box(
title = "Choose your data", width = 3, solidHeader = TRUE,
selectInput("facet_select", "Select faceting variable:",
choices = list("None" = "none",
"Region" = "region",
"Elevation" = "elevation"),
selected = c("None")),
selectInput("facet2_select", "Select second faceting variable",
choices = list("None" = "none",
"Region" = "region",
"Elevation" = "elevation")),
checkboxInput("show_temp", "Show temperature data", FALSE)
),
box(
title = "See your data output", width = 9, solidHeader = TRUE,
plotOutput("siteplot", height = 500)
)
)
)
And the server side:
server <- function(input, output) {
facet1 <- reactive({
if(input$facet_select == "region"){return(region)}
if(input$facet_select == "elevation"){return(elevation)}
})
facet2 <- reactive({
if(input$facet_select == "region"){return(region)}
if(input$facet_select == "elevation"){return(elevation)}
})
faceter <- reactive({
if(input$facet_select == "none"){return(NULL)}
else if(input$facet_select != "none" & input$facet2_select == "none")
{return(list(facet_grid(facet1() ~ .)))}
else if(input$facet_select != "none" & input$facet2_select != "none")
{return(list(facet_grid(facet1() ~ facet2())))}
})
temperature <- reactive({
if(input$show_temp == FALSE){return(NULL)}
else if(input$show_temp == TRUE){return(list(
geom_rect(data = noaacrw,
aes(xmin = DateStart, xmax = DateEnd, ymin = 0, ymax = Inf, fill = SST_AVG),
position = "identity", show.legend = TRUE, alpha = 0.5),
scale_fill_gradient2(high = "red3", mid = "white", low = "blue3", midpoint = 28)))}
})
output$siteplot <- renderPlot({
ggplot()+
temperature()+
geom_point(data = sitedata, aes(x = date, y = affected, group = sitename, color = sitename), size = 3)+
geom_line(data = sitedata, aes(x = date, y = affected, group = sitename, color = sitename), size = 3)+
#facet_grid(elevation ~ region) <-- this works!
faceter() # <- but this does not!
})
}
# Run the application
shinyApp(ui = ui, server = server)
Here is my take (I used syms(...)). It works under R4.0, at least:
library(shiny)
library(shinydashboard)
library(lubridate)
library(tidyr)
library(readr)
library(ggplot2)
library(dplyr)
{ # Setup ----
# Create a dummy data frame
sitename <- rep(c("A", "B", "C", "D", "E", "F", "G", "H"), times = 4)
region <- rep(c("North", "South", "East", "West"), times = 8)
elevation <- rep(c("High", "Low"), each = 4, length.out = 32)
date <- as.Date(rep(c("2015-01-01", "2016-01-01", "2017-01-01", "2018-01-01"), each = 8))
affected <- runif(32, min = 0, max = 1)
sitedata <- data.frame(date, sitename, region, elevation, affected)
# Load and process external temperature data
noaacrw <- read_table2("http://coralreefwatch.noaa.gov/product/vs/data/guam.txt", skip = 21)
noaacrw <- noaacrw %>%
mutate(DateStart = as.Date(ISOdate(noaacrw$YYYY, noaacrw$MM, noaacrw$DD))) %>%
mutate(DateEnd = as.Date(DateStart + (as.Date(DateStart) - lag(as.Date(DateStart), default = first(DateStart))))) %>%
mutate(SST_AVG = `SST#90th_HS`) %>%
select(DateStart, DateEnd, SST_AVG) %>%
filter(DateStart > as.Date("2015-01-01")) %>%
filter(DateEnd < as.Date("2018-01-01"))
}
# UI ----
ui <- fluidPage(
fluidRow(
box(
title = "Choose your data", width = 3, solidHeader = TRUE,
selectInput("facet_select", "Select faceting variable:",
choices = list("None" = NULL,
"Region" = "region",
"Elevation" = "elevation"),
selected = c("None"),
multiple = TRUE),
checkboxInput("show_temp", "Show temperature data", FALSE)
),
box(
title = "See your data output", width = 9, solidHeader = TRUE,
plotOutput("siteplot", height = 500)
)
)
)
server <- function(input, output) {
temperature <- reactive({
if(!input$show_temp){return(NULL)}
else if(input$show_temp){return(list(
geom_rect(data = noaacrw,
aes(xmin = DateStart, xmax = DateEnd, ymin = 0, ymax = Inf, fill = SST_AVG),
position = "identity", show.legend = TRUE, alpha = 0.5),
scale_fill_gradient2(high = "red3", mid = "white", low = "blue3", midpoint = 28)))}
})
makePlot <- function(...){
p <- ggplot()+
temperature()+
geom_point(data = sitedata, aes(x = date, y = affected, group = sitename, color = sitename), size = 3)+
geom_line(data = sitedata, aes(x = date, y = affected, group = sitename, color = sitename), size = 3)
if(length(eval(substitute(alist(...)))) > 0){
p <- p + facet_grid(syms(...))
}
return(p)
}
output$siteplot <- renderPlot({
makePlot(input$facet_select)
})
}
# Run the application
shinyApp(ui = ui, server = server)

Shiny app does not reproduce graphics and not is responsive

I'm building a shiny application (Here!), Whose code below and the database for compilation can be found on my github. I can't understand why the graphics "Number of Deaths by Covid19 in Brazil" and "Number of Confirmed with Covid19 in Brazil" are not compiling? On my computer, sometimes the graphics are generated, sometimes not! In addition, the renderText () function is also not working and the graphics do not respond when changing the choice of state?
Obs: We did not notice an error when the code size decreased and only kept the graphics that are not compiling with the code below. That is, apparently, the brilliant cannot compile all the graphics for some reason!
Here is the code I am using:
Minimal code (I don't see the error in this case):
library("shiny")
library("readr")
library("dplyr")
library("tidyverse")
library("treemap")
library("ggplot2")
library("dplyr")
library("tidyr")
library("hrbrthemes")
library("ggrepel")
library("shinythemes")
library("rio")
library(miceadds)
load(url("https://rawcdn.githack.com/fsbmat-ufv/fsbmat-ufv.github.io/a16ef0fe0a27374cdbb7f88106c080ca0cd2ded3/blog_posts/26-03-2020/Corona/covid19.RData"))
data <- x
rm(x)
data$deaths[is.na(data$deaths)] <- 0
data$date <- as.Date(data$date)
data <- data[order(data$date) , ]
data <- data %>%
dplyr::filter(place_type == "state") %>%
dplyr::group_by(state,date, confirmed,deaths) %>%
select(date, state, confirmed, deaths, estimated_population_2019)
names(data) <- c("date", "state", "confirmed", "deaths", "Pop")
aggSetor <-data%>%filter(date==last(data$date))%>%group_by(state) %>% summarise(quantidade = sum(deaths),
confirmedM = mean(confirmed))
aggSetor$escala <- scale(aggSetor$confirmedM)
ui <- fluidPage( # App title ----
titlePanel("Coronavirus in Brazil"),
fluidRow(
column(width = 4, class = "well",
h4("Number of Deaths by Covid19 in Brazil"),
plotOutput("plot1", height = 200,
dblclick = "plot1_dblclick",
brush = brushOpts(
id = "plot1_brush",
resetOnNew = TRUE
)
)
),
column(width = 4, class = "well",
h4("Number of Confirmed with Covid19 in Brazil"),
plotOutput("plot2", height = 200,
dblclick = "plot2_dblclick",
brush = brushOpts(
id = "plot2_brush",
resetOnNew = TRUE
)
)
),
column(width = 4, class = "well",
h4("Treemap of deaths and number of confirmed by State"),
plotOutput("plot3", height = 200,
dblclick = "plot3_dblclick",
brush = brushOpts(
id = "plot3_brush",
resetOnNew = TRUE
)
)
)
)
)
server <- function(input, output) {
filt <- selectInput("codeInput",label ="Escolha um Estado",
choices = as.list(unique(data$state)))
output$codePanel <- renderUI({ filt
})
dataset<-reactive({
subset(data, state == input$codeInput)
})
dataset2<-reactive({
df <- dataset()
teste1 <- dplyr::lag(df$deaths)
teste1[is.na(teste1)] <- 0
teste2 <- dplyr::lag(df$confirmed)
teste2[is.na(teste2)] <- 0
df$teste1 <- teste1
df$teste2 <- teste2
df$deaths_day <- df$deaths-df$teste1
df$confirmed_day <- df$confirmed-df$teste2
df <- df %>% select(1:5,8:9)
return(df)
})
dataset3 <- reactive({
ndeaths <- data %>% group_by(date) %>% summarise(deaths = sum(deaths))
return(ndeaths)
})
dataset4 <- reactive({
nconfirmed <- data %>% group_by(date) %>% summarise(confirmed = sum(confirmed))
return(nconfirmed)
})
# -------------------------------------------------------------------
# Single zoomable plot (on left)
#ranges <- reactiveValues(x = date, y = confirmed)
output$plot1 <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19"
ggplot2::ggplot(dataset3(), aes(x = date, y = deaths)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset3()$deaths+20, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=deaths), position=position_dodge(width=0.9), vjust=-0.25) +
labs(x = xlab,
y = "Number of Deaths",
title = " ",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
output$plot2 <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19/caso"
ggplot2::ggplot(dataset4(), aes(x = date, y = confirmed)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset4()$confirmed+300, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=confirmed), position=position_dodge(width=0.5), vjust=-0.25) +
labs(x = xlab,
y = "Number of Confirmed",
title = " ",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
output$plot3 <- renderPlot({
treemap(aggSetor, index = "state", vSize = "quantidade", vColor = "escala",
type = "value", palette = "-RdGy", lowerbound.cex.labels = 0.3,
title = "Color related to deaths - Size related to confirmed")
})
}
shinyApp(ui = ui, server = server)
Complete code:
library("shiny")
library("readr")
library("dplyr")
library("tidyverse")
library("treemap")
library("ggplot2")
library("dplyr")
library("tidyr")
library("hrbrthemes")
library("ggrepel")
library("shinythemes")
library("rio")
#library(miceadds)
#setwd("~/GitHub/fsbmat-ufv.github.io/blog_posts/26-03-2020/Shiny/Corona")
#data <- read_csv(url("https://rawcdn.githack.com/fsbmat-ufv/fsbmat-ufv.github.io/fcba93f491ed21eba0628471649eb9a5bda033f2/blog_posts/26-03-2020/Corona/covid19.csv"))
#export(data, "covid19.rdata")
load(url("https://rawcdn.githack.com/fsbmat-ufv/fsbmat-ufv.github.io/a16ef0fe0a27374cdbb7f88106c080ca0cd2ded3/blog_posts/26-03-2020/Corona/covid19.RData"))
#load("covid19.Rdata")
data <- x
rm(x)
#data <- miceadds::load.Rdata2(filename=url("https://rawcdn.githack.com/fsbmat-ufv/fsbmat-ufv.github.io/a16ef0fe0a27374cdbb7f88106c080ca0cd2ded3/blog_posts/26-03-2020/Corona/covid19.RData"))
data$deaths[is.na(data$deaths)] <- 0
data$date <- as.Date(data$date)
data <- data[order(data$date) , ]
data <- data %>%
dplyr::filter(place_type == "state") %>%
dplyr::group_by(state,date, confirmed,deaths) %>%
select(date, state, confirmed, deaths, estimated_population_2019)
names(data) <- c("date", "state", "confirmed", "deaths", "Pop")
aggSetor <-data%>%filter(date==last(data$date))%>%group_by(state) %>% summarise(quantidade = sum(deaths),
confirmedM = mean(confirmed))
aggSetor$escala <- scale(aggSetor$confirmedM)
#tabPanelSobre <- source("sobre.r")$value
ui <- fluidPage(#theme=shinytheme("united"),
headerPanel(
HTML(
'<div id="stats_header">
Coronavirus in Brazil
<img align="right" alt="fsbmat Logo" src="./img/fsbmat.png" />
</div>'
),
"Coronavirus in Brazil"
),
# App title ----
titlePanel("Coronavirus in Brazil"),
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
uiOutput("codePanel")#,
#tags$p("Autor: Fernando de Souza Bastos - Professor da Universidade Federal de Vicosa - MG")
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Formatted text for caption ----
h3(textOutput("caption")),
# Output: 1 ----
plotOutput("deathsPlot", height = 300,
dblclick = "deathsPlot_dblclick",
brush = brushOpts(
id = "deathsPlot_brush",
resetOnNew = TRUE
)
),
plotOutput("confirmedPlot", height = 300,
dblclick = "confirmedPlot_dblclick",
brush = brushOpts(
id = "confirmedPlot_brush",
resetOnNew = TRUE
)
),
plotOutput("dayPlot", height = 300,
dblclick = "dayPlot_dblclick",
brush = brushOpts(
id = "dayPlot_brush",
resetOnNew = TRUE
)
),
DT::dataTableOutput("text")
)
),
fluidRow(
column(width = 4, class = "well",
h4("Number of Deaths by Covid19 in Brazil"),
plotOutput("plot1", height = 200,
dblclick = "plot1_dblclick",
brush = brushOpts(
id = "plot1_brush",
resetOnNew = TRUE
)
)
),
column(width = 4, class = "well",
h4("Number of Confirmed with Covid19 in Brazil"),
plotOutput("plot2", height = 200,
dblclick = "plot2_dblclick",
brush = brushOpts(
id = "plot2_brush",
resetOnNew = TRUE
)
)
),
column(width = 4, class = "well",
h4("Treemap of deaths and number of confirmed by State"),
plotOutput("plot3", height = 200,
dblclick = "plot3_dblclick",
brush = brushOpts(
id = "plot3_brush",
resetOnNew = TRUE
)
)
)
)#,
#tabPanelSobre()
)
server <- function(input, output) {
filt <- selectInput("codeInput",label ="Escolha um Estado",
choices = as.list(unique(data$state)))
output$codePanel <- renderUI({ filt
})
dataset<-reactive({
subset(data, state == input$codeInput)
})
dataset2<-reactive({
df <- dataset()
teste1 <- dplyr::lag(df$deaths)
teste1[is.na(teste1)] <- 0
teste2 <- dplyr::lag(df$confirmed)
teste2[is.na(teste2)] <- 0
df$teste1 <- teste1
df$teste2 <- teste2
df$deaths_day <- df$deaths-df$teste1
df$confirmed_day <- df$confirmed-df$teste2
df <- df %>% select(1:5,8:9)
return(df)
})
dataset3 <- reactive({
ndeaths <- data %>% group_by(date) %>% summarise(deaths = sum(deaths))
return(ndeaths)
})
dataset4 <- reactive({
nconfirmed <- data %>% group_by(date) %>% summarise(confirmed = sum(confirmed))
return(nconfirmed)
})
# output$caption and output$mpgPlot functions
formulaText <- reactive({
paste("Results Regarding the State of", input$codeInput)
})
# Return the formula text for printing as a caption ----
output$caption <- renderText({
formulaText()
})
output$text<-renderDataTable(dataset())
# # Generate a plot of the requested variable against mpg ----
# # and only exclude outliers if requested
output$deathsPlot <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19/caso"
ggplot2::ggplot(dataset(), aes(x = date, y = deaths)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset()$deaths+20, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=deaths), position=position_dodge(width=0.9), vjust=-0.25) +
labs(x = xlab,
y = "Numbers of Deaths",
title = "Number of deaths by COVID-19",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
output$confirmedPlot <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19/caso"
ggplot2::ggplot(dataset(), aes(x = date, y = confirmed)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset()$confirmed+100, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=confirmed), position=position_dodge(width=0.9), vjust=-0.25) +
labs(x = xlab,
y = "Numbers of Confirmed",
title = "Number of Cases Confirmed with Covid19",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
output$dayPlot <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19/caso"
#Graph with the number of confirmed daily cases
ggplot(dataset2(), aes(x=date, y=confirmed_day))+
geom_line( color="steelblue")+
geom_point() +
geom_text_repel(aes(label=confirmed_day), size = 3)+
xlab("Data") + ylab("Number of confirmed daily cases")+
theme_ipsum() +
theme(axis.text.x=element_text(angle=60, hjust=1))+
scale_x_date(date_breaks = "2 day", date_labels = "%d %b")
})
# -------------------------------------------------------------------
# Single zoomable plot (on left)
#ranges <- reactiveValues(x = date, y = confirmed)
output$plot1 <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19"
ggplot2::ggplot(dataset3(), aes(x = date, y = deaths)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset3()$deaths+20, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=deaths), position=position_dodge(width=0.9), vjust=-0.25) +
labs(x = xlab,
y = "Number of Deaths",
title = " ",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
# -------------------------------------------------------------------
# Linked plots (middle and right)
#ranges2 <- reactiveValues(x = NULL, y = NULL)
output$plot2 <- renderPlot({
xlab <- "Data"
legenda <- "fonte: https://brasil.io/dataset/covid19/caso"
ggplot2::ggplot(dataset4(), aes(x = date, y = confirmed)) +
geom_bar(stat = "identity", alpha = .7, color = "red", fill = "red") +
scale_x_date(date_breaks = "1 day",
date_labels = "%d/%m") +
scale_y_continuous(limits = c(0, max(dataset4()$confirmed+300, na.rm = TRUE) + 3),
expand = c(0, 0)) +
geom_text(aes(label=confirmed), position=position_dodge(width=0.5), vjust=-0.25) +
labs(x = xlab,
y = "Number of Confirmed",
title = " ",
caption = legenda) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 90))
})
output$plot3 <- renderPlot({
treemap(aggSetor, index = "state", vSize = "quantidade", vColor = "escala",
type = "value", palette = "-RdGy", lowerbound.cex.labels = 0.3,
title = "Color related to deaths - Size related to confirmed")
})
}
shinyApp(ui = ui, server = server)
Apparently, the problem is the communication of shiny with the database. The same application using Fleshboard worked perfectly, follow the link for viewing, click here!

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