ggplotly works in RStudio console but not rendering in shiny app - r

I am working on created a shiny app and I wrote a function to display a plotly. The function works fine and prints the plot when I run it in the console, but the ggplotly histogram will not render when I run the app. I do not receive any errors when running the function in the console nor when I try to run the app. The graphs just do not show up in the app. Here is the function, which I wrote in a helper file:
# making function to display simulated state-level pv2ps
pv2p_plot <- function(x) {
# filter based on input$state from ui.R
# getting text to specify the predicted pv2p and the chance of victory
pv2p <- sims %>%
drop_na() %>%
filter(state == x) %>%
mutate(d_pv2p = sim_dvotes_2020 / (sim_rvotes_2020 + sim_dvotes_2020),
r_pv2p = 1 - d_pv2p) %>%
summarise(d_pv2p = mean(d_pv2p) * 100,
r_pv2p = mean(r_pv2p) * 100)
win_prob <- sims %>%
mutate(biden_win = ifelse(sim_dvotes_2020 > sim_rvotes_2020, 1, 0)) %>%
group_by(state) %>%
summarise(pct_biden_win = mean(biden_win, na.rm = TRUE)) %>%
filter(pct_biden_win < 1 & pct_biden_win > 0) %>%
mutate(pct_trump_win = 1 - pct_biden_win) %>%
select(state, pct_biden_win, pct_trump_win) %>%
filter(state == x)
pv2p_lab <- paste0("Forecasted Two-Party Popular Vote: ", round(pv2p$d_pv2p, 2), "% for Biden and ", round(pv2p$r_pv2p, 2), "% for Trump")
win_lab <- paste0("Forecasted Probability of Electoral College Victory: ", round(win_prob$pct_biden_win * 100, 2), "% for Biden and ", round(win_prob$pct_trump_win * 100, 2), "% for Trump")
pv_plot <- sims %>%
filter(state == x) %>%
mutate(Democrat = sim_dvotes_2020 / (sim_dvotes_2020 + sim_rvotes_2020),
Republican = 1 - Democrat) %>%
pivot_longer(cols = c(Democrat, Republican), names_to = "party") %>%
ggplot(aes(value, fill = party)) +
geom_histogram(aes(y = after_stat(count / sum(count)),
text = paste0("Probability: ", round(after_stat(count / sum(count)), 5))), bins = 1000, alpha = 0.5, position = "identity") +
scale_fill_manual(breaks = c("Democrat", "Republican"),
labels = c("Biden", "Trump"),
values = c(muted("blue"), "red3")) +
labs(title = paste("Simulated Two-Party Popular Vote \nin", x),
x = "Predicted Share of the Two-Party Popular Vote",
y = "Probability",
fill = "Candidate",
subtitle = pv2p_lab) +
theme_hodp()
print(ggplotly(pv_plot, tooltip = "text"))
}
And this is my UI & server code from the app:
# loaded libraries, read in data, and created functions in other file to keep
# this script nice and clean
source("helper.R")
ui <- navbarPage(
# Application title
"Presidential Forecast in Retrospect",
tabPanel(
"About",
includeHTML(file.path("pages/about.html"))
),
navbarMenu("Forecast Simulations",
tabPanel("State-by-State Two-Party Popular Vote",
fluidPage(theme = "bootstrap.css",
tabsetPanel(
tabPanel("Estimated Vote Share",
selectInput("state",
"State:",
sims %>% pull(state) %>% unique() %>% sort()),
plotlyOutput("statesimPlotly")),
tabPanel("Probability of Victory",
selectInput("state_type",
"State Category:",
types %>% pull(type) %>% unique()),
plotlyOutput("statevictoryPlotly")
)
)
)
),
tabPanel("Predicted Vote Margin Map",
# creating this page to show the win margin
includeHTML(file.path("pages/margin_maps.html"))
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
output$statesimPlotly <- renderPlotly({
# calling function that I defined at the top of the app
pv2p_plot(input$state)
})
output$statevictoryPlotly <- renderPlotly(
# calling function from helper to make this plot
state_win_probs(input$state_type)
)
}
# Run the application
shinyApp(ui = ui, server = server)
As I said above, the function works fine in my console. Most people who have had issues with this online are not using the proper output/render functions (e.g. using renderPlot instead of renderPlotly), but I am not seeing what is wrong with my code. Thanks in advance!

Related

Map plot won't show in Shiny app, no error shown

I am fairly new to R Shiny and I've been working on an app with an interactive world map which shows each country's performance at the Olympics, using scale_fill_gradient. The app user gets to choose the performance indicator (total medals won, gold only, weighted score) and the year (1996 to 2020).
The problem is there's no more error shown, but the plot doesn't show either! I have tried to run the functions as normal R script and they worked fine there (the plot showed up in the viewer pane). I found a few others who have also run into problems with no plot or error showing, but their cases are different to mine (e.g. mismatch in Output and Render) so the resolutions don't work for me.
It's a massive dataset so I've not included it here, I thought I might check first if the error could be spotted from the code alone. Here's what I've used:
function
world_map1 <- function(WorldMap, year, performance) {
w_plot1 <- WorldMap %>%
filter(Year == year) %>%
select("long", "lat", "group", "region", all_of(performance)) %>%
replace(is.na(.), 0) %>%
rename_at(performance, ~ "Value") %>%
mutate(Value = as.numeric(as.character(Value)))
tooltip_css <- "background-color:#2E2E2E; font-family: Calibri; color:#F2F2F2;"
w_g1 <- ggplot() +
geom_polygon_interactive(data = subset(w_plot1, lat >= -60 & lat <= 90),
aes(x = long,
y = lat,
fill = Value,
group = group,
tooltip = sprintf("%s<br/>%s", region, Value))) +
scale_fill_gradient(name = "Medals /Score",
low = "lightgoldenrodyellow",
high = "goldenrod1",
na.value = "white")
return(
girafe(
ggobj = w_g1,
options = list(
opts_tooltip(
css = tooltip_css
)
))
)
}
ui
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
radioButtons(inputId = "performance", label = "Performance measure:",
choices = c("Total medals won" = "Total",
"Gold medals won" = "Gold",
"Weighted points system" = "Weighted"
)),
width = 3
),
mainPanel(
girafeOutput("mapPlot1"),
sliderInput(inputId = "year", label = "Year:",
min = 1996, max = 2020, step = 4, value = 1996, ticks = FALSE, sep = ""
)
)
)
)
server
server <- function(input, output) {
output$mapPlot1 <- renderGirafe({
ggiraph(code = print(world_map1(WorldMap, input$year, input$performance)))
}
)
}
run app
shinyApp(ui = ui, server = server)
Any help or insights appreciated!
I thought it was my theme() block so I removed that, as shown above. Also checked other cases on no plot showing here, couldn't find one with fixes that would work for me because it seems the underlying problem is different?

How to fix "Error in UseMethod("select") : no applicable method for 'select' applied to an object of class "function""?

I am trying to create an interactive map in R with the covid-19 prison data in the U.S. dataset given (after tidying), trying to plot a map of different variables (ex. staff cases, prisoner cases, prisoner deaths) and having a slider for the different months out of 15 months.
A sample of my dataset for one of the 50 states is seen here:
Sample set
Below is my code so far, and I am quite stuck on everything from asterisk divider and below. I keep getting an error message saying that Error in UseMethod("select") : no applicable method for 'select' applied to an object of class "function" when I try to use select within the created function STATE, though I don't know if that function is correct at all with what I am trying to do.
Any help would mean the world.
if (!require(Lahman)) install.packages('Lahman')
if (!require(plotly)) install.packages('plotly')
if (!require(shiny)) install.packages('shiny')
if (!require(tidyverse)) install.packages('tidyverse')
library(albersusa)
library(shiny)
library(Lahman)
library(tidyverse)
library(plotly)
my_map_theme <- function(){
theme(panel.background=element_blank(),
axis.text=element_blank(),
axis.ticks=element_blank(),
axis.title=element_blank())
}
# Load Dataset from CSV, Dataset saved and tidied from Github
cpc <- read_csv("cpc.csv")
us_states <- usa_sf("laea")
cpc_tidy <- cpc %>%
select(name,
staff_tests,
total_staff_cases,
total_staff_deaths,
prisoner_tests,
total_prisoner_cases,
total_prisoner_deaths,
as_of_date,
year,
Month) %>%
arrange(name)
cpc_tidy_f <- cpc_tidy %>%
group_by(name, year, Month) %>%
summarise(across(everything(), last))
cpc_sel <- cpc_tidy_f
cpc_sel$merge <- as.character.Date(paste(cpc_sel$year, cpc_sel$Month, sep = "-"))
TEST_JOIN <- left_join(us_states, cpc_sel, c=("name"="name"))
*****************************************************
STATE <- function(stat, Month = 11, data = cpc_sel) {
my_stat <- enquo(stat)
data %>%
select(name, merge, plot_stat = !!my_stat) %>%
# filter(yearID >= 1901) %>%
group_by(name, merge) %>%
summarize(plot_stat = sum(plot_stat)) %>%
ungroup() %>%
group_by(merge) %>%
top_n(n_players, wt = plot_stat)
}
COVID_Plot <- function(data) {
p <- TEST_JOIN %>%
mutate(text_y = paste("<b>",name,
"</b>\n Total Variable:",
signif(plot_stat,3),
"in 2020-2021")) %>%
ggplot(cpc_sel) +
geom_sf(aes(fill=plot_stat, text=text_y), color="black") +
scale_fill_continuous("Total of Variable:", low="#EEFBE5", high="#082573") +
my_map_theme()
ggplotly(p, tooltip = "text") %>%
style(hoveron = "fill")
}
# Define user interface (UI) for our app
ui <- fluidPage(
# Application title
titlePanel("Covid-19 Data in prisons across the United States"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("my_stat",
"Statistic to Plot:",
choices = list("Total Staff Cases" = "tota_staff_cases",
"Total Prisoner Cases" = "tota_prisoner_cases"
),
selected = "tota_prisoner_cases"),
sliderInput("n",
"Months:",
min = 1,
max = 15,
value = 11)),
# Show our plot
mainPanel(
h3(textOutput("TitleText")),
h5(textOutput("SubtitleText")),
h5("Graphs for U.S. prison covid data not implemented yet."),
plotlyOutput("statPlot"),
h5("Data source:",
tags$a(href="https://github.com/themarshallproject/COVID_prison_data/blob/master/data/covid_prison_cases.csv/",
"The Marshall Project Covid Prison Data")),
h5("Graphs inspired by plots in The Marshall Project article, ",
tags$a(href="https://www.themarshallproject.org/2020/05/01/a-state-by-state-look-at-coronavirus-in-prisons/",
"\"A State-By-State Look at 15 Months of Coronavirus in Prisons\""))
)
)
)
# Define server logic required to create the graph
server <- function(input, output) {
output$TitleText <- renderText(paste(input$my_stat, "Records over time"))
output$SubtitleText <- renderText(paste("Graph shows", input$n,
"for each state across the U.S."))
output$statPlot <- renderPlotly({
COVID_Plot(STATE(stat = input$my_stat, Month = input$n,
data = cpc_sel))
})
}
# Run the application
shinyApp(ui = ui, server = server)

"Error in match: 'match' requires vector arguments in R Shiny

I am trying to create a dashboard using R Shiny from NYC Tree Census 2015. The dashboard should look something like in the picture here > Dashboard in Shiny Picture
My code is mentioned below:
library(shiny)
library(tidyverse)
library(ggplot2)
my_data <- read.csv("/Users/abhikpaul/Documents/Documents/Github/Fiverr/2015_Street_Tree_Census_-_Tree_Data.csv")
ui <- fluidPage(
titlePanel("The Dashboard of Tree Distribution in New York City"),
sidebarLayout(
sidebarPanel(
# Description ----
helpText("In this page you can get information about the tree distribution, status, health conditions, and species rank in New York City. Please choose the borough that you want to check. It may take 10 seconds for the graphics to load. Thank you for your patience!"),
#Input: Check boxes for Boroughs ----
checkboxGroupInput("checkboxInput",
label = "Borough",
choices = list("Bronx",
"Brooklyn",
"Manhattan",
"Queens",
"Staten Island"),
selected = "Bronx"),
),
# Main panel for displaying outputs ----
mainPanel(
# Tabs panel for displaying outputs ----
tabsetPanel(type = "tabs",
#Output: About ----
tabPanel("About",
h3("About this dataset", align = "left"),
p("The dataset displays the information of trees (including health, status, species, etc.) within the five boroughs in New York City. The dataset is organized by NYC parks & Recreation and partner organizations."),
h3("How to make NYC an urban forest?", align = "left"),
p("As a group, we are concerned about planting tree and green environments. Therefore, we will focus on identifying the locations that require more taking care of trees, the top species that have the most number of trees in each borough, the health conditions of those species, and the distribution of trees in each borough."),
HTML("<p>For more information, visit: <a href='https://data.cityofnewyork.us/Environment/2015-Street-Tree-Census-Tree-Data/uvpi-gqnh'>2015 NYC Tree Census</a></p>")
),
#Output: Status ----
tabPanel("Status", plotOutput(outputId = "statusplot")),
)
)
)
)
)
server <- function(input, output) {
my_data <- as_tibble(my_data)
my_data <- my_data[my_data$borough %in% checkboxInput,]
my_data <- data.frame(table(my_data$borough,my_data$status))
my_data <- my_data[apply(my_data!=0, 1, all),]
my_data <- my_data %>%
group_by(Var1) %>%
mutate(Percent = (Freq/sum(Freq) * 100))
output$statusplot <- renderPlot({
ggplot(my_data, aes(fill = Var2, y = Percent, x = Var1)) +
geom_bar(position = "dodge", stat = "identity")
})
}
shinyApp(ui = ui, server = server)
However, while running the app, I am getting an error as mentioned below
Warning: Error in match: 'match' requires vector arguments 50: %in% 47: server [/Users/abhikpaul/Documents/Documents/GitHub/Fiverr/my_app.R#90]Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments
Can someone help me fix this issue as I am a newbie in R Shiny?
Try this
server <- function(input, output) {
output$statusplot <- renderPlot({
my_data <- as_tibble(my_data)
my_data <- my_data[my_data$borough %in% input$checkboxInput,]
my_data <- data.frame(table(my_data$borough,my_data$status))
my_data <- my_data[apply(my_data!=0, 1, all),]
my_data <- my_data %>%
group_by(Var1) %>%
mutate(Percent = (Freq/sum(Freq) * 100))
ggplot(my_data, aes(fill = Var2, y = Percent, x = Var1)) +
geom_bar(position = "dodge", stat = "identity")
})
}

Shiny App: Error in filter_impl: Result must have length 4090, not 0

Trying to run a shiny app, but keep getting the error: Error in filter_impl: Result must have length 4090, not 0
I've tried:
debugging by removing individual filters to try isolate the issue.
using dplyr::filter to force dplr's filter
ensured all filters are in a reactive function
checked whether it was an issue of sharing inputs between ui.R and server.r
checked whether it is caused by a previous df transformation.
Spent about 3 hours trying to find the cause, with no success.
Can you please help?
Server.R
rm(list = ls())
library(shiny)
library(tidyverse)
library(shiny)
library(ggplot2)
library(singer)
library(ggvis)
library(dplyr)
# Set Up DataFrames
data(package = "singer")
data(singer_locations)
sdf <- singer_locations %>% filter(year != 0) # filter out songs with missing years for simplicity
sdf %>% skim() %>% kable() # Check to see missing and incomplete values
sdf <- sdf %>% filter(complete.cases(.)) # filter out songs with missing observations for simplicity
sdf %>% skim() %>% kable() # Check to see if missing and incomplete values have been ignored
sdf <- sdf %>% select(
track_id, title, song_id, release, artist_id, artist_name, year, duration,
artist_hotttnesss, artist_familiarity, name, city, longitude, latitude
)
# add new columns with rounded data (for nicer graphs later)
sdf$latitude_rounded <- round(sdf$latitude, 0)
sdf$longitude_rounded <- round(sdf$longitude, 0)
sdf$duration_rounded <- round(sdf$duration, 0)
# Add song_popularity & very_popular_song columns
pops <- sdf$artist_hotttnesss + sdf$artist_familiarity
sdf$artist_popularity <- round(pops, 0)
sdf$very_popular_song <- round(sdf$artist_popularity)
sdf$very_popular_song[sdf$very_popular_song < 1] <- "No"
sdf$very_popular_song[sdf$very_popular_song >= 1] <- "Yes"
# Select() relevant variables so they can be passed into server below (without having to use df[,"VAR"])
songs_list <- sdf %>% select(
track_id, title, song_id, release, artist_id, artist_name, year, duration_rounded, duration,
artist_hotttnesss, artist_familiarity, name, city, latitude_rounded, longitude_rounded, longitude,
latitude, artist_popularity, very_popular_song
)
#axis_variables <- reactive({
axis_variables <- c(
"Length of Song (Seconds)" = "duration_rounded",
"Rating" = "artist_hotttnesss",
"Rating" = "artist_familiarity",
"Year" = "year",
"Popularity Rating" = "artist_popularity"
)
################################### SHINY SERVER #########################################
function(input, output) {
songs <- reactive({ # Create Reactive Filtering Component
duration_s <- input$duration_s
artist_hotttnesss_s <- input$artist_hotttnesss_s
artist_familiarity_s <- input$artist_familiarity_s
latitude_s <- input$latitude_s
longitude_s <- input$longitude_s
year_s <- input$year_s
artist_popularity_s <- input$artist_popularity_s
# Apply filters
songs_df <- songs_list %>%
dplyr::filter(
duration_rounded >= duration_s,
artist_hotttnesss >= artist_hotttnesss_s,
artist_familiarity >= artist_familiarity_s,
latitude_rounded >= latitude_s,
longitude_rounded >= longitude_s,
year >= year_s,
artist_popularity >= artist_popularity_s
) %>%
arrange(duration_rounded)
# filter by city option
if (input$city_in != "All") {
city_in_temp <- paste0("%", input$city_in, "%")
songs_df <- songs_df %>% dplyr::filter(songs_df$city %like% city_in_temp)
}
# filter by artist_name option
if (input$artist_name_in != "" && !is.null(input$artist_name_in)) {
artist_name_temp <- paste0("%", input$artist_name_in, "%")
songs_df <- songs_df %>% dplyr::filter(songs_df$artist_name %like% artist_name_temp)
}
songs_df <- as.data.frame(songs_df)
songs_df # return df
})
# search fuction
song_search <- function(s) {
if (is.null(s)) return(NULL)
if (is.null(s$track_id)) return(NULL)
# Isolate the given ID
songs_df <- isolate(songs())
temp_song <- songs_df[songs_df$track_id == s$track_id, ]
paste0("<b>", temp_song$artist_name, "</b><br>",
temp_song$year, "<br>",
"popularity ", format(temp_song$artist_popularity, big.mark = ",", scientific = FALSE)
)
}
# A reactive expression with the ggvis plot
vis <- reactive({
# setting variablex & variabley (input names are type str)
variablex <- prop("x", as.symbol(input$variablex))
variabley <- prop("y", as.symbol(input$variabley))
# Lables for axes
xvar_name <- names(axis_variables)[axis_variables == input$variablex]
yvar_name <- names(axis_variables)[axis_variables == input$variabley]
songs %>%
ggvis(x = variablex, y = variabley) %>%
layer_points(size := 50, size.hover := 200,
fillOpacity := 0.2, fillOpacity.hover := 0.5,
stroke = ~artist_popularity, key := ~artist_name) %>%
add_tooltip(song_search, "hover") %>%
add_axis("x", title = xvar_name) %>%
add_axis("y", title = yvar_name) %>%
add_legend("stroke", title = "Very Popular", values = c("Yes", "No")) %>%
scale_nominal("stroke", domain = c("Yes", "No"),
range = c("orange", "#aaa")) %>%
set_options(width = 500, height = 500)
})
vis %>% bind_shiny("plot1")
output$songs_selected <- renderText({ nrow(songs()) })
}
Ui.R
rm(list = ls())
library(tidyverse)
library(shiny)
library(ggplot2)
library(singer)
library(ggvis)
library(dplyr)
#axis_variables <- reactive({
axis_variables <- c(
"Length of Song (Seconds)" = "duration_rounded",
"Hotness Rating" = "artist_hotttnesss",
"Familiarity Rating" = "artist_familiarity",
"Year" = "year",
"Popularity Rating" = "artist_popularity"
)
# Define UI for application that draws a histogram
shinyUI(fluidPage(
shinythemes::themeSelector(),
titlePanel("Artist & Song Data"),
fluidRow(
column(3,
wellPanel(
h4("Filter By"),
# Slider Options for Data Exploration
sliderInput("duration_s", "Minimum duration of song (seconds)", 10, 500, 100, step = 10),
sliderInput("year_s", "Year released", 1900, 2018, value = c(1980, 2018)),
sliderInput("artist_hotttnesss_s", "Ranking / 10 for popularity", 0, 2, 0, step = 0.1),
sliderInput("artist_familiarity_s", "Ranking / 10 for familiarity", 0, 2, 0, step = 0.1),
sliderInput("artist_popularity", "Ranking / 10 for familiarity", 0, 2, 0, step = 0.1),
# Filter by custom input condition
textInput("city_in", "Name of the city"),
textInput("artist_name_in", "Artist's name contains (e.g Pink f)")
),
wellPanel(
selectInput("variablex", "X-axis", axis_variables, selected = "year"),
selectInput("variabley", "Y-axis", axis_variables, selected = "duration_rounded")
)
),
column(9,
ggvisOutput("plot1"),
wellPanel(
span("Degrees of Freedom",
textOutput("songs_selected")
)
)
)
)
It looks like you are filtering using data created by input$XXX. Try to put req(input$XXX, req(input$YYY, ...) at the beginning of your reactive element(s).
Also read this tweet about starting with rm(list = ls()).

Shiny: Conditional Panel and Conditional List of checkboxGroupInput

I want to create a shiny app for plotting the most recent pollstR charts of US presidential primaries. Users should be able to select a Party (Dem or Rep), the Candidates and the states, where the primaries (or Caucusus) took place.
I have three problems:
Based on the selected party (Dem or Rep), users should get the next checkboxGroupInput, where only the Democratic or Republican candidates appear. I try to solved that with a conditionalPanel. However, I cannot use "Candidate" twice as a name for the Widget (later in the server.R I need input$Candidate). How can I solve that?
Based on the selected party (again Dem or Rep), users should get a list of all states, where primaries and caucusus took place up to now. At the moment, I am listing all US states, which I defined before (and hence I get errors, if I want to plot the results of states, where no polls are available). Is there a way to get the list of states from the dataset, which is generated in the server.R part (it is called polls$state there, but I cannot use it, because the ui.R does not now "polls").
I plot the results as bar-charts with ggplot and the facet_wrap function (with two columns). The more states I choose, the smaller the plots get. Is there a way to set the height of the plots and insert a vertical scrollbar in the main panel?
Here is the code for the UI:
shinyUI(fluidPage(
titlePanel("2016 Presidential primaries"),
sidebarLayout(position = "right",
sidebarPanel(
helpText("Choose between Democratic (Dem) and Republican (Rep)
Primaries and Caucuses:"),
selectInput("party",
label = "Dem or Rep?",
choices = c("Dem", "Rep",
selected = "Dem")),
conditionalPanel(
condition = "input.party == 'Dem'",
checkboxGroupInput("Candidate", label = h4("Democratic Candidates"),
choices = list("Clinton" = "Clinton", "Sanders" = "Sanders"),
selected = NULL)),
conditionalPanel(
condition = "input.party == 'Rep'",
checkboxGroupInput("Candidate", label = h4("Republican Candidates"),
choices = list("Bush" = "Bush", "Carson" = "Carson", "Christie" = "Christie",
"Cruz" = "Cruz", "Kasich" = "Kasich", "Rubio" = "Rubio",
"Trump" = "Trump"),
selected = NULL)),
checkboxGroupInput("state",
label = "Select State",
choices = states,
inline = TRUE,
selected = NULL)
),
mainPanel(
tabsetPanel(
tabPanel("Plot", plotOutput("plot")),
tabPanel("Table", tableOutput("table"))
)
)
)
))
And here the code for the server.R:
### getting and cleaning the data for the shiny app-----------------------------
# load pollstR-package to get Huffpost opinion polls
require(pollstR)
# load dplyr and tidyr for data wrangling
require(dplyr)
require(tidyr)
# load ggplot2 for plotting
require(ggplot2)
# download 2016 GOP presidential primaries
repPoll <- pollstr_charts(topic='2016-president-gop-primary', showall = TRUE)
# extract and combine columns needed
choice <- repPoll$estimates$choice
value <- repPoll$estimates$value
election <- repPoll$estimates$slug
party <- repPoll$estimates$party
rep.df <- data_frame(election, choice, value, party)
# extract and combine slug and state info to add list of US state abbreviations
election <- repPoll$charts$slug
state <- repPoll$charts$state
r.stateAbb <- data_frame(election, state)
# join both data frames based on slug
rep.df <- left_join(rep.df, r.stateAbb, by = "election")
## download 2016 DEM presidential primaries
demPoll <- pollstr_charts(topic='2016-president-dem-primary', showall = TRUE)
# extract and combine columns needed
choice <- demPoll$estimates$choice
value <- demPoll$estimates$value
election <- demPoll$estimates$slug
party <- demPoll$estimates$party
dem.df <- data_frame(election, choice, value, party)
# extract and combine slug and state info to add list of US state abbreviations
election <- demPoll$charts$slug
state <- demPoll$charts$state
d.stateAbb <- data_frame(election, state)
# join both data frames based on slug
dem.df <- left_join(dem.df, d.stateAbb, by = "election")
# combine dem and rep datasets
polls <- bind_rows(dem.df, rep.df)
polls$party <- as.factor(polls$party)
polls$state <- as.factor(polls$state)
polls$choice <- as.factor(polls$choice)
shinyServer(function(input, output) {
df <- reactive({
polls %>% filter(party %in% input$party) %>% filter(choice %in% input$Candidate) %>%
filter(state %in% input$state)
})
# generate figures
output$plot <- renderPlot({
validate(
need(input$party, "Please select a party"),
need(input$Candidate, "Please choose at least one candidate"),
need(input$state, "Please select at least one state")
)
p <- ggplot(df())
p <- p + geom_bar(aes(x = choice, weight = value, fill = choice),
position = "dodge", width=.5)
# colorize bars based on parties
if (input$party == "Dem")
p <- p + scale_fill_brewer(palette = "Blues", direction = -1)
if (input$party == "Rep")
p <- p + scale_fill_brewer(palette = "Reds", direction = -1)
# add hlines for waffle-design
p <- p + geom_hline(yintercept=seq(0, 100, by = 10), col = 'white') +
geom_text(aes(label = value, x = choice, y = value + 1), position = position_dodge(width=0.9), vjust=-0.25) +
# facet display
facet_wrap( ~ state, ncol = 2) +
# scale of y-axis
ylim(0, 100) +
# delete labels of x- and y-axis
xlab("") + ylab("") +
# blank background and now grids and legend
theme(panel.grid.major.x = element_blank(), panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.background = element_blank(), legend.position = "none")
print(p)
}
)
# Generate a table view of the data
output$table <- renderTable({
polls %>% filter(party %in% input$party) %>% filter(choice %in% input$Candidate) %>%
filter(state %in% input$state)
})
}
)
Here is the solution for problem 1 and 2:
In ui.R, replace conditionalPanel and checkboxGroupInput with
uiOutput('candidates'),
uiOutput('states')
In server.R, add the following code before df <- reactive({..... Note that you need to change some of your input$Candidate code to lower case.
observeEvent(input$party, {
output$candidates <- renderUI({
checkboxGroupInput(
"candidate",
ifelse(input$party == 'Dem', "Democratic Candidates", "Republican Candidates"),
as.vector(unique(filter(polls,party==input$party)$choice))
)
})
})
observeEvent(input$candidate, {
output$states <- renderUI({
states_list <- as.vector(unique(filter(polls, party==input$party & choice==input$candidate)$state))
checkboxGroupInput(
"state",
"Select state",
# Excluding national surveys
states_list[states_list!="US"]
)
})
})
For problem 3, change the df reactive to observe, and then set plot height depending on how many states selected. Also change this line p <- ggplot(df)
observe({
df <- polls %>% filter(party %in% input$party) %>% filter(choice %in% input$candidate) %>% filter(state %in% input$state)
height <- ceiling(length(input$state) / 2) * 200
output$plot <- renderPlot({
#Your plot code
}, height=height)
})

Resources