Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
branches: [*]

name: R-CMD-check

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint-changed-files.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
on:
workflow_dispatch:
pull_request:
branches: [main, master]
branches: [*]
paths:
- '**.R'
- '**.Rmd'
Expand Down
8 changes: 8 additions & 0 deletions R/constants.R
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,11 @@ DEF_TOUCHSTONE_OLD_OLD <- "202110"
#'
#' @export
COLOUR_VIMC <- "#008080"

#' @name constants
#'
#' @examples
#' pine
#'
#' @export
pine <- c("PAK", "IND", "NGA", "ETH")
274 changes: 274 additions & 0 deletions R/fn_plotting_impact.R
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall comment on these fns - since they prepare data before plotting it, I would separate the preparation steps from the plotting steps, and have paired functions prep_plot_X() and plot_X(), which is the pattern we've adopted in {vimcheck}. In a report, these would/should be pipe-able, data %>% prep_plot_X() %>% plot_X(),

Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
#' Plot central impact estimates by cohort and year.
#'
#' Produces faceted plots of central impact estimates for priority countries,
#' stratified either by birth cohort or by year of vaccination.
#' Impact metrics include cases, deaths, DALYs, and YLLs.
#'
#' @param data A tibble containing impact estimates.
#' @param burden_type Burden metric used to evaluate impact. burden_type can be: cases, deaths, dalys, yll.
#' @param title Title of the plot to be rendered
#' @param view Charactar scalar. The way impact is assigned, either by birth cohort ("cohort") or by year of vaccination ("year").
#'
#' @return ggplot object showing central impact estimates
#'
#' @examples
#'
#' # Create example data
#' impact_data <- tibble::tibble(
#' country = c("A", "A", "B", "B"),
#' year = c(2020, 2021, 2020, 2021),
#' birth_cohort = c(2000, 2001, 2000, 2001),
#' burden_outcome = c("deaths", "cases", "deaths", "cases"),
#' impact = c(15, 5, 14, 8),
#' short_name = c("short1", "short2", "short3", "short4")
#' )
#' plot_impact(
#' data = impact_data,
#' burden_type = "cases",
#' title = "Cases averted",
#' view = "year"
#' )
Comment thread
zegibney marked this conversation as resolved.
#'
#' @export
plot_impact <- function(
data,
burden_type = c("cases", "deaths", "dalys", "yll"),
title,
view = c("cohort", "year")
){
checkmate::assert_tibble(data, min.rows = 1L, min.cols = 1L)
Comment thread
zegibney marked this conversation as resolved.

required_cols <- c("country", "burden_outcome", "impact", "short_name")

checkmate::assert_names(
names(data),
must.include = required_cols
)

checkmate::assert_character(title, len = 1)

burden_type <- rlang::arg_match(burden_type)
view <- rlang::arg_match(view)

Impact <- dplyr::filter(data,
.data$country %in% pine,
.data$burden_outcome == burden_type,
.data$impact != 0)

if(nrow(Impact) > 0){
# ---- Cohort view ----
if(view == "cohort"){

checkmate::assert_names(names(data), must.include = "birth_cohort")

Impact <- Impact %>% dplyr::rename(Impact, cohort = .data$birth_cohort)

cols_to_select <- c("country", "cohort", "impact", "short_name")

Impact <- dplyr::select(Impact, all_of(cols_to_select))

p <- ggplot(
Impact,
aes(
x = .data$cohort,
y = .data$impact,
ymin = .data$impact,
ymax = .data$impact,
fill = as.character(.data$short_name)
)
) +
ggplot::geom_ribbon(alpha = 0.3) +
ggplot::geom_line(aes(colour = .data$short_name), size = 0.5)+
ggplot::geom_point(aes(colour = .data$short_name), size = 0.5)+
theme_vimc() + #TODO: to check where the theme definition is saved as may not be right for this plot
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The theme is in R/fn_plotting_helpers.R - you could either modify the default theme or build off it if you want this figure to look different.

facet_wrap(country~., scales = "free_y") +
labs(
x = "Birth cohort",
y = paste(burden_type, "averted"),
title = title
) +
theme(
legend.position="bottom",
legend.key.size= unit(0.5, 'cm'),
legend.key.width = unit(0.3, 'cm')
)

} else { # ---- Year (non-cohort) view ----
cols_to_select <- c("country", "year", "impact", "short_name")

checkmate::assert_names(names(data), must.include = "year")

Impact <- dplyr::select(Impact, all_of(cols_to_select))

p <- ggplot (
Impact,
aes(
x = .data$year,
y = .data$impact,
ymin = .data$impact,
ymax = .data$impact,
fill = .data$short_name
)
) +
ggplot::geom_ribbon(alpha = 0.3)+
ggplot::geom_line(aes(colour = .data$short_name), size = 0.5)+
ggplot::geom_point(aes(colour = .data$short_name), size = 0.5)+
theme_vimc() + #TODO: same note as above re theme definition
facet_wrap(country~., scales = "free_y")+
labs(
x = "Year",
y = paste(burden_type, "averted"),
title = title
) +
theme(
legend.position="bottom",
legend.key.size= unit(0.5, 'cm'),
legend.key.width = unit(0.3, 'cm')
)
}
} else {
p <- "No estimates in the data." #TODO: both here and in the below plot returning p may be an issue? Can you think of a better way?
}
Comment on lines +129 to +131
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be handled in a plotting preparation function that errors if there is no PINE data? That way the plotting fn always returns a plot.

return(p)

}

