Skip to content

Commit

Permalink
Merge pull request #47 from oxford-pharmacoepi/mah_observationPeriod
Browse files Browse the repository at this point in the history
inObservation() functions
  • Loading branch information
catalamarti authored Aug 1, 2024
2 parents 2596193 + f9ea3f7 commit bf92dbe
Show file tree
Hide file tree
Showing 20 changed files with 885 additions and 498 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ Imports:
CDMConnector (>= 1.3.0),
checkmate,
cli,
clock,
CohortCharacteristics,
CohortConstructor,
dplyr,
ggplot2,
gt,
IncidencePrevalence (>= 0.7.0),
lubridate,
magrittr,
omopgenerics (>= 0.0.3),
PatientProfiles,
Expand Down
4 changes: 2 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Generated by roxygen2: do not edit by hand

export(plotObservationPeriod)
export(plotInObservation)
export(plotRecordCount)
export(summariseClinicalRecords)
export(summariseEntryCharacteristics)
export(summariseObservationPeriod)
export(summariseInObservation)
export(summarisePersonDays)
export(summariseRecordCount)
export(suppress)
Expand Down
29 changes: 18 additions & 11 deletions R/checks.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,28 @@ checkOmopTable <- function(omopTable){
}

#' @noRd
checkUnit <- function(unit){
checkUnit <- function(unit,call = parent.frame()){
inherits(unit, "character")
assertLength(unit, 1)
if(!unit %in% c("year","month")){
cli::cli_abort("units value is not valid. Valid options are year or month.")
cli::cli_abort("units value is not valid. Valid options are year or month.", call = call)
}
}

#' @noRd
checkUnitInterval <- function(unitInterval){
checkUnitInterval <- function(unitInterval, call = parent.frame()){
inherits(unitInterval, c("numeric", "integer"))
assertLength(unitInterval, 1)
if(unitInterval < 1){
cli::cli_abort("unitInterval input has to be equal or greater than 1.")
cli::cli_abort("unitInterval input has to be equal or greater than 1.", call = call)
}
if(!(unitInterval%%1 == 0)){
cli::cli_abort("unitInterval has to be an integer.")
cli::cli_abort("unitInterval has to be an integer.", call = call)
}
}

#' @noRd
checkCategory <- function(category, overlap = FALSE, type = "numeric") {
checkCategory <- function(category, overlap = FALSE, type = "numeric", call = parent.frame()) {
checkmate::assertList(
category,
types = type, any.missing = FALSE, unique = TRUE,
Expand Down Expand Up @@ -84,11 +84,11 @@ checkCategory <- function(category, overlap = FALSE, type = "numeric") {
x[1] <= x[2]
}))
if (!(all(checkLower))) {
cli::cli_abort("Lower bound should be equal or smaller than upper bound")
cli::cli_abort("Lower bound should be equal or smaller than upper bound", call = call)
}

# built tibble
result <- lapply(category, function(x) {
result <- lapply(category, function(x, call = parent.frame()) {
dplyr::tibble(lower_bound = x[1], upper_bound = x[2])
}) |>
dplyr::bind_rows() |>
Expand All @@ -111,7 +111,7 @@ checkCategory <- function(category, overlap = FALSE, type = "numeric") {
lower <- result$lower_bound[2:nrow(result)]
upper <- result$upper_bound[1:(nrow(result) - 1)]
if (!all(lower > upper)) {
cli::cli_abort("There can not be overlap between categories")
cli::cli_abort("There can not be overlap between categories", call = call)
}
}
}
Expand All @@ -120,8 +120,15 @@ checkCategory <- function(category, overlap = FALSE, type = "numeric") {
}


checkFacetBy <- function(summarisedRecordCount, facet_by){
checkFacetBy <- function(summarisedRecordCount, facet_by, call = parent.frame()){
if(!facet_by %in% colnames(summarisedRecordCount) & !is.null(facet_by)){
cli::cli_abort("facet_by argument has to be one of the columns from the summarisedRecordCount object.")
cli::cli_abort("facet_by argument has to be one of the columns from the summarisedRecordCount object.", call = call)
}
}

checkOutput <- function(output, call = parent.frame()){
if(!output %in% c("person-days","all","records")){
cli::cli_abort("output argument is not valid. It must be either `person-days`, `records`, or `all`.")
}
}

154 changes: 154 additions & 0 deletions R/internalPlot.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#' @noRd
internalPlot <- function(summarisedResult, facet = NULL, call = parent.frame()){
# Initial checks ----
assertClass(summarisedResult, "summarised_result", call = call)

if(summarisedResult |> dplyr::tally() |> dplyr::pull("n") == 0){
cli::cli_warn("summarisedOmopTable is empty.")
return(
summarisedResult |>
ggplot2::ggplot()
)
}

summarisedResult <- summarisedResult |>
dplyr::filter(.data$estimate_name == "count")

if(summarisedResult |> dplyr::select("variable_name") |> dplyr::distinct() |> dplyr::pull("variable_name") |> length() > 1){
cli::cli_abort("The summarised result can only contain one type of variable_name. Please, filter variable_name.", call = call)
}

# Determine color variables ----
Strata <- c("cdm_name", "group_level","strata_level")

# If facet has variables, remove that ones from the strata variable
if(!is.null(facet)){
x <- facetFunction(facet, summarisedResult)
facetVarX <- x$facetVarX
facetVarY <- x$facetVarY

if(!is.null(facetVarX)){Strata <- Strata[Strata != facetVarX]}
if(!is.null(facetVarY)){Strata <- Strata[Strata != facetVarY]}
}

# If all the variables have been selected to facet by, do not use any strata
if(length(Strata) == 0){
Strata <- "black"
}else{
# Create strata variable with the remaining variables in strata
summarisedResult <- summarisedResult |> dplyr::mutate(strata_col = "")
for(i in 1:length(Strata)){
summarisedResult <- summarisedResult |>
dplyr::mutate(strata_col = paste0(.data$strata_col,"; ",.data[[Strata[i]]]))
}

summarisedResult <- summarisedResult |>
dplyr::mutate(strata_col = sub("; ","",.data$strata_col)) |>
dplyr::rename("Strata" = "strata_col")
}

# Plot ----
p1 <- summarisedResult |>
dplyr::mutate(count = as.numeric(.data$estimate_value),
time = as.Date(.data$variable_level))

if(TRUE %in% c(Strata == "black")){
p1 <- ggplot2::ggplot(p1, ggplot2::aes(x = .data$time,
y = .data$count))
}else{
p1 <- ggplot2::ggplot(p1, ggplot2::aes(x = .data$time,
y = .data$count,
group = .data$Strata,
color = .data$Strata))
}

p1 +
ggplot2::geom_point() +
ggplot2::geom_line(show.legend = dplyr::if_else(Strata == "black",FALSE, TRUE)) +
ggplot2::facet_grid(facets = facet) +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 90, vjust = 0.5, hjust=1)) +
ggplot2::xlab("Dates") +
ggplot2::ylab(stringr::str_to_sentence(gsub("_"," ",summarisedResult |> dplyr::pull("variable_name") |> unique()))) +
ggplot2::theme() +
ggplot2::theme_bw()
}

facetFunction <- function(facet, summarisedResult) {
if (!is.null(facet)) {
checkmate::assertTRUE(inherits(facet, c("formula", "character")))

if (inherits(facet, "formula")) {
facet <- Reduce(paste, deparse(facet))
}

# Extract facet names
x <- extractFacetVar(facet)
facetVarX <- x$facetVarX
facetVarY <- x$facetVarY

# Check facet names validity
facetVarX <- checkFacetNames(facetVarX, summarisedResult)
facetVarY <- checkFacetNames(facetVarY, summarisedResult)
} else {
facetVarX <- NULL
facetVarY <- NULL
}

# Add table_name column
return(list("facetVarX" = facetVarX, "facetVarY" = facetVarY))
}

checkFacetNames <- function(facetVar, summarisedResult) {
if (!is.null(facetVar)) {
# Remove spaces at the beginning or at the end
facetVar <- gsub(" $", "", facetVar)
facetVar <- gsub("^ ", "", facetVar)

# Replace empty spaces with "_"
facetVar <- gsub(" ", "_", facetVar)

# Turn to lower case
facetVar <- tolower(facetVar)

facetVar[facetVar == "cohort_name"] <- "group_level"
facetVar[facetVar == "window_name"] <- "variable_level"
facetVar[facetVar == "strata"] <- "strata_level"

# Replace empty or "." facet by NULL
if (TRUE %in% (facetVar %in% c("", ".", as.character()))) {
facetVar <- NULL
}

# Check correct column names
if(FALSE %in% c(facetVar %in% c("cdm_name", "group_level", "strata_level"))){
cli::cli_abort("Only the following columns are allowed to be facet by: 'cdm_name', 'group_level', 'strata_level')")
}
}
return(facetVar)
}

extractFacetVar <- function(facet) {
if (unique(stringr::str_detect(facet, "~"))) {
# Separate x and y from the formula
facetVarX <- gsub("~.*", "", facet)
facetVarY <- gsub(".*~", "", facet)

# Remove
facetVarX <- stringr::str_split(facetVarX, pattern = "\\+")[[1]]
facetVarY <- stringr::str_split(facetVarY, pattern = "\\+")[[1]]
} else {
if (length(facet) == 1) {
facetVarX <- facet
facetVarY <- NULL
} else {
# Assign "randomly" the positions
horizontal <- 1:round(length(facet) / 2)
vertical <- (round(length(facet) / 2) + 1):length(facet)

facetVarX <- facet[horizontal]
facetVarY <- facet[vertical]
}
}

return(list("facetVarX" = facetVarX, "facetVarY" = facetVarY))
}
15 changes: 15 additions & 0 deletions R/plotInObservation.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#' Create a gt table from a summarised omop_table.
#'
#' @param summarisedInObservation A summarised_result object with the output from summariseInObservation().
#' @param facet columns in data to facet. If the facet position wants to be specified, use the formula class for the input
#' (e.g., strata ~ group_level + cdm_name). Variables before "~" will be facet by on horizontal axis, whereas those after "~" on vertical axis.
#' Only the following columns are allowed to be facet by: "cdm_name", "group_level", "strata_level".
#'
#' @return A ggplot showing the table counts
#'
#' @export
#'
plotInObservation <- function(summarisedInObservation, facet = NULL){
internalPlot(summarisedResult = summarisedInObservation,
facet = facet)
}
36 changes: 0 additions & 36 deletions R/plotObservationPeriod.R

This file was deleted.

Loading

0 comments on commit bf92dbe

Please sign in to comment.