#' Business logic of the app #' #' @description #' Responsible for the data wrangling, generation of text and charts and (it might be a bit of overkill in this app) filtering for the user interface. See [Using R6 as data storage](https://engineering-shiny.org/common-app-caveats.html#using-r6-as-data-storage) for more information on this solution. #' #' @export BusinessLogic <- R6::R6Class( "BusinessLogic", public = list( #' @field months Month numbers and their names, on the app selecting the month's name will return the month's number. months = c( "January" = 1, "February" = 2, "March" = 3, "April" = 4, "May" = 5, "June" = 6, "July" = 7, "August" = 8, "September" = 9, "October" = 10, "November" = 11, "December" = 12 ), #' @field metrics Available metrics with better looking names for the app. metrics = c( "Departure delay" = "dep_delay", "Arrival delay" = "arr_delay" ), #' @field data Will store the data (more useful for bigger apps). data = NULL, #' @field unique_carriers Available carriers (more useful in the case of a database with more carriers being added over time). unique_carriers = NULL, #' @field results Where results (title and text for the page and the chart itself) are stored. results = list( title = NULL, text = NULL, chart = NULL ), #' @description #' Create a new business logic object. #' @return A new `BusinessLogic` object. initialize = function() { self$data <- nycflights13::flights self$unique_carriers <- nycflights13::airlines %>% dplyr::mutate(name = name %>% stringr::str_remove_all(" Inc.") %>% stringr::str_remove_all(" Corporation")) }, #' @description #' Generate results, all parameters come directly from the user interface of the app. #' @param carrier_filter Carrier for report. #' @param month_filter Month for report. #' @param metric_filter Metric for report. #' @param threshold Threshold for report. generate_results = function( carrier_filter, month_filter, metric_filter, threshold ) { carrier_code <- self$unique_carriers %>% dplyr::filter(name == carrier_filter) %>% dplyr::pull(carrier) filtered_data <- self$data %>% dplyr::filter( carrier == carrier_code, month == month_filter, .data[[metric_filter]] >= 0 ) %>% dplyr::group_by(day) %>% dplyr::summarize(metric = mean(.data[[metric_filter]], na.rm = TRUE)) month <- self$months[month_filter] %>% names() carrier <- carrier_filter number_of_days <- filtered_data %>% dplyr::filter(metric > threshold) %>% nrow() metric <- dplyr::if_else( metric_filter == "dep_delay", "departures", "arrivals" ) self$results$title <- "{month}: {carrier}" %>% glue::glue() self$results$text <- "In {month} {carrier} had {number_of_days} days with {metric} delayed by more than {threshold} minutes." %>% glue::glue() self$results$chart <- filtered_data %>% dplyr::mutate(day = factor(day)) %>% ggplot2::ggplot(ggplot2::aes(day, metric)) + ggplot2::geom_line(group = 1) + ggplot2::geom_hline( yintercept = threshold, lty = "dashed", color = "red" ) + ggplot2::labs( title = "Average {metric} delay per day for {carrier} in {month}" %>% glue::glue(), x = "Day of the month", y = "Average delay [minutes]" ) } ) )
business_logic <- BusinessLogic$new() business_logic$generate_results("Endeavor Air", 1, "arr_delay", 30) business_logic$results$title business_logic$results$text business_logic$results$chart
test_that("business_logic works", { business_logic <- BusinessLogic$new() business_logic$generate_results("Endeavor Air", 1, "arr_delay", 30) expect_s3_class(business_logic, "R6") expect_s3_class(business_logic, "BusinessLogic") expect_identical(business_logic$data, nycflights13::flights) expect_identical(business_logic$results$title, "January: Endeavor Air") expect_identical(business_logic$results$text, "In January Endeavor Air had 16 days with arrivals delayed by more than 30 minutes.") vdiffr::expect_doppelganger("Results chart 1", business_logic$results$chart) business_logic$generate_results("United Air Lines", 7, "dep_delay", 12) expect_identical(business_logic$results$text, "In July United Air Lines had 30 days with departures delayed by more than 12 minutes.") vdiffr::expect_doppelganger("Results chart 2", business_logic$results$chart) })
# Run but keep eval=FALSE to avoid infinite loop # Execute in the console directly fusen::inflate( flat_file = "dev/flat_business-logic.Rmd", vignette_name = NA, check = FALSE )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.