Skip to content

Commit c94a854

Browse files
authored
Merge pull request #4 from The-Strategy-Unit/1-poc-trend
Add basic proof-of-concept app
2 parents dc15108 + 1b1e3cb commit c94a854

File tree

15 files changed

+484
-27
lines changed

15 files changed

+484
-27
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
^\.github$
2+
^\.Renviron\.example$
23
^\.Rproj\.user$
34
^\.vscode$
45
^app\.R$

.Renviron.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
AZ_CONTAINER_INPUTS=
2+
AZ_STORAGE_EP=

DESCRIPTION

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,21 @@ Description: A Shiny-app-in-a-package to explore data related to
88
License: MIT + file LICENSE
99
URL: https://github.com/The-Strategy-Unit/cpma-explorer
1010
BugReports: https://github.com/The-Strategy-Unit/cpma-explorer/issues
11+
Depends:
12+
R (>= 4.1.0)
1113
Imports:
14+
azkit,
15+
bsicons,
1216
bslib,
13-
shiny
17+
dplyr,
18+
ggplot2,
19+
jsonlite,
20+
purrr,
21+
rlang,
22+
shiny,
23+
stringr
24+
Remotes:
25+
The-Strategy-Unit/azkit
1426
Encoding: UTF-8
1527
Roxygen: list(markdown = TRUE)
1628
RoxygenNote: 7.3.2

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(run_app)
4+
importFrom(rlang,.data)
5+
importFrom(rlang,.env)

R/ZZZ.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#' @importFrom rlang .data .env
2+
NULL

R/add_external_resources.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ add_external_resources <- function() {
1515
#' @param ... character vectors, specifying subdirectory and file(s)
1616
#' within your package. The default, none, returns the root of the app.
1717
#' @noRd
18-
#' @noRd
1918
app_sys <- function(...) {
20-
system.file(..., package = "cpma-explorer")
19+
system.file(..., package = "cpma.explorer")
2120
}

R/app_server.R

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,57 @@
22
#' @param input,output,session Internal parameters for {shiny}.
33
#' @noRd
44
app_server <- function(input, output, session) {
5-
output$distPlot <- shiny::renderPlot({
6-
x <- datasets::faithful[, 2]
7-
bins <- seq(min(x), max(x), length.out = input$bins + 1)
8-
9-
# draw the histogram with the specified number of bins
10-
graphics::hist(
11-
x,
12-
breaks = bins,
13-
col = "darkgray",
14-
border = "white",
15-
xlab = "Waiting time to next eruption (in mins)",
16-
main = "Histogram of waiting times"
5+
# Data ----
6+
7+
container <- azkit::get_container(Sys.getenv("AZ_CONTAINER_INPUTS"))
8+
rates <- azkit::read_azure_parquet(container, "rates", "dev")
9+
10+
# Reactives ----
11+
12+
selected_provider <- shiny::reactive(input$provider_select)
13+
selected_strategy <- shiny::reactive(input$strategy_select)
14+
15+
rates_prepared <- shiny::reactive({
16+
rates |>
17+
dplyr::filter(
18+
.data$provider == selected_provider(),
19+
.data$strategy == selected_strategy()
20+
) |>
21+
dplyr::arrange(.data$fyear)
22+
}) |>
23+
shiny::bindEvent(selected_provider(), selected_strategy())
24+
25+
# Observers ----
26+
27+
shiny::observe({
28+
providers <- jsonlite::read_json(
29+
app_sys("app", "data", "datasets.json"),
30+
simplify_vector = TRUE
31+
)
32+
provider_choices <- purrr::set_names(names(providers), providers)
33+
shiny::updateSelectInput(
34+
session,
35+
"provider_select",
36+
choices = provider_choices
1737
)
1838
})
39+
40+
shiny::observe({
41+
strategies <- jsonlite::read_json(
42+
app_sys("app", "data", "mitigators.json"),
43+
simplify_vector = TRUE
44+
)
45+
strategy_choices <- purrr::set_names(names(strategies), strategies)
46+
shiny::updateSelectInput(
47+
session,
48+
"strategy_select",
49+
choices = strategy_choices
50+
)
51+
})
52+
53+
# Outputs ----
54+
55+
output$rates_plot <- shiny::renderPlot({
56+
rates_prepared() |> plot_rates()
57+
})
1958
}

R/app_ui.R

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
11
#' The application User-Interface
2-
#' @param request Internal parameter for `{shiny}`.
2+
#' @param request Internal parameter for shiny.
33
#' @noRd
44
app_ui <- function(request) {
55
bslib::page_sidebar(
6-
title = "Old Faithful Geyser Data",
7-
lang = "en",
8-
theme = bslib::bs_theme(primary = "#005EB8", base_font = "Frutiger"),
6+
title = "CPMA Explorer",
97
sidebar = bslib::sidebar(
10-
shiny::sliderInput(
11-
"bins",
12-
"Number of bins:",
13-
min = 1,
14-
max = 50,
15-
value = 30
8+
shiny::selectInput(
9+
"provider_select",
10+
"Choose a provider:",
11+
choices = NULL
12+
),
13+
shiny::selectInput(
14+
"strategy_select",
15+
"Choose a strategy:",
16+
choices = NULL
1617
)
1718
),
1819

1920
bslib::card(
20-
bslib::card_header("A nice plot"),
21-
shiny::plotOutput("distPlot")
21+
fill = FALSE,
22+
bslib::card_header(
23+
class = "bg-warning",
24+
bsicons::bs_icon("exclamation-triangle"),
25+
"Warning"
26+
),
27+
"This application is in development and its output has not been verified.
28+
The information presented here should not be relied on as fact."
29+
),
30+
31+
bslib::card(
32+
bslib::card_header("Trend in rates"),
33+
bslib::card_body(
34+
shiny::plotOutput("rates_plot")
35+
),
36+
full_screen = TRUE
2237
)
2338
)
2439
}

R/fct_plot.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#' Plot Trend in Rates
2+
#' @param rates_df A data.frame. Must contain columns given by `fyear_col` and
3+
#' `rate_col`. Pre-filtered for a given provider and strategy. One row per
4+
#' financial year.
5+
#' @param fyear_col Character. Name of the column in `rates_df` containing the
6+
#' financial year in the form `"2023/24"`.
7+
#' @param rate_col Character. Name of the column in `rates_df` containing the
8+
#' rate value (the type of which is dependent on the strategy).
9+
plot_rates <- function(rates_df, fyear_col = "fyear", rate_col = "rate") {
10+
x_breaks <- rates_df[[fyear_col]]
11+
x_labels <- enstring_fyear(x_breaks)
12+
13+
rates_df |>
14+
ggplot2::ggplot(ggplot2::aes(
15+
x = .data[[fyear_col]],
16+
y = .data[[rate_col]]
17+
)) +
18+
ggplot2::geom_line() +
19+
ggplot2::labs(
20+
x = "Financial year",
21+
y = "Rate"
22+
) +
23+
ggplot2::scale_x_continuous(
24+
breaks = x_breaks,
25+
labels = x_labels,
26+
guide = ggplot2::guide_axis(angle = 45)
27+
)
28+
}

R/fct_utils.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#' Convert a Financial Year to Character
2+
#' @param year Integer. Expressed in the form `202526`. To be converted to the
3+
#' form `"2025/26"`.
4+
enstring_fyear <- function(year) {
5+
yyyy <- stringr::str_sub(year, 1, 4)
6+
yy <- stringr::str_sub(year, -2)
7+
paste0(yyyy, "/", yy)
8+
}

0 commit comments

Comments
 (0)