Skip to contents

Visualise geographical distribution across multiple administrative boundaries on an interactive leaflet map.

Usage

place_ui(
  id,
  geo_data,
  count_vars = NULL,
  group_vars = NULL,
  title = "Place",
  icon = bsicons::bs_icon("geo-fill"),
  tooltip = NULL,
  geo_lab = "Geo boundaries",
  count_vars_lab = "Indicator",
  groups_lab = "Group data by",
  no_grouping_lab = "No grouping",
  circle_size_lab = "Circle size multiplyer",
  opts_btn_lab = "options",
  download_lab = "download",
  full_screen = TRUE
)

place_server(
  id,
  df,
  geo_data,
  count_vars = NULL,
  group_vars = NULL,
  show_parent_borders = FALSE,
  choro_lab = "Rate /100 000",
  choro_pal = "Reds",
  choro_opacity = 0.7,
  export_width = 1200,
  export_height = 650,
  time_filter = shiny::reactiveVal(),
  filter_info = shiny::reactiveVal(),
  filter_reset = shiny::reactiveVal()
)

Arguments

id

Module id. Must be the same in both the UI and server function to link the two.

geo_data

A list of named lists containing spatial sf dataframes and other information for different geographical levels.

count_vars

If data is aggregated, variable name(s) of count variable(s) in data. If more than one is variable provided, a select input will appear in the options dropdown. If named, names are used as variable labels.

group_vars

Character vector of categorical variable names. If provided, a select input will appear in the options dropdown allowing for data groups to be visualised on the map in pie charts per geographical unit. If named, names are used as variable labels.

title

The title for the card.

icon

The icon to be displayed next to the title

tooltip

additional title hover text information

geo_lab

The label for the geographical level selection.

count_vars_lab

text label for the aggregate count variables input.

groups_lab

The label for the group data by selection.

no_grouping_lab

text label for the no grouping option in the grouping input.

circle_size_lab

text label for the circle size slider input.

opts_btn_lab

text label for the dropdown menu button.

download_lab

text label for the download button.

full_screen

Add button to card to with the option to enter full screen mode?

df

Data frame or tibble of patient level or aggregated data. Can be either a shiny reactive or static dataset.

show_parent_borders

Show borders of parent boundary levels?

choro_lab

Label for attack rate choropleth (only applicable if geo_data contains population data)

choro_pal

Colour palette passed to leaflet::colorBin() for attack rate choropleth (only applicable if geo_data contains population data)

choro_opacity

Opacity of choropleth colour (only applicable if geo_data contains population data)

export_width

The width of the exported map image.

export_height

The height of the exported map image.

time_filter

supply the output of time_server() wrapped in a shiny::reactive() here to filter the data by click events on the time module bar chart (clicking a bar will filter the data to the period the bar represents)

filter_info

If contained within an app using filter_server(), supply the filter_info object returned by that function here wrapped in a shiny::reactive() to add filter information to chart exports.

filter_reset

If contained within an app using filter_server(), supply the filter_reset object returned by that function here wrapped in a shiny::reactive() to reset any click event filters that have been set from by module.

Value

A bslib::card UI element with options and download button and a leaflet map.

The server function returns the leaflet map's shape click information as a list.

Examples

library(shiny)
library(bslib)
library(epishiny)

# example package data
data("df_ll") # linelist
data("sf_yem") # sf geo boundaries for Yemen admin 1 & 2

# setup geo data for adm1 and adm2 using the
# geo_layer function to be passed to the place module
# if population variable is provided, attack rates
# will be shown on the map as a choropleth
geo_data <- list(
  geo_layer(
    layer_name = "Governorate", # name of the boundary level
    sf = sf_yem$adm1, # sf object with boundary polygons
    name_var = "adm1_name", # column with place names
    pop_var = "adm1_pop", # column with population data (optional)
    join_by = c("pcode" = "adm1_pcode") # geo to data join vars: LHS = sf, RHS = data
  ),
  geo_layer(
    layer_name = "District",
    sf = sf_yem$adm2,
    name_var = "adm2_name",
    pop_var = "adm2_pop",
    join_by = c("pcode" = "adm2_pcode")
  )
)

# range of dates used in filter module to filter time period
date_range <- range(df_ll$date_notification, na.rm = TRUE)

# define date variables in data as named list to be used in app
date_vars <- c(
  "Date of notification" = "date_notification",
  "Date of onset" = "date_symptom_start",
  "Date of hospitalisation" = "date_hospitalisation_start",
  "Date of outcome" = "date_hospitalisation_end"
)

# define categorical grouping variables
# in data as named list to be used in app
group_vars <- c(
  "Governorate" = "adm1_origin",
  "Sex" = "sex_id",
  "Hospitalised" = "hospitalised_yn",
  "Vaccinated measles" = "vacci_measles_yn",
  "Outcome" = "outcome"
)

# user interface
ui <- page_sidebar(
  title = "epishiny",
  # sidebar
  sidebar = filter_ui(
    "filter",
    group_vars = group_vars,
    date_range = date_range,
    period_lab = "Notification period"
  ),
  # main content
  layout_columns(
    col_widths = c(12, 7, 5),
    place_ui(
      id = "map",
      geo_data = geo_data,
      group_vars = group_vars
    ),
    time_ui(
      id = "curve",
      title = "Time",
      date_vars = date_vars,
      group_vars = group_vars,
      ratio_line_lab = "Show CFR line?"
    ),
    person_ui(id = "age_sex")
  )
)

# app server
server <- function(input, output, session) {
  app_data <- filter_server(
    id = "filter",
    df = df_ll,
    date_var = "date_notification",
    group_vars = group_vars
  )
  place_server(
    id = "map",
    df = reactive(app_data()$df),
    geo_data = geo_data,
    group_vars = group_vars,
    filter_info = reactive(app_data()$filter_info)
  )
  time_server(
    id = "curve",
    df = reactive(app_data()$df),
    date_vars = date_vars,
    group_vars = group_vars,
    show_ratio = TRUE,
    ratio_var = "outcome",
    ratio_lab = "CFR",
    ratio_numer = "Deceased",
    ratio_denom = c("Deceased", "Healed", "Abandonment"),
    filter_info = reactive(app_data()$filter_info)
  )
  person_server(
    id = "age_sex",
    df = reactive(app_data()$df),
    age_var = "age_years",
    sex_var = "sex_id",
    male_level = "Male",
    female_level = "Female",
    filter_info = reactive(app_data()$filter_info)
  )
}

# launch app
if (interactive()) {
  shinyApp(ui, server)
}