0
votes

I would like the user to be able to select the date range of data they are interested in. This is my first time working with flexdashboard and Rshiny, so forgive if this is a simple question. I understand that user input requires you to use reactive expressions...

I tried searching stackoverflow for a while and still can't find an answer to help me. Here is the code I wrote so far.

---
title: "title"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    theme: lumen
    runtime: shiny
---
library(flexdashboard)
library(dplyr)
library(lubridate)
setwd("...")
data = readxl::read_excel("Resignation Data.xlsx")
Column {.sidebar}
-----------------------------------------------------------------------

Please choose the date range of interest.

```{r}
DateSeq = seq(as.Date("2020-07-13"), Sys.Date(), "day")
dateRangeInput("dateRange", "Date Select", format = "yyyy-mm-dd", start=min(DateSeq), end=max(DateSeq))
Row {data-width=150}
-----------------------------------------------------------------------

### ESS Utilization this month

```{r}
data_filter = renderTable({
    x = data[data$`Termination Date` >= input$dateRange[1] & data$`Termination Date` <= input$dateRange[2] | 
               is.na(data$`Termination Date`) & data$`Termination Initiation Date (HR)` >= input$dateRange[1] |
               is.na(data$`Termination Date`) & data$`Termination Initiation Date (ESS)` >= input$dateRange[1], ]
  })

renderGauge({
  utilization = round(length(which(!is.na(data_filter()$`Termination Initiation Date (ESS)`))) / length(data_filter()$`Employee ID`) * 100, 1)
  gauge(utilization, min = 0, max = 100, gaugeSectors(success = c(80, 100), warning = c(30, 79), danger = c(0, 29)))
  })

This results in a Warning: Error in $: $ operator is invalid for atomic vectors. And the gauge does not populate.

I am having trouble understanding how to access the filtered data in the reactive function. I tried using data_filter()$ based on this stackoverflow response Returning a dataframe in a reactive function in R Shiny Dashboard. Thank you for your help.

2
The issue is that you named your dataset data and then you define a reactive with name data. When you run your app, data first refers to a dataframe, but after it is processed inside of the reactive it behaves like a function. Hence, in the line starting with temp = ... you are trying to subset a function which results in the famous Error: object of type 'closure' is not subsettable.stefan
Okay, that makes sense, so I changed it to data_filter. I guess my real problem is I don't know how to access the data. If I try to access the new reactive filtered data set by dataf_filter() it gives me the error: operation not allowed without an active reactive context. How do I access the filtered data?Gabriella
You can acess the reactive only inside a so called reactive expressions, e.g. inside one of the render function like renderTable({data_filter()}). Or you have to make temp itself a reactive.stefan

2 Answers

1
votes

As @stefan already points out in the comments, you can only access the reactive data inside a reactive expression.

It seems that the problem is that utilization is still "reactive" but you use it in a non-reactive context when calling gauge.

Without seeing your whole dashboard and data, I would suggest to wrap gauge in a renderGauge call.

renderGauge({
  gauge(utilization, min = 0, max = 100, gaugeSectors(
    success = c(80, 100), warning = c(30, 79), danger = c(0, 29)))
})

See also here:

To include a gauge within a Shiny flexdashboard you need to be sure to wrap the gauge output in renderGauge (so that it is updated when inputs it depends on change).

Does this work?

0
votes

Thank you to for all the help. The final issue (there were many) is solved by using reactive({}) instead of renderTable({}). The gauge populated.

# Utilization Percentage for ESS since it started
data_filter = reactive({
    x = data[data$`Termination Date` >= input$dateRange[1] & data$`Termination Date` <= input$dateRange[2] | 
               is.na(data$`Termination Date`) & data$`Termination Initiation Date (HR)` >= input$dateRange[1] & data$`Termination Date` <= input$dateRange[2] |
               is.na(data$`Termination Date`) & data$`Termination Initiation Date (ESS)` >= input$dateRange[1] & data$`Termination Date` <= input$dateRange[2], ]
  })

renderGauge({
  utilization = round(length(which(!is.na(data_filter()$`Termination Initiation Date (ESS)`))) / length(data_filter()$`Employee ID`), 3) * 100
  gauge(utilization, min = 0, max = 100, gaugeSectors(success = c(80, 100), warning = c(30, 79), danger = c(0, 29)))
  })