Reputation: 129
I am getting errors in my if statements with checkBoxGroupInput in my R Shiny App. Please ignore the fact that all the plots I want to output are the same - I will change this later.
Here is the code:
library(shiny)
library(leaflet)
library(DT)
library(ggplot2)
library(dplyr)
r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()
plotdata <- read.csv("C:/Users/Anatoly/Documents/Collatz/RenameLater/RenameLater/MapsAndSuch/RShinyCoral.csv")
colnames(plotdata) <- c("Year1", "RLIMona", "Year2", "RLICatalina", "Year3", "RLILaParguera1998", "Year4", "RLILAPARGUERA2004")
parguera <- read.csv("C:/Users/Anatoly/Documents/Collatz/RenameLater/RenameLater/MapsAndSuch/RShinyCoral.csv")
parguera <- select(parguera, 5:8)
colnames(parguera) <- c("Year", "1998 Expedition", "Year", "2004 Expedition")
monaisland <- read.csv("C:/Users/Anatoly/Documents/Collatz/RenameLater/RenameLater/MapsAndSuch/RShinyCoral.csv")
monaisland <- select(monaisland, 1:2)
colnames(monaisland) <- c("Year", "Mona Island RLI")
islacatalina <- read.csv("C:/Users/Anatoly/Documents/Collatz/RenameLater/RenameLater/MapsAndSuch/RShinyCoral.csv")
islacatalina <- select(islacatalina, 3:4)
colnames(islacatalina) <- c("Year", "Isla Catalina RLI")
ui <- fluidPage(
titlePanel("NOAA Coral Luminescence Data (RLI, 5-year Running Average)"),
leafletOutput("mymap"),
p(),
fluidRow(
column(3, actionButton("laparguera", "La Parguera Data"),
actionButton("mona", "Mona Island Data"),
actionButton("isla", "Isla Catalina Data"))),
fluidRow(
column(3, offset = 5, actionButton("visualize", "Visualize Data"))),
fluidRow(
column(7, offset = 5, checkboxGroupInput("checkbox", "Add to plot",
c("La Parguera" = "La Parguera", "Mona Island" = "Mona Island", "Isla Catalina" = "Isla Catalina"))),
fluidRow(
DT::dataTableOutput('tbl'),
plotOutput("plot1")
)
)
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles() %>%
addMarkers(lat = 17.95, lng = - 67.05, popup = "La Parguera ") %>%
addMarkers(lat = 18.00, lng = -67.50, popup = "Mona Island") %>%
addMarkers(lat = 18.2, lng = -69.00, popup = "Isla Catalina")
})
observeEvent(input$laparguera, {
output$tbl <- DT::renderDataTable(DT::datatable(parguera, options = list(pagelength = 25)))
})
observeEvent(input$mona, {
output$tbl <- DT::renderDataTable(DT::datatable(monaisland, options = list(pagelength = 25)))
})
observeEvent(input$isla, {
output$tbl <- DT::renderDataTable(DT::datatable(islacatalina, options = list(pagelength = 25)))
})
observeEvent(input$visualize, {
output$plot1 <- renderPlot(
{
if (input$checkbox == c("Mona Island"))
{
gplot <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot)
}
else if(input$checkbox == c("La Parguera", "Mona Island"))
{
gplot2 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot2)
}
else if (input$checkbox == c("La Parguera", "Mona Island", "Isla Catalina"))
{
gplot3 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot3)
}
else if(input$checkbox == c("Mona Island", "Isla Catalina"))
{
gplot4 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot4)
}
else if(input$checkbox == c("La Parguera", "Isla Catalina"))
{
gplot5 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot5)
}
else if(input$checkbox == c("Isla Catalina"))
{
gplot6 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot6)
}
else if(input$checkbox == c("La Parguera"))
{
gplot7 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot7)
}
else if(is.null(input$checkbox))
{
print("Check some damn boxes")
}
})
})
}
shinyApp(ui, server)
I think the problem is, I don't really know what type of input I get from the checkbox. I assumed it was a character vector, but I'm not sure, and the documentation wasn't very helpful (at least for me).
Thanks.
Upvotes: 0
Views: 1352
Reputation: 2611
Please note that I normally prefer to post some working code, but this time I couldn't because I do not have access to your data: my apologies.
Some consideration:
checkboxGroupInput
you just need a plain character vector, i.e. you don't need to name columns etc.
input$checkbox
is another character vector checkboxGroupInput
is designed to allow more than one input at a time, so the output can be a vector with more than one entry.if
I normally prefer to use switch (edited: but it works only for 1 element comparisons), as it makes the code more readable (but it is personal taste).In your case, to decrease the risk of errors (often due to a reactive calling the code more than once), in output$plot1
you could use
cols <- isolate(input$checkbox)
Also, rather than the existing code for output$plot1
, you could eliminate an observeEvent
in this way:
# snippet - not tested
#
# observeEvent(input$visualize, { # this is redundant
output$plot1 <- renderPlot(
if(is.null(input$visualize)) return() # this is all you need to make output$plot1 reactive to input$visualize
cols <- isolate(input$checkbox)
if (cols == c("Mona Island"))
{
The proliferation of nested reactive elements is never a good thing in shiny (among other things it causes unnecessarily the code to run repeatedly, burning CPU cycles).
If useful, I recently posted on SO a code example with checkboxGroupInput
. See it here
If you still get errors I would suggest to post the links to allow me or others to get your data and post back a working example.
Working Example and "new comments"
library(shiny)
library(leaflet)
library(DT)
library(ggplot2)
library(dplyr)
r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()
plotdata <- read.csv("RShinyCoral.csv")
colnames(plotdata) <- c("Year1", "RLIMona", "Year2", "RLICatalina", "Year3", "RLILaParguera1998", "Year4", "RLILAPARGUERA2004")
parguera <- read.csv("RShinyCoral.csv")
parguera <- select(parguera, 5:8)
colnames(parguera) <- c("Year", "1998 Expedition", "Year", "2004 Expedition")
monaisland <- read.csv("RShinyCoral.csv")
monaisland <- select(monaisland, 1:2)
colnames(monaisland) <- c("Year", "Mona Island RLI")
islacatalina <- read.csv("RShinyCoral.csv")
islacatalina <- select(islacatalina, 3:4)
colnames(islacatalina) <- c("Year", "Isla Catalina RLI")
ui <- fluidPage(
titlePanel("NOAA Coral Luminescence Data (RLI, 5-year Running Average)"),
leafletOutput("mymap"),
p(),
fluidRow(
column(3, actionButton("laparguera", "La Parguera Data"),
actionButton("mona", "Mona Island Data"),
actionButton("isla", "Isla Catalina Data")),
column(9,
actionButton("visualize", "Add to Plot"),
checkboxGroupInput("checkbox", label = NULL,
c("La Parguera", "Mona Island", "Isla Catalina"))
)),
fluidRow(column(6, DT::dataTableOutput('tbl')),
column(6, plotOutput("plot1"))
)
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles() %>%
addMarkers(lat = 17.95, lng = - 67.05, popup = "La Parguera ") %>%
addMarkers(lat = 18.00, lng = -67.50, popup = "Mona Island") %>%
addMarkers(lat = 18.2, lng = -69.00, popup = "Isla Catalina")
})
observeEvent(input$laparguera, {
output$tbl <- DT::renderDataTable(DT::datatable(parguera, options = list(pagelength = 25)))
})
observeEvent(input$mona, {
output$tbl <- DT::renderDataTable(DT::datatable(monaisland, options = list(pagelength = 25)))
})
observeEvent(input$isla, {
output$tbl <- DT::renderDataTable(DT::datatable(islacatalina, options = list(pagelength = 25)))
})
output$plot1 <- renderPlot({
if(length(input$visualize) == 0 ) return()
isolate({
if(length(input$checkbox) == 0) return()
incheckbox <- input$checkbox
}) # end isolate
if(length(incheckbox) == 1) {
switch(incheckbox,
"Mona Island"= { gplot <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot) },
"Isla Catalina"= { gplot6 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot6) },
"La Parguera"= { gplot7 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot7) }
) # end switch
} else if(length(incheckbox) == 2) {
if(all(c("La Parguera", "Mona Island") %in% incheckbox)) {
gplot2 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot2)
} else if( all(c("Mona Island", "Isla Catalina") %in% incheckbox)) {
gplot4 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot4)
} else if(all(c("La Parguera", "Isla Catalina") %in% incheckbox)) {
gplot5 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot5)
}
} else if ( all(c("La Parguera", "Mona Island", "Isla Catalina") %in% incheckbox)) {
gplot3 <- ggplot(data = plotdata) +
geom_polygon(mapping = aes(x = Year1, y = RLIMona), na.rm = TRUE) +
ylab("Candelas (5-year Running Average)" )
print(gplot3)
}
})
}
shinyApp(ui, server)
The code above works for me :)
Apart the UI changes (made to get a bit tidier UI and see what was happening), the key is the if
cascade`.
Take into account:
if
only works for one element. If you compare a vector of length >1 with another vector >1, only the first matching element of the first vector is considered.Suppose you have selected 3 elements. all(c("La Parguera", "Mona Island") %in% incheckbox)
would always be true. This is why currently I split the comparisons by number of elements (but there are probably other alternatives using other set
operators like setdiff
).
Please let me know if it works for you.
Upvotes: 1