#' Plot coverage and fully vaccinated persons (FVPs)
#'
#' Generates plots of routine vaccine coverage and fully vaccinated
#' persons (FVPs) over time for selected countries.
#'
#' @param fvps A tibble showing the number of fvps (fully vaccinated persons)
#' by country, year and scenario/activity type.
#'
#' @return A named list with two ggplot objects:
#' \describe{
#' \item{coverage}{A plot of routine vaccine coverage over time.}
#' \item{fvps}{A plot of fully vaccinated persons over time.}
#' }
#' @examples
#'
#' # Create example data
#' fvps <- tibble::tibble(
#' country = c("AGO", "AGO", "BEN", "BEN"),
#' year = c(2020, 2021, 2020, 2021),
#' activity_type = c("routine", "campaign", "routine", "campaign"),
#' scenario_type = c("default", "default", "default", "default"),
#' vaccine = c("measles", "measles", "measles", "measles"),
#' coverage_adjusted = c(0.8, 0.85, 0.4, 0.7),
#' fvps = c(1000000, 1200000, 800000, 900000)
#' )

#' plots <- plot_coverage_fvps(fvps)
Comment thread
zegibney marked this conversation as resolved.
#' plots$coverage
#' plots$fvps
#'
#' @export
plot_coverage_fvps <- function(fvps){
checkmate::assert_tibble(fvps, min.rows = 1L, min.cols = 1L)
Comment on lines +167 to +168
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty much the same general suggestions as for the preceding fn.


required_cols <- c(
"country",
"activity_type",
"scenario_type",
"vaccine",
"coverage_adjusted",
"year",
"fvps"
)

checkmate::assert_names(
names(fvps),
must.include = required_cols
)


fvps <- dplyr::filter(fvps, .data$country %in% pine)

cov <- dplyr::filter(fvps, .data$activity_type == "routine")

cov <- dplyr::mutate(cov,
vaccine_delivery = paste(.data$scenario_type, .data$vaccine, sep = "_"),
coverage_adjusted = round(.data$coverage_adjusted*100, 2)
)

cols_to_select <- c("country", "vaccine_delivery", "year", "coverage_adjusted")

cov <- dplyr::select(cov, all_of(cols_to_select))

cov <- dplyr::rename(cov, coverage = .data$coverage_adjusted)

fvps <- dplyr::mutate(fvps,
vaccine_delivery = paste(.data$scenario_type, .data$activity_type, sep = "_")
)
cols_to_select <- c("country", "vaccine_delivery", "year", "fvps")

fvps <- dplyr::select(fvps, all_of(cols_to_select))

fvps <- dplyr::group_by(fvps,
.data$country,
.data$vaccine_delivery,
.data$year)

fvps <- dplyr::summarise(fvps,
fvps = round(sum(.data$fvps)/1e6, 2),
.groups = "drop"
)
if(nrow(cov) > 0){
p <- ggplot(
cov,
aes(
x = .data$year,
y = .data$coverage,
ymin = 0,
ymax = 1,
fill = .data$vaccine_delivery)
) +
ggplot::geom_line(aes(colour = .data$vaccine_delivery), size = 0.5) +
theme_vimc() + #TODO: same note as above
facet_wrap(country~., scales = "free_y")+
labs(
x = "Year",
y = "Coverage (%)",
title = "Routine vaccine coverage"
) +
theme(
legend.position="bottom",
legend.key.size= unit(0.5, 'cm'),
legend.key.width = unit(0.3, 'cm')
)

} else {
p <- "There is no routine coverage in the database."
}


q <- ggplot(
fvps,
aes(
x = .data$year,
y = .data$fvps,
ymin = .data$fvps,
ymax = .data$fvps, #TODO: min/max both here and above seem to be the same so may be irrelevant to define
fill = .data$vaccine_delivery
)
) +
geom_point(aes(colour = .data$vaccine_delivery), size = 0.5) +
theme_vimc()+ #TODO: same note above on theme
facet_wrap(country~., scales = "free_y") +
labs(
x = "Year",
y = "FVPs (in millions)",
title = "FVPs"
) +
theme(
legend.position="bottom",
legend.key.size = unit(0.5, 'cm'),
legend.key.width = unit(0.3, 'cm')
)

return(list(
coverage = p,
fvps = q
))
}
6 changes: 6 additions & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ reference:
- subtitle: Plot impact estimates
contents:
- plot_impact_diagnostics
- subtitle: Plot central impact estimates by cohort and year
contents:
- plot_impact
- subtitle: Plot coverage and fully vaccinated persons (FVPs)
contents:
- plot_coverage_fvps

- title: Plotting helper functions
contents:
Expand Down
7 changes: 7 additions & 0 deletions man/constants.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions man/plot_coverage_fvps.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading