Rshiny not producing plots after user's input change - r

Roman history fan here, so I have a dataframe with the name of two legions (fifth and tirteenth), their casualties (numerical value), and the morale of the troops (high, medium, low).
I want to know (boxplot) the relationship between morale (x axis) and casualties (y axis), and also subset by legion.
Please notice that this is a toy example. In the real data (no romans) we have several variables for each of the axis, so we ask the user to load the data, and then select which variables he wants to use for each axis.
Here you have a RepEx:
Legion <- c("Fifth", "Fifth", "Fifth","Fifth","Fifth","Tirteenth","Tirteenth", "Tirteenth", "Tirteenth","Tirteenth")
Casualties <- c(13, 34,23,123,0,234,3,67,87,4)
Morale <- c("High", "Medium", "Low","High", "Medium", "Low","High", "Medium", "Low", "High")
romans <- data.frame(Legion, Casualties, Morale)
# Shiny
library(shiny)
library(shinyWidgets)
# Data
library(readxl)
library(dplyr)
# Data
library(effsize)
# Objects and functions
not_sel <- "Not Selected"
main_page <- tabPanel(
title = "Romans",
titlePanel("Romans"),
sidebarLayout(
sidebarPanel(
title = "Inputs",
fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
selectInput("factor", "Select factor", choices = c(not_sel)), uiOutput("leg"), # This group will be the main against the one we will perform the statistics
br(),
actionButton("run_button", "Run Analysis", icon = icon("play"))
),
mainPanel(
tabsetPanel(
tabPanel(
title = "Plot",
plotOutput("plot_1")
)
)
)
)
)
# Function for printing the plots with two different options
# When there is not a selection of the biomarker (we will take into account var_1 and var_2)
# And when there is a selection of the biomarker (we will take into account the three of them)
draw_boxplot <- function(data_input, num_var_1, num_var_2, biomarker){
print(num_var_1)
if(num_var_1 != not_sel & num_var_2 != not_sel & biomarker == not_sel){
ggplot(data = data_input, aes(x = .data[[num_var_1]], y = .data[[num_var_2]])) +
geom_boxplot() +
theme_bw()
}
else if(num_var_1 != not_sel & num_var_2 != not_sel & biomarker != not_sel){
ggplot(data = data_input, aes(x = .data[[num_var_1]], y = .data[[num_var_2]])) +
geom_boxplot() +
theme_bw()
}
}
################# --------------------------------------------------------------
# User interface
################# --------------------------------------------------------------
ui <- navbarPage(
main_page
)
################# --------------------------------------------------------------
# Server
################# --------------------------------------------------------------
server <- function(input, output){
data_input <- reactive({
#req(input$xlsx_input)
#inFile <- input$xlsx_input
#read_excel(inFile$datapath, 1)
romans
})
# We update the choices available for each of the variables
observeEvent(data_input(),{
choices <- c(not_sel, names(data_input()))
updateSelectInput(inputId = "num_var_1", choices = choices)
updateSelectInput(inputId = "num_var_2", choices = choices)
updateSelectInput(inputId = "factor", choices = choices)
})
# Allow user to select the legion
output$leg <- renderUI({
req(input$factor, data_input())
if (input$factor != not_sel) {
b <- unique(data_input()[[input$factor]])
pickerInput(inputId = 'selected_factors',
label = 'Select factors',
choices = c(b[1:length(b)]), selected=b[1], multiple = TRUE,
# choices = c("NONE",b[1:length(b)]), selected="NONE", If we want "NONE" to appear as the first option
# multiple = TRUE, ## if you wish to select multiple factor values; then deselect NONE
options = list(`actions-box` = TRUE)) #options = list(`style` = "btn-warning"))
}
})
num_var_1 <- eventReactive(input$run_button, input$num_var_1)
num_var_2 <- eventReactive(input$run_button, input$num_var_2)
factor <- eventReactive(input$run_button, input$factor)
## Plot
plot_1 <- eventReactive(input$run_button,{
#print(input$selected_factors)
req(input$factor, data_input())
if (!is.null(input$selected_factors)) df <- data_input()[data_input()[[input$factor]] %in% input$selected_factors,]
else df <- data_input()
draw_boxplot(df, num_var_1(), num_var_2(), factor())
})
output$plot_1 <- renderPlot(plot_1())
}
# Connection for the shinyApp
shinyApp(ui = ui, server = server)
This code works fine at the beginning. However, there is a major inconvenience.
As you can see, the user can choose three different panels. In the image attached we would be getting the plot for the morale over the casualties, filtering only for the fifth legion.
enter image description here
However, if after filtering by legion, we deselect this box, then we will be getting an empty plot, as I show in the image.
enter image description here
I don't really know where the issue may be comming from. I thought it may be in 'pickerInput', but that doesn't make much sense. I'm not getting any hints by R either. It is probably here:
req(input$factor, data_input())
if (!is.null(input$selected_factors)) df <- data_input()[data_input()[[input$factor]] %in% input$selected_factors,]
else df <- data_input()
Any help would be appreciated.

