Reputation: 7735
In my flexdashboard shiny app, I'm using selectizeInput()
with three options: "english", "spanish", and "other". In my toy dataset, there are no observations of the variable lang
that take the value "other". Therefore, when only "other" is selected in the input bar, R returns an evaluation error:
missing value where TRUE/FALSE needed.
This is caused by the following line of the pipe in the "Page 1" section:
filter(if(is.null(input$foo)) (new==1) else (lang %in% input$foo)) %>%
What is the right approach to show a blank plot when there are no observations in the dataset that take the value of the input?
---
title: "test"
output:
flexdashboard::flex_dashboard:
theme: bootstrap
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
library(tibbletime)
library(dygraphs)
library(magrittr)
library(xts)
```
```{r global, include=FALSE}
# generate data
set.seed(1)
dat <- data.frame(date = seq(as.Date("2018-01-01"),
as.Date("2018-06-30"),
"days"),
sex = sample(c("male", "female"), 181, replace=TRUE),
lang = sample(c("english", "spanish"), 181, replace=TRUE),
age = sample(20:35, 181, replace=TRUE))
dat <- sample_n(dat, 80)
```
Sidebar {.sidebar}
=====================================
```{r}
selectizeInput(
'foo', label = NULL,
choices = c("english", "spanish", "other"),
multiple = TRUE
)
```
Page 1
=====================================
```{r}
# all
totals <- reactive({
dat %>%
mutate(new = 1) %>%
arrange(date) %>%
filter(if(is.null(input$foo)) (new==1) else (lang %in% input$foo)) %>%
# time series analysis
tibbletime::as_tbl_time(index = date) %>% # convert to tibble time object
select(date, new) %>%
tibbletime::collapse_by("1 week", side = "start", clean = TRUE) %>%
group_by(date) %>%
mutate(total = sum(new, na.rm = TRUE)) %>%
distinct(date, .keep_all = TRUE) %>%
ungroup() %>%
# expand matrix to include weeks without data
complete(
date = seq(date[1], date[length(date)], by = "1 week"),
fill = list(total = 0)
)
})
# convert to xts
totals_ <- reactive({
totals <- totals()
xts(totals, order.by = totals$date)
})
# plot
renderDygraph({
totals_ <- totals_()
dygraph(totals_[, "total"]) %>%
dyRangeSelector() %>%
dyOptions(useDataTimezone = FALSE,
stepPlot = TRUE,
drawGrid = FALSE,
fillGraph = TRUE)
})
```
Upvotes: 0
Views: 654
Reputation: 12165
One way to do this is to use the shiny::req
function to check the requirements before running the code block.
If you add:
req(dat$lang %in% input$foo)
to the top of your totals <- reactive({
expression, then it will check that the value of input$foo
is in dat$lang
before running the rest of that expression. If it's not found, then the operation will be stopped silently. No error will be displayed and the plot will remain blank.
Upvotes: 2