You correctly pinned down which part of the code was causing issues. What happens is that first you render the input$selected_factors by selecting an input$factor. The legion that you have selected in this input is now in memory (meaning not NULL) for the first time. Next you change the input$factor to "Not Selected" which hides the input$selected_factors UI, however it doesn't erase it's memory. Even if your UI is hidden your input$selected_factors will remain "fifth" which triggers your if condition. However data_input()[["Not Selected"]] will return an empty table.
My recommendation would be to change the if condition like so:
if (input$factor != "Not Selected") df <- data_input()[data_input()[[input$factor]] %in% input$selected_factors,]
else df <- data_input()

Related

Plotting in Rshiny for newly created variable

I have a dataset with categorical data (let's use Arthritis from vcd package for exmaple purposes).
I want to obtain a barplot where for two variables and colouring by a third one.
In base R this would be:
library(vcd)
library(ggplot2)
data(Arthritis)
tab <- as.data.frame(prop.table(table(Arthritis$Treatment, Arthritis$Improved), margin = 1))
ggplot(tab,aes(x=Var1,y=Freq, fill=Var2, label = round(Freq,3)))+
geom_bar(stat = 'identity')+
geom_text(position = position_stack(vjust=0.5))+
scale_fill_manual(values=c('cyan3','tomato', 'blue'), guide = guide_legend(reverse=TRUE))
Which would give the result:
In my shinyApp the user should be able to choose the variables to plot.
For this I've created:
# Shiny
library(shiny)
library(shinyWidgets)
library(shinyjqui)
library(shinyjs)
# Data
library(readxl)
library(dplyr)
library(vcd)
# Plots
library(ggplot2)
not_sel <- "Not Selected"
ui <- navbarPage(
title = "Plotter",
windowTitle = "Plotter",
tabPanel(
"Plotter",
fluidPage(
fluidRow(
sidebarPanel(
title = "Inputs",
fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
uiOutput("factor"),
br(),
actionButton("run_button", "Run Analysis", icon = icon("play"))
),
# Main panel
mainPanel(
tabsetPanel(
tabPanel(
"Plot",
br(),
plotOutput("plot_1"),
br(),
verbatimTextOutput("data")
)
)
)
)
)
)
)
################# --------------------------------------------------------------
# Server
################# --------------------------------------------------------------
server <- function(input, output){
# Dynamic selection of the data
data_input <- reactive({
#req(input$xlsx_input)
#inFile <- input$xlsx_input
#read_excel(inFile$datapath, 1)
Arthritis
})
# We update the choices available for each of the variables
observeEvent(data_input(),{
choices <- c(not_sel, names(data_input()))
updateSelectInput(inputId = "num_var_1", choices = choices)
updateSelectInput(inputId = "num_var_2", choices = choices)
})
num_var_1 <- eventReactive(input$run_button, input$num_var_1)
num_var_2 <- eventReactive(input$run_button, input$num_var_2)
# data
data_discrete_plot <- reactive({
req(data_input(), input$num_var_1, input$num_var_2)
df <- data_input()
df1 <- as.data.frame(prop.table(table(df[[input$num_var_1]], df[[input$num_var_2]]), margin = 1))
df1
})
# Function for printing the plots
draw_barplot <- function(data_input)
ggplot(data = data_input, aes(x=data_input[1], y=data_input[3], fill=data_input [2], label = round(Freq, 3))) +
geom_bar(stat = "identity") +
scale_fill_manual(guide = guide_legend(reverse=TRUE)) +
ylim(0, 100) +
theme_bw()
## BarPlot -------------------------------------------------------------------
plot_1 <- eventReactive(input$run_button,{
req(data_input())
draw_barplot(data_discrete_plot())
})
output$plot_1 <- renderPlot(plot_1())
output$data <- renderPrint(data_discrete_plot())
}
# Connection for the shinyApp
shinyApp(ui = ui, server = server)
As you can see in the previous RepEx we are obtaining the contingency table, however, I'm finding some trouble when calling for the variables to plot,
as it is a new dataframe with different names for the data.
If I run the code above, I get an error that says: default method not implemented for type 'list'
But if I try to do something like:
data_input[1] <- unlist(data_input[1])
data_input[2] <- unlist(data_input[2])
data_input[3] <- unlist(data_input[3])
The application crashes.
As the columns of your new dataframe have names Var1, Var2 and Freqyou could do:
draw_barplot <- function(data_input) {
ggplot(data = data_input, aes(x = Var1, y = Freq, fill = Var2, label = round(Freq, 3))) +
geom_bar(stat = "identity") +
scale_fill_discrete(guide = guide_legend(reverse = TRUE)) +
ylim(0, 1) +
theme_bw()
}
Additionally I replaced scale_fill_manual by scale_fill_discrete as for the first one you have to provide a vector of color values and set ylim(0, 1) as the proportions in the ´Freq` column are on a 0 to 1 scale.

Obtain contingecy table based on users input - Rshiny

If I want to obtain the fisher test first I need a contigency table. I can do that for the Arthritis package by simply:
library(vcd)
data(Arthritis)
freq <- as.data.frame.matrix(table(Arthritis$Treatment, Arthritis$Improved))
> freq
None Some Marked
Placebo 29 7 7
Treated 13 7 21
So I could do for example, a fisher test for:
Not marked Marked
Placebo 36 7
Treated 20 21
For now, what I want to do in shiny is allow the user to select two categorical variables (Treatment and Improved), and then filter by another one (Gender) and obtain the contingency table.
I could use later this one to obtain the 2x2 frequency. But for now this is what I have:
# Shiny
library(shiny)
library(shinyWidgets)
library(shinyjqui)
# Data
library(vcd)
library(readxl)
library(dplyr)
library(arules) # Discretization
# Plots
library(ggplot2)
not_sel <- "Not Selected"
ui <- fluidPage(
titlePanel("Plotter"),
sidebarPanel(
fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
selectInput("biomarker", "Select Biomarker", choices = c(not_sel)), uiOutput("factor")
),
mainPanel(
tabsetPanel(
tabPanel(
verbatimTextOutput("test")
)
)
)
)
## Server ##
server <- function(input, output){
# Dynamic selection of the data. We allow the user to input the data that they want
data_input <- reactive({
#req(input$xlsx_input)
#inFile <- input$xlsx_input
#read_excel(inFile$datapath, 1)
Arthritis
})
# We update the choices available for each of the variables
observeEvent(data_input(),{
choices <- c(not_sel, names(data_input()))
updateSelectInput(inputId = "num_var_1", choices = choices)
updateSelectInput(inputId = "num_var_2", choices = choices)
updateSelectInput(inputId = "biomarker", choices = choices)
})
num_var_1 <- eventReactive(input$run_button, input$num_var_1)
num_var_2 <- eventReactive(input$run_button, input$num_var_2)
biomarker <- eventReactive(input$run_button, input$biomarker)
output$factor <- renderUI({
req(input$biomarker, data_input())
if (input$biomarker != not_sel) {
b <- unique(data_input()[[input$biomarker]])
pickerInput(inputId = 'selected_factors',
label = 'Select factors',
choices = c(b[1:length(b)]), selected=b[1], multiple = TRUE,
# choices = c("NONE",b[1:length(b)]), selected="NONE", If we want "NONE" to appear as the first option
# multiple = TRUE, ## if you wish to select multiple factor values; then deselect NONE
options = list(`actions-box` = TRUE)) #options = list(`style` = "btn-warning"))
}
})
data_stats_discrete <- reactive({
req(data_input(), input$num_var_1, input$num_var_2, input$biomarker)
# We filter by biomarker in case user selected, otherwise data_input() remains the same
if (input$biomarker != "Not Selected") df <- data_input()[data_input()[[input$biomarker]] %in% input$selected_factors,]
else df <- data_input()
df <- as.data.frame.matrix(table(.data[[input$num_var_1]], .data[[input$num_var_2]]))
df
})
output$test <- renderPrint(data_stats_discrete())
}
shinyApp(ui = ui, server = server)
As you can see in this RepEx, no dataframe is being selected in the data_stats_discrete.
Change
df <- as.data.frame.matrix(table(.data[[input$num_var_1]], .data[[input$num_var_2]]))
to
df <- as.data.frame.matrix(table(df[[input$num_var_1]], df[[input$num_var_2]]))

Having trouble implementing a for and while loop and how to add multiple outputs to be displayed in a tab panel

I am currently creating a RShiny website for a project that models the data for Murder, Assault and Rape in the United States. I've made significant progress so far but I am having trouble with two issues.
I am attempting to implement a for or while loop as part of my project and I'm unable to get the output to be displayed when I run the app. I want the for/while loop to return the states that also shared a Low/Medium/High risk of crime in the form of a text "The other states which have a low/medium/high rate of crime are State1, State2, State3, etc". This is dependent on the state the user selected in the drop down box in the sidebar. I have had no luck in writing the code for this. I understand theres 100% easier ways to do this without a looping structure but my project requires me to use a for or while loop.
How am I able to combine more than one output on a tab panel so that both outputs show. I want there to only be one "How safe is the State?" tab, but whenever I tried to combine both, no outputs would show on the tab.
library(shiny)
library(tidyverse)
library(ggplot2)
# Define UI for application that draws the graphs
ui <- fluidPage(
# Application title
titlePanel("Rate of Crime in United States"),
p("Use the variable selector to refine your search!"),
# Sidebar with widgets adjust server output
sidebarLayout(
sidebarPanel(
checkboxGroupInput("display_var",
"Which Crime/s to Display?",
choices = c("Murder" = "Murder",
"Assault" = "Assault",
"Rape" = "Rape"),
selected = "Murder"
),
sliderInput("bins",
"Number of bins (valid for Histogram chart only):",
min = 5,
max = 10,
value = 7
),
selectInput(
"search", "How safe is this state?", choices = (attributes(USArrests)$row.names), selected = NULL)
),
# Create the tabs
mainPanel(
tabsetPanel(
tabPanel("Bar Plot", plotOutput("barplot")),
tabPanel("Histogram", plotOutput("distPlot")),
tabPanel("How Safe is the State?", textOutput("howsafe")),
tabPanel("How Safe is the State?pt2", textOutput("howsafe2"))
)
)
))
# Define server logic required to draw graphs
server <- function(input, output) {
output$barplot <- renderPlot({
marchoice <- req(input$display_var)
sd <- setdiff(names(USArrests),marchoice)
temp_df <- USArrests
temp_df[,sd] <- 0
counts <- temp_df$Murder + temp_df$Assault + temp_df$Rape
names(counts) <- rownames(temp_df)
barplot(counts,
main="Aggregate Sum of Crime in the United States",
xlab="State",
ylab="Frequency",las=2,col=rgb(0.2,0.4,0.6,0.6))
})
#Transform numeric variables into categorical
CategorisedMAR <- cut(USArrests$Murder + USArrests$Assault + USArrests$Rape, breaks=c(0,150,300,450), labels = c("Low", "Medium", "High"))
names(CategorisedMAR) <- attributes(USArrests)$row.names
st <- reactive(input$search)
output$howsafe <- renderText({
#if-else statement to state risk based on state selection
if (CategorisedMAR[[input$search]] == "Low") {
paste0(st(), " has a low rate of crime")
} else if (CategorisedMAR[[input$search]] == "Medium") {
paste0( st()," has a mid-level rate of crime")
} else if (CategorisedMAR[[input$search]] == "High") {
paste0( st(), " has a high rate of crime")
}
})
output$howsafe2 <- renderText({
for(value in CategorisedMAR) {
if(value == "Low") {
print(value)}
}
})
output$distPlot <- renderPlot({
#Create new data based on the selection
USArrests2 <-
USArrests %>%
select(!!input$display_var) %>%
mutate(cumulative_frequency = rowSums(across(where(is.numeric))))
# Create plot - Show the cumulative frequency
ggplot(USArrests2, aes(cumulative_frequency)) + ggtitle("Histogram of Variable Frequency") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_histogram(bins = input$bins,
fill = rgb(0.2,0.4,0.6,0.6),
colour = "grey30") +
#Create a new label based on what has been selected
xlab(str_c(input$display_var, collapse = " & ")) +
theme_minimal()
})
}
# Run the application
shinyApp(ui = ui, server = server)
This is the code that I have built so far. I have also attached a photo detailing what I am trying to achieve for clarity.
"reprex of what I am trying to achieve
I have spent countless days working on this and any help would be greatly appreciated. Thanks in advance!
Perhaps this will do
library(shiny)
library(tidyverse)
library(ggplot2)
library(DT)
# Define UI for application that draws the graphs
ui <- fluidPage(
# Application title
titlePanel("Rate of Crime in United States"),
p("Use the variable selector to refine your search!"),
# Sidebar with widgets adjust server output
sidebarLayout(
sidebarPanel(
checkboxGroupInput("display_var",
"Which Crime/s to Display?",
choices = c("Murder" = "Murder",
"Assault" = "Assault",
"Rape" = "Rape"),
selected = "Murder"
),
sliderInput("bins",
"Number of bins (valid for Histogram chart only):",
min = 5,
max = 10,
value = 7
),
selectInput( "search", "How safe is this state?", choices = (attributes(USArrests)$row.names), selected = NULL)
),
# Create the tabs
mainPanel(
tabsetPanel(
tabPanel("Bar Plot", plotOutput("barplot")),
tabPanel("Histogram", plotOutput("distPlot")),
tabPanel("How Safe is the State?", textOutput("howsafe"), br(),br(), textOutput("howsafe2"))
)
)
))
# Define server logic required to draw graphs
server <- function(input, output) {
output$barplot <- renderPlot({
marchoice <- req(input$display_var)
sd <- setdiff(names(USArrests),marchoice)
temp_df <- USArrests
temp_df[,sd] <- 0
counts <- temp_df$Murder + temp_df$Assault + temp_df$Rape
names(counts) <- rownames(temp_df)
barplot(counts,
main="Aggregate Sum of Crime in the United States",
xlab="State",
ylab="Frequency",las=2,col=rgb(0.2,0.4,0.6,0.6))
})
#Transform numeric variables into categorical
labels = c("Low", "Medium", "High")
CategorisedMAR <- cut(USArrests$Murder + USArrests$Assault + USArrests$Rape, breaks=c(0,150,300,450), labels = labels)
names(CategorisedMAR) <- attributes(USArrests)$row.names
st <- reactive(input$search)
output$howsafe <- renderText({
#if-else statement to state risk based on state selection
if (CategorisedMAR[[input$search]] == "Low") {
paste0(st(), " has a low rate of crime")
} else if (CategorisedMAR[[input$search]] == "Medium") {
paste0( st()," has a mid-level rate of crime")
} else if (CategorisedMAR[[input$search]] == "High") {
paste0( st(), " has a high rate of crime")
}
})
output$howsafe2 <- renderText({
myvalue = CategorisedMAR[[input$search]]
n <- length(CategorisedMAR)
list_states <- c()
for (i in 1:n){
if (CategorisedMAR[[i]]==myvalue) list_states <- c(list_states,names(CategorisedMAR)[i])
}
mylist <- list_states[! list_states %in% st()]
a <- paste0(c("The following states also had", tolower(labels[myvalue]),"rate of crime:"), collapse=" ")
b <- paste0(paste(c(a,mylist), collapse=", "),".")
aa <- gsub(":,",":", b)
paste(aa)
})
output$distPlot <- renderPlot({
#Create new data based on the selection
USArrests2 <-
USArrests %>%
dplyr::select(input$display_var) %>%
mutate(cumulative_frequency = rowSums(across(where(is.numeric))))
# Create plot - Show the cumulative frequency
ggplot(USArrests2, aes(cumulative_frequency)) + ggtitle("Histogram of Variable Frequency") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_histogram(bins = input$bins,
fill = rgb(0.2,0.4,0.6,0.6),
colour = "grey30") +
#Create a new label based on what has been selected
xlab(str_c(input$display_var, collapse = " & ")) +
theme_minimal()
})
}
# Run the application
shinyApp(ui = ui, server = server)

How to link 2 widget options dynamically in R Shiny?

I'm trying to link the two options Type Selection & Subtype Selection as shown in the image. So I expect if I click Beer under Type Selection, I wouldn't see ICE WINE RED in Subtype Selection as it isn't a subtype of beer. Any idea to link Type Selection & Subtype Selection, so everytime I check some types in Type Selection, I wouldn't see irrelated subtypes in Subtype Selection?
Not sure if you can see bcl dataset, if can't here is the data screenshot:
enter image description here
Here is my code for these 2 functions:
dput(head(bcl))
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("priceInput", "Price", 0, 100, c(25, 40), pre = "$"),
checkboxGroupInput(
"type",
label = "Type Selection:",
choices = c("BEER" = "BEER", "WINE" = "WINE", "SPIRITS" = "SPIRITS", "REFRESHMENT" = "REFRESHMENT"),
selected = c("BEER", "WINE")
),
checkboxInput("filterSubType", "Filter by Subtype", FALSE),
conditionalPanel(
condition = "input.filterSubType",
uiOutput("SubtypeSelectOutput")
),
)
),
mainPanel(
plotOutput("plot"),
br(), br(),
#tableOutput("prices")
DT::dataTableOutput("prices")
)
)
)
server <- function(input, output, session) {
output$SubtypeSelectOutput <- renderUI({
selectInput("subtypeInput", "Subtype",
sort(unique(bcl$Subtype)),
selected = "ALMOND",
multiple = TRUE)
})
output$summaryText <- renderText({
numOptions <- nrow(prices())
if (is.null(numOptions)) {
numOptions <- 0
}
paste0("We found ", numOptions, " options for you")
})
prices <- reactive({
prices <- bcl
if (is.null(input$subtypeInput)) {
return(NULL)
}
prices <- dplyr::filter(prices, Type %in% input$type)
if (input$filterSubType) {
prices <- dplyr::filter(prices, Subtype == input$subtypeInput)
}
prices <- dplyr::filter(prices, Price >= input$priceInput[1],
Price <= input$priceInput[2]
)
if(nrow(prices) == 0) {
return(NULL)
}
prices
})
output$plot <- renderPlot({
if (is.null(prices())) {
return(NULL)
}
ggplot(prices(), aes(Alcohol_Content, fill = Type)) +
geom_histogram(colour = "black") +
theme_classic(20)
})
output$prices <- DT::renderDataTable({
prices()
})
}
shinyApp(ui = ui, server = server)
Update your SubtypeSelectionOutput so that it filters based on the first input.
output$SubtypeSelectOutput <- renderUI({
selectInput("subtypeInput", "Subtype",
choices = bcl %>%
filter(type %in% input$type) %>%
pull(Subtype) %>%
unique() %>% sort(),
selected = "ALMOND",
multiple = TRUE)
})
This may not solve all of your issues with this app, but it will properly link Type Selection & Subtype Selection.

radioButtons() input as a condition to filter a data frame in Shiny, doesn't seem to work

Using the midwest dataframe from ggplot2:
# (in app_ui.r)
poverty_sidebar <- sidebarPanel(
radioButtons(
inputId = "state",
label = "State",
choices = list("IL" = 1, "IN" = 2, "MI" = 3, "OH" = 4, "WI" = 5),
selected = 1
))
poverty_plot <- mainPanel(
plotOutput(
outputId = "poverty_plot"
)
)
# (in app_server.r)
server <- function(input, output) {
output$poverty_plot <- renderPlot({
filtered <- filter(midwest, state == input$state)
plot <- ggplot(data = filtered) +
geom_col(x = county, y = poppovertyknown)
return(plot)
})
Doesn't seem to work, gives me a "Object county not found" error. is doing filter(midwest, state == input$state) the wrong approach? Or does the error lie with my radio buttons?
So the code provided is close, you are making two mistakes
choices does not need to map to numeric
x = county, y = poppovertyknown should be in the aes of geom_col so aes(x = county, y = poppovertyknown)
Hence the final working code would be (Note I have added assignment to ui to make it work in single file with call to shinyApp(ui, server)),
library(shiny)
library(dplyr)
library(ggplot2)
poverty_sidebar <- sidebarPanel(
radioButtons(
inputId = "state",
label = "State",
choices = list("IL", "IN", "MI", "OH", "WI"), # remove mapping to integers
selected = "IL"
))
poverty_plot <- mainPanel(
plotOutput(
outputId = "poverty_plot"
)
)
ui <-
fluidPage(
poverty_sidebar,
poverty_plot
)
# (in app_server.r)
server <- function(input, output) {
output$poverty_plot <- renderPlot({
filtered <- filter(midwest, state == input$state)
print(filtered)
print(input$state)
filtered0 <<- filtered
plot <-
filtered %>%
ggplot() +
geom_col(aes(x = county, y = poppovertyknown)) # used aes()
return(plot)
})
}
shinyApp(ui, server)

Resources