From 0300e2384680b63ae24d5851d469e9bcfb442de0 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Wed, 15 May 2024 05:08:54 +0000 Subject: [PATCH 01/23] New function to derive oak_id_vars. More work needed. --- R/oak_id_vars.R | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/R/oak_id_vars.R b/R/oak_id_vars.R index 718d11da..b443233d 100644 --- a/R/oak_id_vars.R +++ b/R/oak_id_vars.R @@ -51,3 +51,31 @@ contains_oak_id_vars <- function(x) { admiraldev::assert_character_vector(x) all(oak_id_vars() %in% x) } + + +#' A function to generate oak_id_vars +#' +#' @param raw_dat +#' @param pat_var +#' @param raw_src +#' +#' @return +#' @export +#' +#' @examples +generate_oak_id_vars <- function(raw_dat, + pat_var, + raw_src) { + + admiraldev::assert_character_scalar(pat_var) + admiraldev::assert_character_scalar(raw_src) + admiraldev::assert_data_frame(raw_dat) + admiraldev::assert_data_frame(raw_dat, required_vars = rlang::syms(pat_var)) + + raw_oak_id_vars <- raw_dat |> + dplyr::mutate(oak_id = structure(seq_len(nrow(raw_dat))), + patient_number = !!rlang::sym(pat_var), + raw_source = raw_src) |> + dplyr::select(oak_id_vars(), dplyr::everything()) + +} From b99fb5d01916ae7b88e8feee57e74e376b9bb0fb Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Wed, 15 May 2024 05:09:37 +0000 Subject: [PATCH 02/23] cm template updates. In progress. --- inst/cm_domain/create_cm_template.R | 52 +++++++++++++---------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/inst/cm_domain/create_cm_template.R b/inst/cm_domain/create_cm_template.R index 346f5909..80e92a93 100644 --- a/inst/cm_domain/create_cm_template.R +++ b/inst/cm_domain/create_cm_template.R @@ -14,48 +14,44 @@ library(dplyr) # Read Specification -sdtm_spec <- read_(filename = "~/inst/cm_domain/cm_sdtm_oak_spec.csv") - -study_ct <- read_study_ct(filename = "~/inst/cm_domain/cm_sdtm_oak_ct.csv") +study_ct <- read.csv(system.file("cm_domain/cm_sdtm_oak_ct.csv", + package = "sdtm.oak")) # Read in raw data -cm_raw_data <- read_raw_data_csv(filename = "~/inst/cm_domain/cm_raw_data.csv") |> - # Derive oak_id_vars - derive_oak_id_vars() +cm_raw <- read.csv(system.file("cm_domain/cm_raw_data.csv", + package = "sdtm.oak")) |> + generate_oak_id_vars(pat_var = "PATNUM", + raw_src = "cm_raw") # Create CM domain. The first step in creating CM domain is to create the topic variable -cm <- cm_daw_data |> +cm <- # Derive topic variable assign_no_ct( - raw_dataset = MD1, # This is added for pseudocode. Not required as pipe will send it - raw_variable = MDRAW, - target_sdtm_var = CMTRT + raw_dat = cm_raw, + raw_var = "MDRAW", + tgt_var = "CMTRT" ) |> # Derive qualifier CMDOSU # Use merge and add the qualifier to the topic variable assign_ct( - raw_dataset = MD1, - raw_variable = DOSU, - target_sdtm_var = CMDOSU, - study_ct = study_ct, - target_sdtm_variable_codelist_code = "C71620", - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> + raw_dat = cm_raw, + raw_var = "DOSU", + tgt_var = "CMDOSU", + ct_spec = study_ct, + ct_clst = "C71620", + id_vars = oak_id_vars() + ) |> # Derive qualifier CMDOSFRM and merge it with the target dataset assign_ct( - raw_dataset = MD1, - raw_variable = MDFORM, - target_sdtm_var = CMDOSFRM, - target_sdtm_variable_codelist_code = "C66726", - study_ct = study_ct, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> + raw_dat = cm_raw, + raw_var = "MDFORM", + tgt_var = "CMDOSFRM", + ct_spec = study_ct, + ct_clst = "C66726", + id_vars = (oak_id_vars()) + ) |> # DERIVE CMROUTE assign_ct( raw_dataset = MD1, From 0d563846432b831a2368ce6949de14eda03333bd Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Tue, 21 May 2024 21:13:47 +0000 Subject: [PATCH 03/23] almost completed cm template --- inst/cm_domain/create_cm_template.R | 323 ++++++++++++++-------------- 1 file changed, 165 insertions(+), 158 deletions(-) diff --git a/inst/cm_domain/create_cm_template.R b/inst/cm_domain/create_cm_template.R index 80e92a93..e0840125 100644 --- a/inst/cm_domain/create_cm_template.R +++ b/inst/cm_domain/create_cm_template.R @@ -32,198 +32,205 @@ cm <- raw_dat = cm_raw, raw_var = "MDRAW", tgt_var = "CMTRT" + ) |> + # Derive CMGRPID + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MDNUM", + tgt_var = "CMGRPID", + id_vars = oak_id_vars() + ) |> + # DERIVE CMINDC + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MDIND", + tgt_var = "CMINDC", + id_vars = oak_id_vars() + ) |> + # Derive CMSTDTC. This function calls create_iso8601 + assign_datetime( + raw_dat = cm_raw, + raw_var = c("MDBDR", "MDBTM"), + tgt_var = "CMSTDTC", + raw_fmt = c("d-m-y", "H:M"), + raw_unk = c("UN", "UNK") + ) |> + # Derive qualifier CMSTRTPT Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE' + hardcode_ct( + raw_dat = add_cond(cm_raw, MDPRIOR == "1"), + raw_var = "MDPRIOR", + tgt_var = "CMSTRTPT", + tgt_val = "BEFORE", + ct_spec = study_ct, + ct_clst = "C66728", + id_vars = oak_id_vars() + ) |> + # Derive qualifier CMSTTPT Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING' + hardcode_no_ct( + raw_dat = add_cond(cm_raw, MDPRIOR == "1"), + raw_var = "MDPRIOR", + tgt_var = "CMSTTPT", + tgt_val = "SCREENING", + id_vars = oak_id_vars() + ) |> + # Derive CMENDTC. This function calls create_iso8601 + assign_datetime( + raw_dat = cm_raw, + raw_var = c("MDEDR", "MDETM"), + tgt_var = "CMENDTC", + raw_fmt = c("d-m-y", "H:M"), + raw_unk = c("UN", "UNK") + ) |> + # Derive qualifier CMENRTPT Annotation text is If MDONG == 1 then CM.CMENRTPT = 'ONGOING' + hardcode_ct( + raw_dat = add_cond(cm_raw, MDONG == "1"), + raw_var = "MDONG", + tgt_var = "CMENRTPT", + tgt_val = "ONGOING", + ct_spec = study_ct, + ct_clst = "C66728", + id_vars = oak_id_vars() + ) |> + # Derive qualifier CMENTPT Annotation text is If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' + hardcode_no_ct( + raw_dat = add_cond(cm_raw, MDONG == "1"), + raw_var = "MDONG", + tgt_var = "CMENTPT", + tgt_val = "DATE OF LAST ASSESSMENT", + id_vars = oak_id_vars() + ) |> + # Derive qualifier CMDOS If collected value in raw_var DOS is numeric then CM.CMDOSE + assign_no_ct( + raw_dat = add_cond(cm_raw, is.numeric(DOS)), + raw_var = "DOS", + tgt_var = "CMDOS", + id_vars = oak_id_vars() + ) |> + # Derive qualifier CMDOS If collected value in raw_var DOS is character then CM.CMDOSTXT + assign_no_ct( + raw_dat = add_cond(cm_raw, is.character(DOS)), + raw_var = "DOS", + tgt_var = "CMDOSTXT", + id_vars = oak_id_vars() ) |> # Derive qualifier CMDOSU - # Use merge and add the qualifier to the topic variable assign_ct( raw_dat = cm_raw, - raw_var = "DOSU", - tgt_var = "CMDOSU", + raw_var = "MDFORM", + tgt_var = "DOSU", ct_spec = study_ct, ct_clst = "C71620", id_vars = oak_id_vars() - ) |> - # Derive qualifier CMDOSFRM and merge it with the target dataset + ) |> + # Derive qualifier CMDOSFRM assign_ct( raw_dat = cm_raw, raw_var = "MDFORM", tgt_var = "CMDOSFRM", ct_spec = study_ct, ct_clst = "C66726", - id_vars = (oak_id_vars()) + id_vars = oak_id_vars() ) |> # DERIVE CMROUTE assign_ct( - raw_dataset = MD1, - raw_variable = MDFORM, - target_sdtm_var = MDRTE, - target_sdtm_variable_codelist_code = "C66729", - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) + raw_dat = cm_raw, + raw_var = MDFORM, + tgt_var = "MDRTE", + ct_spec = study_ct, + ct_clst = "C66729", + id_vars = oak_id_vars() ) |> # DERIVE CMDOSFRQ assign_ct( - raw_dataset = MD1, - raw_variable = MDFRQ, - target_sdtm_var = CMDOSFRQ, - target_sdtm_variable_codelist_code = "C71113", - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) + raw_dat = cm_raw, + raw_var = MDFRQ, + tgt_var = CMDOSFRQ, + ct_spec = study_ct, + ct_clst = "C71113", + id_vars = oak_id_vars() ) |> - # DERIVE CMINDC + # Derive qualifier CMPROPH Annotation text is If MDPROPH == 1 then CM.CMPROPH = 'Y' + hardcode_ct( + raw_dat = add_cond(cm_raw, MDPROPH == "1"), + raw_var = "MDPROPH", + tgt_var = "CMPROPH", + tgt_val = "Y", + ct_spec = study_ct, + ct_clst = "C66742", + id_vars = oak_id_vars() + ) |> + # Derive qualifier CMMODIFY Annotation text If collected value in CMMODIFY + # in cm_raw is different to CM.CMTRT then + # assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY) assign_no_ct( - raw_dataset = MD1, - raw_variable = MDIND, - target_sdtm_var = CMINDC, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMDOSE. Annotation text = If numeric then CM.CMDOSE - if_then_else( - raw_dataset = MD1, - raw_variable = DOS, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = DOS, - condition_operator = "is_numeric", - sub_algorithm = assign_no_ct, # pass the function as the argument - target_sdtm_var = CMDOSE, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMDOSTXT. Annotation text = If character then CM.CMDOSTXT - if_then_else( - raw_dataset = MD1, - raw_variable = DOS, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = DOS, - condition_operator = "is_character", - sub_algorithm = assign_no_ct, - target_sdtm_var = CMDOSETXT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMMODIFY Annotation text = If different to CM.CMTRT then CM.CMMODIFY - if_then_else( - raw_dataset = MD1, - raw_variable = CMMODIFY, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = CMMODIFY, - condition_operator = "diffferent_to", - condition_right_sdtm_variable_domain = CM, - condition_right_sdtm_variable = CMTRT, - sub_algorithm = assign_no_ct, - target_sdtm_var = CMDOSETXT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) + raw_dat = cm_raw, + raw_var = "CMMODIFY", + # add_cond = (cm_raw$CMMODIFY == .data$CMTRT), + tgt_var = "CMMODIFY", + id_vars = oak_id_vars() ) |> - # Derive CMDECOD + # Derive CMDRG assign_no_ct( - raw_dataset = MD1, - raw_variable = CMDECOD, - target_sdtm_var = CMDECOD + raw_dat = cm_raw, + raw_var = "CMDRG", + tgt_var = "CMDRG" ) |> - # Derive CMSTDTC. This function calls create_iso8601 + # Derive CMDRGCD assign_no_ct( - raw_dataset = MD1, - raw_variable = c("MDBD", "MDBTM"), - target_sdtm_var = CMSTDTC, - .format = c("ddmmmyyyy", "HHMM") + raw_dat = cm_raw, + raw_var = "CMDRGCD", + tgt_var = "CMDRGCD" ) |> - # Derive CMENDTC. This function calls create_iso8601 + # Derive CMDECOD assign_no_ct( - raw_dataset = MD1, - raw_variable = c("MDED", "MDETM"), - target_sdtm_var = CMENDTC, - .format = c("ddmmmyyyy", "HHMM") - ) |> - # Derive qualifier CMSTRTPT Annotation text = If checked then CM.CMSTRTPT = 'BEFORE' - if_then_else( - raw_dataset = MD1, - raw_variable = MDPRIOR, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = MDPRIOR, - condition_operator = "if_checked", - sub_algorithm = assign_ct, - target_sdtm_variable_codelist_code = "C66728", - target_sdtm_var = CMSTRTPT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMSTRTPT Annotation text = If checked then CM.CMSTTPT = 'SCREENING' - if_then_else( - raw_dataset = MD1, - raw_variable = MDPRIOR, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = MDPRIOR, - condition_operator = "if_checked", - sub_algorithm = hardcode_no_ct, - target_hardcoded_value = "SCREENING", - target_sdtm_var = CM.CMSTTPT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMENRTPT Annotation text = If checked then CM.CMENRTPT = 'ONGOING' - if_then_else( - raw_dataset = MD1, - raw_variable = MDONG, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = MDONG, - condition_operator = "if_checked", - sub_algorithm = hardcode_ct, - target_hardcoded_value = "ONGOING", - target_sdtm_variable_codelist_code = "C66728", - target_sdtm_var = CMENRTPT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) - ) |> - # Derive qualifier CMENTPT Annotation text = If checked then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' - if_then_else( - raw_dataset = MD1, - raw_variable = MDONG, - condition_left_raw_dataset = MD1, - condition_left_raw_variable = MDONG, - condition_operator = "if_checked", - sub_algorithm = hardcode_no_ct, - target_hardcoded_value = "DATE OF LAST ASSESSMENT", - target_sdtm_var = CMENTPT, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) + raw_dat = cm_raw, + raw_var = CMDECOD, + tgt_var = CMDECOD ) |> - # Derive CMGRPID + # Derive CMPNCD assign_no_ct( - raw_dataset = MD1, - raw_variable = MDNUM, - target_sdtm_var = CMGRPID, - merge_to_topic_by = c(oak_id_vars, - topic_var_source = MDRAW - ) + raw_dat = cm_raw, + raw_var = "CMPNCD", + tgt_var = "CMPNCD" ) |> dplyr::mutate( STUDYID = "test_study", DOMAIN = "CM", - CMCAT = "GENERAL CONMED" + CMCAT = "GENERAL CONMED", + USUBJID = "test_study" || "-" || cm_raw$PATNUM + ) |> + # DERIVE VISIT + assign_ct( + raw_dat = cm_raw, + raw_var = "INSTANCE", + tgt_var = "VISIT", + ct_spec = study_ct, + ct_clst = "VISIT", + id_vars = oak_id_vars() ) |> - derive_usubjid() |> - derive_sequence(keys = c(USUBJID, CMTRT)) |> - derive_visit_visitnum() |> - calculate_study_day( + # DERIVE VISITNUM + assign_ct( + raw_dat = cm_raw, + raw_var = "INSTANCE", + tgt_var = "VISITNUM", + ct_spec = study_ct, + ct_clst = "VISITNUM", + id_vars = oak_id_vars() + ) |> + derive_seq(tgt_var = "VSSEQ", + rec_vars= c("USUBJID", "CMTRT")) |> + derive_study_day( + sdtm_in = .data, dm_domain = dm, - study_day_var = "RFSTDTS", - var_in = CMSTDTC, - target_var = CMSTDY, - merge_key = "USUBJID" + tgdt = "CMENDTC", + refdt = "RFXSTDTC", + study_day_var = "CMENDY" ) |> derive_study_day( - var_in = CMENDTC, - target_var = CMENDY - ) + sdtm_in = .data, + dm_domain = dm, + tgdt = "CMSTDTC", + refdt = "RFXSTDTC", + study_day_var = "CMSTDY" + ) |> + dplyr::select("STUDYID", "USUBJID", everything()) From 8dfa57f03a8b603aa78a62e3892e57c2a6215a0a Mon Sep 17 00:00:00 2001 From: Ramiro Magno Date: Fri, 24 May 2024 01:01:40 +0100 Subject: [PATCH 04/23] Basic support for "conditioned" data frames - Adds a new S3 class (cnd_df) for represented conditioned data frames, i.e. data frames that carry metadata about what records should be used for derivations - Adds support for basic pretty printing of cnd_df objects - Adds a user-facing function for creating such cnd_df objects: `condition_by` - Adds experimental "mutate"-version function for these conditioned data frames: `derive_by_condition()` --- DESCRIPTION | 3 +- NAMESPACE | 4 + R/assertions.R | 16 + R/cnd_df.R | 299 +++++++ man/condition_by.Rd | 27 + man/eval_conditions.Rd | 74 ++ man/new_cnd_df.Rd | 40 + man/rm_cnd_df.Rd | 18 + man/tbl_sum.cnd_df.Rd | 16 + renv/profiles/4.4/renv.lock | 1279 +++++++++++++++++++++++++++++ renv/profiles/4.4/renv/.gitignore | 7 + 11 files changed, 1782 insertions(+), 1 deletion(-) create mode 100644 R/assertions.R create mode 100644 R/cnd_df.R create mode 100644 man/condition_by.Rd create mode 100644 man/eval_conditions.Rd create mode 100644 man/new_cnd_df.Rd create mode 100644 man/rm_cnd_df.Rd create mode 100644 man/tbl_sum.cnd_df.Rd create mode 100644 renv/profiles/4.4/renv.lock create mode 100644 renv/profiles/4.4/renv/.gitignore diff --git a/DESCRIPTION b/DESCRIPTION index 721a589a..4cd995cb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -46,7 +46,8 @@ Imports: tibble, vctrs, readr, - glue + glue, + pillar Suggests: knitr, rmarkdown, diff --git a/NAMESPACE b/NAMESPACE index 41e0d4cd..472cb825 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,10 +1,12 @@ # Generated by roxygen2: do not edit by hand S3method(print,iso8601) +S3method(tbl_sum,cnd_df) export(assign_ct) export(assign_datetime) export(assign_no_ct) export(clear_cache) +export(condition_by) export(create_iso8601) export(ct_map) export(ct_spec_example) @@ -16,6 +18,8 @@ export(hardcode_no_ct) export(problems) export(read_ct_spec) export(read_ct_spec_example) +export(rm_cnd_df) +importFrom(pillar,tbl_sum) importFrom(rlang,"%||%") importFrom(rlang,":=") importFrom(rlang,.data) diff --git a/R/assertions.R b/R/assertions.R new file mode 100644 index 00000000..8228c4ee --- /dev/null +++ b/R/assertions.R @@ -0,0 +1,16 @@ +# Surprisingly, admiraldev doesn't provide `assert_logical_vector`. +assert_logical_vector <- function(arg, optional = FALSE) { + if (optional && is.null(arg)) { + return(invisible(arg)) + } + + if (!is.logical(arg)) { + err_msg <- sprintf( + "`arg` must be a logical vector but is %s.", + admiraldev::what_is_it(arg) + ) + rlang::abort(err_msg) + } + + invisible(arg) +} diff --git a/R/cnd_df.R b/R/cnd_df.R new file mode 100644 index 00000000..f9640294 --- /dev/null +++ b/R/cnd_df.R @@ -0,0 +1,299 @@ +# ------------------------------------------------------------------------------ +# File: cnd_df.R +# Package: sdtm.oak +# Author: Ramiro Magno +# Created: 2024-05-23 +# Last Modified: 2024-05-23 +# ------------------------------------------------------------------------------ +# Description: +# +# This file contains functions and scripts related to the so-called conditioned +# data frames, i.e. those data frames extended with class `cnd_df`. +# +# Functions: +# +# - `new_cnd_df()`: Create a "conditioned data set" (class cnd_df). +# - `is_cnd_df()`: Assess whether the argument is a `cnd_df` data frame. +# - `get_cnd_df_cnd()`: Extract the attribute "cnd" from a `cnd_df` data frame. +# - `get_cnd_df_cnd_sum()`: Extract the attribute "cnd_sum" from a `cnd_df` data frame. +# - `rm_cnd_df()`: De-class a cnd_df data frame. +# - `tbl_sum.cnd_df()`: Provide a tibble header print method for `cnd_df` tibbles. +# - `ctl_new_rowid_pillar.cnd_df()`: A print method for the row ids cnd_df` tibbles. +# - `eval_conditions()`: Find which rows match a set of conditions. +# - `condition_by()`: Create a conditioned data frame (user facing). +# - `derive_by_condition()`: Perform a derivation on a conditioned data frame. + +#' Create a data frame with filtering tags +#' +#' [new_cnd_df()] creates a _conditioned_ data frame, classed `cnd_df`, meaning +#' that this function extends the data frame passed as argument by storing a +#' logical vector `cnd` (as attribute) that marks rows for posterior conditional +#' transformation by methods that support _conditioned_ data frames. +#' +#' @param dat A data frame. +#' @param cnd A logical vector. Length must match the number of rows in `dat`. +#' @param .warn Whether to warn about creating a new _conditioned_ data frame +#' in case that `dat` already is one. +#' +#' @returns A data frame `dat` with the additional class `"cnd_df"` and the +#' following attributes: +#' +#' - `cnd`: The logical vector passed as argument `cnd`: `TRUE` values mark +#' rows in `dat` to be used for transformations; rows marked with `FALSE` are +#' not transformed; and `NA` mark rows whose transformations are to be applied +#' resulting in `NA`. +#' - `cnd_sum`: An integer vector of three elements providing the sum of `TRUE`, +#' `FALSE` and `NA` values in `cnd`, respectively. +#' +#' @examples +#' df <- data.frame(x = 1:3, y = letters[1:3]) +#' sdtm.oak:::new_cnd_df(dat = df, cnd = c(FALSE, NA, TRUE)) +#' +#' @keywords internal +new_cnd_df <- function(dat, cnd, .warn = TRUE) { + + admiraldev::assert_data_frame(dat) + assert_logical_vector(cnd) + + if (!identical(nrow(dat), length(cnd))) { + msg <- c( + "Number of rows in `dat` must match length of `cond`." + ) + rlang::abort(message = msg) + } + + is_cnd_df <- inherits(dat, "cnd_df") + if (.warn && is_cnd_df) { + msg <- "`dat` is already a conditioned data frame (`cnd_df`)." + rlang::warn(message = msg) + } + + if (!is_cnd_df) { + class(dat) <- c("cnd_df", class(dat)) + } + + n_true <- sum(cnd, na.rm = TRUE) + n_false <- sum(!cnd, na.rm = TRUE) + n_na <- length(cnd) - (n_true + n_false) + cnd_sum <- c(n_true = n_true, n_false = n_false, n_na = n_na) + + attr(dat, "cnd") <- cnd + attr(dat, "cnd_sum") <- cnd_sum + + return(dat) +} + +is_cnd_df <- function(dat) { + inherits(dat, "cnd_df") +} + +get_cnd_df_cnd <- function(dat) { + if (is_cnd_df(dat)) { + attr(dat, "cnd") + } else { + NULL + } +} + +get_cnd_df_cnd_sum <- function(dat) { + if (is_cnd_df(dat)) { + attr(dat, "cnd_sum") + } else { + NULL + } +} + +#' Remove the cnd_df class from a data frame +#' +#' This function removes the 'cnd_df' class, along with its attributes, if +#' applicable. +#' +#' @param dat A data frame. +#' @return The input `dat` without the 'cnd_df' class. +#' +#' @export +rm_cnd_df <- function(dat) { + if (is_cnd_df(dat)) { + class(dat) <- class(dat)[class(dat) != "cnd_df"] + attr(dat, "cnd") <- NULL + attr(dat, "cnd_sum") <- NULL + } + return(dat) +} + +#' Print +#' +#' Blah +#' +#' @param x A conditioned tibble of class 'cnd_df'. +#' @param ... Additional arguments passed to the default print method. +#' +#' @importFrom pillar tbl_sum +#' @export +tbl_sum.cnd_df <- function(x, ...) { + default_header <- NextMethod() + + tally <- get_cnd_df_cnd_sum(x) + h2 <- sprintf("%d/%d/%d", tally[1], tally[2], tally[3]) + c(default_header, "Cond. tbl" = h2) +} + +lgl_to_chr <- function(x) { + ifelse(is.na(x), "-", ifelse(x, "T", "F")) +} + +ctl_new_rowid_pillar.cnd_df <- function(controller, x, width, ...) { + + out <- NextMethod() + n_row <- nrow(x) + idx <- seq_len(n_row) + i <- sprintf("%d", idx) + i_width <- nchar(as.character(i)) + i_max_width <- max(i_width) + max_width <- i_max_width + 2 + ws <- strrep(" ", max_width - i_width - 1) + abb_lgl <- lgl_to_chr(attr(controller, "cnd")[idx]) + + row_ids <- paste0(i, ws, abb_lgl) + width <- max(nchar(as.character(row_ids))) + pillar::new_pillar( + list( + title = out$title, + type = out$type, + data = pillar::pillar_component( + pillar::new_pillar_shaft(list(row_ids = row_ids), + width = width, + class = "pillar_rif_shaft" + ) + ) + ), + width = width + ) +} + +#' Evaluate conditions +#' +#' @description +#' [eval_conditions()] evaluates a set of conditions in the context of a +#' data frame and an optional environment. +#' +#' The utility of this function is to provide an easy way to generate a logical +#' vector of matching records from a set of logical conditions involving +#' variables in a data frame (`dat`) and optionally in a supplementary +#' environment (`.env`). The set of logical conditions are provided as +#' expressions to be evaluated in the context of `dat` and `.env`. +#' +#' Variables are looked up in `dat`, then in `.env`, then in the calling +#' function's environment, followed by its parent environments. +#' +#' @param dat A data frame +#' @param ... A set of logical conditions, e.g. `y & z, x | z` (`x`, `y`, `z` +#' would have to exist either as columns in `dat` or in the enviroment +#' `.env`). If multiple expressions are included, they are combined with the +#' `&` operator. +#' @param .na Return value to be used when the conditions evalute to `NA`. +#' @param .env An optional environment to look for variables involved in logical +#' expression passed in `...`. A data frame or a list can also be passed that +#' will be coerced to an environment internally. +#' +#' @returns A logical vector reflecting matching rows in `dat`. +#' +#' @examples +#' # Create a sample data frame +#' df <- data.frame( +#' x = c(1, 2, 3, 4, 5), +#' y = c(TRUE, FALSE, TRUE, FALSE, TRUE), +#' z = c("a", "b", "a", "b", "a") +#' ) +#' +#' # Simple condition on one column +#' sdtm.oak:::eval_conditions(df, x > 2) +#' +#' # Combined conditions on multiple columns +#' sdtm.oak:::eval_conditions(df, x > 2, y) +#' +#' # Using conditions with NA handling +#' df_with_na <- data.frame( +#' x = c(1, 2, NA, 4, 5), +#' y = c(TRUE, FALSE, TRUE, FALSE, TRUE) +#' ) +#' sdtm.oak:::eval_conditions(df_with_na, x > 2, .na = FALSE) +#' +#' # The environment where `eval_conditions()` is called is also inspected +#' # when evaluating conditions in `...`. +#' w <- 1 +#' sdtm.oak:::eval_conditions(df, x > w) +#' +#' # Using an environment +#' env <- rlang::env(w = 2) +#' sdtm.oak:::eval_conditions(df, x > w, .env = env) +#' +#' # In place of an environment, you may alternatively pass a list or data frame. +#' sdtm.oak:::eval_conditions(df, x > w, .env = list(w = 3)) +#' sdtm.oak:::eval_conditions(df, x > w, .env = tibble::tibble(w = 4)) +#' +#' @keywords internal +eval_conditions <- function(dat, + ..., + .na = NA, + .env = rlang::env()) { + + conditions <- rlang::enexprs(...) + + # List (or data frame). + if (is.list(.env)) { + .env <- rlang::as_environment(.env, parent = rlang::env()) + } + + lgl_vctrs <- + conditions |> + purrr::map(~ rlang::eval_tidy(.x, dat, env = .env)) |> + purrr::map(~ dplyr::if_else(is.na(.x), .na, .x)) + + cnd <- purrr::reduce(lgl_vctrs, `&`, .init = rep(TRUE, nrow(dat))) + + cnd +} + +#' Condition a data set based on specified conditions +#' +#' This function tags records in a data set, indicating which rows match the +#' specified conditions. +#' +#' @param dat A tibble. +#' @param ... Conditions to filter the tibble. +#' @return A tibble with an additional class 'cnd_df' and a logical vector +#' attribute indicating matching rows. +#' @param .na Return value to be used when the conditions evalute to `NA`. +#' @param .env An optional environment to look for variables involved in logical +#' expression passed in `...`. A data frame or a list can also be passed that +#' will be coerced to an environment internally. +#' +#' @export +condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { + + if (is_cnd_df(dat)) { + rlang::warn( + c("`dat` is already a conditioned data frame (`cnd_df`).", + "The previous condition will be replaced by the new one.") + ) + } + + cnd <- eval_conditions(dat = dat, ..., .na = .na, .env = .env) + new_cnd_df(dat, cnd = cnd, .warn = FALSE) +} + +#' @keywords internal +derive_by_condition <- function(dat, ...) { + + cnd <- get_cnd_df_cnd(dat) + derivations <- rlang::enquos(...) + derived_vars <- names(derivations) + + lst <- purrr::map(derivations, ~ rlang::expr(dplyr::if_else({{cnd}}, !!.x, NA))) + lst <- rlang::set_names(lst, derived_vars) + dat2 <- dplyr::mutate({{dat}}, !!!lst) + rm_cnd_df(dat2) +} + + diff --git a/man/condition_by.Rd b/man/condition_by.Rd new file mode 100644 index 00000000..f3d0cf7e --- /dev/null +++ b/man/condition_by.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{condition_by} +\alias{condition_by} +\title{Condition a data set based on specified conditions} +\usage{ +condition_by(dat, ..., .na = NA, .env = rlang::env()) +} +\arguments{ +\item{dat}{A tibble.} + +\item{...}{Conditions to filter the tibble.} + +\item{.na}{Return value to be used when the conditions evalute to \code{NA}.} + +\item{.env}{An optional environment to look for variables involved in logical +expression passed in \code{...}. A data frame or a list can also be passed that +will be coerced to an environment internally.} +} +\value{ +A tibble with an additional class 'cnd_df' and a logical vector +attribute indicating matching rows. +} +\description{ +This function tags records in a data set, indicating which rows match the +specified conditions. +} diff --git a/man/eval_conditions.Rd b/man/eval_conditions.Rd new file mode 100644 index 00000000..3de50b96 --- /dev/null +++ b/man/eval_conditions.Rd @@ -0,0 +1,74 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{eval_conditions} +\alias{eval_conditions} +\title{Evaluate conditions} +\usage{ +eval_conditions(dat, ..., .na = NA, .env = rlang::env()) +} +\arguments{ +\item{dat}{A data frame} + +\item{...}{A set of logical conditions, e.g. \verb{y & z, x | z} (\code{x}, \code{y}, \code{z} +would have to exist either as columns in \code{dat} or in the enviroment +\code{.env}). If multiple expressions are included, they are combined with the +\code{&} operator.} + +\item{.na}{Return value to be used when the conditions evalute to \code{NA}.} + +\item{.env}{An optional environment to look for variables involved in logical +expression passed in \code{...}. A data frame or a list can also be passed that +will be coerced to an environment internally.} +} +\value{ +A logical vector reflecting matching rows in \code{dat}. +} +\description{ +\code{\link[=eval_conditions]{eval_conditions()}} evaluates a set of conditions in the context of a +data frame and an optional environment. + +The utility of this function is to provide an easy way to generate a logical +vector of matching records from a set of logical conditions involving +variables in a data frame (\code{dat}) and optionally in a supplementary +environment (\code{.env}). The set of logical conditions are provided as +expressions to be evaluated in the context of \code{dat} and \code{.env}. + +Variables are looked up in \code{dat}, then in \code{.env}, then in the calling +function's environment, followed by its parent environments. +} +\examples{ +# Create a sample data frame +df <- data.frame( + x = c(1, 2, 3, 4, 5), + y = c(TRUE, FALSE, TRUE, FALSE, TRUE), + z = c("a", "b", "a", "b", "a") +) + +# Simple condition on one column +sdtm.oak:::eval_conditions(df, x > 2) + +# Combined conditions on multiple columns +sdtm.oak:::eval_conditions(df, x > 2, y) + +# Using conditions with NA handling +df_with_na <- data.frame( + x = c(1, 2, NA, 4, 5), + y = c(TRUE, FALSE, TRUE, FALSE, TRUE) +) +sdtm.oak:::eval_conditions(df_with_na, x > 2, .na = FALSE) + +# The environment where `eval_conditions()` is called is also inspected +# when evaluating conditions in `...`. +w <- 1 +sdtm.oak:::eval_conditions(df, x > w) + +# Using an environment +env <- rlang::env(w = 2) +sdtm.oak:::eval_conditions(df, x > w, .env = env) + +# In place of an environment, you may alternatively pass a list or data frame. +sdtm.oak:::eval_conditions(df, x > w, .env = list(w = 3)) +sdtm.oak:::eval_conditions(df, x > w, .env = tibble::tibble(w = 4)) + +} +\keyword{internal} diff --git a/man/new_cnd_df.Rd b/man/new_cnd_df.Rd new file mode 100644 index 00000000..f40b140b --- /dev/null +++ b/man/new_cnd_df.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{new_cnd_df} +\alias{new_cnd_df} +\title{Create a data frame with filtering tags} +\usage{ +new_cnd_df(dat, cnd, .warn = TRUE) +} +\arguments{ +\item{dat}{A data frame.} + +\item{cnd}{A logical vector. Length must match the number of rows in \code{dat}.} + +\item{.warn}{Whether to warn about creating a new \emph{conditioned} data frame +in case that \code{dat} already is one.} +} +\value{ +A data frame \code{dat} with the additional class \code{"cnd_df"} and the +following attributes: +\itemize{ +\item \code{cnd}: The logical vector passed as argument \code{cnd}: \code{TRUE} values mark +rows in \code{dat} to be used for transformations; rows marked with \code{FALSE} are +not transformed; and \code{NA} mark rows whose transformations are to be applied +resulting in \code{NA}. +\item \code{cnd_sum}: An integer vector of three elements providing the sum of \code{TRUE}, +\code{FALSE} and \code{NA} values in \code{cnd}, respectively. +} +} +\description{ +\code{\link[=new_cnd_df]{new_cnd_df()}} creates a \emph{conditioned} data frame, classed \code{cnd_df}, meaning +that this function extends the data frame passed as argument by storing a +logical vector \code{cnd} (as attribute) that marks rows for posterior conditional +transformation by methods that support \emph{conditioned} data frames. +} +\examples{ +df <- data.frame(x = 1:3, y = letters[1:3]) +sdtm.oak:::new_cnd_df(dat = df, cnd = c(FALSE, NA, TRUE)) + +} +\keyword{internal} diff --git a/man/rm_cnd_df.Rd b/man/rm_cnd_df.Rd new file mode 100644 index 00000000..21f096b6 --- /dev/null +++ b/man/rm_cnd_df.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{rm_cnd_df} +\alias{rm_cnd_df} +\title{Remove the cnd_df class from a data frame} +\usage{ +rm_cnd_df(dat) +} +\arguments{ +\item{dat}{A data frame.} +} +\value{ +The input \code{dat} without the 'cnd_df' class. +} +\description{ +This function removes the 'cnd_df' class, along with its attributes, if +applicable. +} diff --git a/man/tbl_sum.cnd_df.Rd b/man/tbl_sum.cnd_df.Rd new file mode 100644 index 00000000..5a0f301f --- /dev/null +++ b/man/tbl_sum.cnd_df.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{tbl_sum.cnd_df} +\alias{tbl_sum.cnd_df} +\title{Print} +\usage{ +\method{tbl_sum}{cnd_df}(x, ...) +} +\arguments{ +\item{x}{A conditioned tibble of class 'cnd_df'.} + +\item{...}{Additional arguments passed to the default print method.} +} +\description{ +Blah +} diff --git a/renv/profiles/4.4/renv.lock b/renv/profiles/4.4/renv.lock new file mode 100644 index 00000000..aafeeb4b --- /dev/null +++ b/renv/profiles/4.4/renv.lock @@ -0,0 +1,1279 @@ +{ + "R": { + "Version": "4.4.0", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods", + "utils" + ], + "Hash": "5ea2700d21e038ace58269ecdbeb9ec0" + }, + "admiraldev": { + "Package": "admiraldev", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "dplyr", + "hms", + "lifecycle", + "lubridate", + "magrittr", + "purrr", + "rlang", + "stringr", + "tidyr", + "tidyselect" + ], + "Hash": "4ab0476ca36f502f6cdd2080f8d0f261" + }, + "askpass": { + "Package": "askpass", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "sys" + ], + "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" + }, + "assertthat": { + "Package": "assertthat", + "Version": "0.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "tools" + ], + "Hash": "50c838a310445e954bc13f26f26a6ecf" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bit": { + "Package": "bit", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "d242abec29412ce988848d0294b208fd" + }, + "bit64": { + "Package": "bit64", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "bit", + "methods", + "stats", + "utils" + ], + "Hash": "9fe98599ca456d6552421db0d6772d8f" + }, + "brio": { + "Package": "brio", + "Version": "1.1.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "c1ee497a6d999947c2c224ae46799b1a" + }, + "bslib": { + "Package": "bslib", + "Version": "0.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "fastmap", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "lifecycle", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "8644cc53f43828f19133548195d7e59e" + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.8", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "c35768291560ce302c0a6589f92e837d" + }, + "callr": { + "Package": "callr", + "Version": "3.7.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "processx", + "utils" + ], + "Hash": "d7e13f49c19103ece9e58ad2d83a7354" + }, + "cli": { + "Package": "cli", + "Version": "3.6.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "utils" + ], + "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + }, + "clipr": { + "Package": "clipr", + "Version": "0.8.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "3f038e5ac7f41d4ac41ce658c85e3042" + }, + "commonmark": { + "Package": "commonmark", + "Version": "1.9.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5d8225445acb167abf7797de48b2ee3c" + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.4.7", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "5a295d7d963cc5035284dcdbaf334f4e" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "grDevices", + "methods", + "utils" + ], + "Hash": "e8a1e41acf02548751f45c718d55aa6a" + }, + "credentials": { + "Package": "credentials", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass", + "curl", + "jsonlite", + "openssl", + "sys" + ], + "Hash": "c7844b32098dcbd1c59cbd8dddb4ecc6" + }, + "curl": { + "Package": "curl", + "Version": "5.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" + }, + "desc": { + "Package": "desc", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "utils" + ], + "Hash": "99b79fcbd6c4d1ce087f5c5c758b384f" + }, + "diffobj": { + "Package": "diffobj", + "Version": "0.3.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "crayon", + "methods", + "stats", + "tools", + "utils" + ], + "Hash": "bcaa8b95f8d7d01a5dedfd959ce88ab8" + }, + "digest": { + "Package": "digest", + "Version": "0.6.35", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" + }, + "downlit": { + "Package": "downlit", + "Version": "0.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "brio", + "desc", + "digest", + "evaluate", + "fansi", + "memoise", + "rlang", + "vctrs", + "withr", + "yaml" + ], + "Hash": "14fa1f248b60ed67e1f5418391a17b14" + }, + "dplyr": { + "Package": "dplyr", + "Version": "1.1.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "cli", + "generics", + "glue", + "lifecycle", + "magrittr", + "methods", + "pillar", + "rlang", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.23", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" + }, + "fansi": { + "Package": "fansi", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "grDevices", + "utils" + ], + "Hash": "962174cf2aeb5b9eea581522286a911f" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "f7736a18de97dea803bde0a2daaafb27" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + }, + "fs": { + "Package": "fs", + "Version": "1.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" + }, + "generics": { + "Package": "generics", + "Version": "0.1.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15e9634c0fcd294799e9b2e929ed1b86" + }, + "gert": { + "Package": "gert", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass", + "credentials", + "openssl", + "rstudioapi", + "sys", + "zip" + ], + "Hash": "f70d3fe2d9e7654213a946963d1591eb" + }, + "gh": { + "Package": "gh", + "Version": "1.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "gitcreds", + "glue", + "httr2", + "ini", + "jsonlite", + "lifecycle", + "rlang" + ], + "Hash": "fbbbc48eba7a6626a08bb365e44b563b" + }, + "gitcreds": { + "Package": "gitcreds", + "Version": "0.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "ab08ac61f3e1be454ae21911eb8bc2fe" + }, + "glue": { + "Package": "glue", + "Version": "1.7.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "e0b3a53876554bd45879e596cdb10a52" + }, + "highr": { + "Package": "highr", + "Version": "0.10", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "06230136b2d2b9ba5805e1963fa6e890" + }, + "hms": { + "Package": "hms", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "lifecycle", + "methods", + "pkgconfig", + "rlang", + "vctrs" + ], + "Hash": "b59377caa7ed00fa41808342002138f9" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "81d371a9cc60640e74e4ab6ac46dcedc" + }, + "httr": { + "Package": "httr", + "Version": "1.4.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "curl", + "jsonlite", + "mime", + "openssl" + ], + "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" + }, + "httr2": { + "Package": "httr2", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "curl", + "glue", + "lifecycle", + "magrittr", + "openssl", + "rappdirs", + "rlang", + "vctrs", + "withr" + ], + "Hash": "03d741c92fda96d98c3a3f22494e3b4a" + }, + "hunspell": { + "Package": "hunspell", + "Version": "3.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "Rcpp", + "digest" + ], + "Hash": "e957e989ea17f937964f0d46b0f0bca0" + }, + "ini": { + "Package": "ini", + "Version": "0.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6154ec2223172bce8162d4153cda21f7" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods" + ], + "Hash": "e1b9c55281c5adc4dd113652d9e26768" + }, + "knitr": { + "Package": "knitr", + "Version": "1.46", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "6e008ab1d696a5283c79765fa7b56b47" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "b8552d117e1b808b09a832f589b79035" + }, + "lubridate": { + "Package": "lubridate", + "Version": "1.9.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "generics", + "methods", + "timechange" + ], + "Hash": "680ad542fbcf801442c83a6ac5a2126c" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "7ce2733a9826b3aeb1775d56fd305472" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "openssl": { + "Package": "openssl", + "Version": "2.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "askpass" + ], + "Hash": "2bcca3848e4734eb3b16103bc9aa4b8e" + }, + "pillar": { + "Package": "pillar", + "Version": "1.9.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "cli", + "fansi", + "glue", + "lifecycle", + "rlang", + "utf8", + "utils", + "vctrs" + ], + "Hash": "15da5a8412f317beeee6175fbc76f4bb" + }, + "pkgbuild": { + "Package": "pkgbuild", + "Version": "1.4.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "callr", + "cli", + "desc", + "processx" + ], + "Hash": "a29e8e134a460a01e0ca67a4763c595b" + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "01f28d4278f15c76cddbea05899c5d6f" + }, + "pkgdown": { + "Package": "pkgdown", + "Version": "2.0.9", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "callr", + "cli", + "desc", + "digest", + "downlit", + "fs", + "httr", + "jsonlite", + "magrittr", + "memoise", + "purrr", + "ragg", + "rlang", + "rmarkdown", + "tibble", + "whisker", + "withr", + "xml2", + "yaml" + ], + "Hash": "8bf1151ed1a48328d71b937e651117a6" + }, + "pkgload": { + "Package": "pkgload", + "Version": "1.3.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "crayon", + "desc", + "fs", + "glue", + "methods", + "pkgbuild", + "rlang", + "rprojroot", + "utils", + "withr" + ], + "Hash": "876c618df5ae610be84356d5d7a5d124" + }, + "praise": { + "Package": "praise", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a555924add98c99d2f411e37e7d25e9f" + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "6b01fc98b1e86c4f705ce9dcfd2f57c7" + }, + "processx": { + "Package": "processx", + "Version": "3.8.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "ps", + "utils" + ], + "Hash": "0c90a7d71988856bad2a2a45dd871bb9" + }, + "progress": { + "Package": "progress", + "Version": "1.2.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "f4625e061cb2865f111b47ff163a5ca6" + }, + "ps": { + "Package": "ps", + "Version": "1.7.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "dd2b9319ee0656c8acf45c7f40c59de7" + }, + "purrr": { + "Package": "purrr", + "Version": "1.0.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "lifecycle", + "magrittr", + "rlang", + "vctrs" + ], + "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" + }, + "ragg": { + "Package": "ragg", + "Version": "1.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "systemfonts", + "textshaping" + ], + "Hash": "e3087db406e079a8a2fd87f413918ed3" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "readr": { + "Package": "readr", + "Version": "2.1.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "cli", + "clipr", + "cpp11", + "crayon", + "hms", + "lifecycle", + "methods", + "rlang", + "tibble", + "tzdb", + "utils", + "vroom" + ], + "Hash": "9de96463d2117f6ac49980577939dfb3" + }, + "rematch2": { + "Package": "rematch2", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "tibble" + ], + "Hash": "76c9e04c712a05848ae7a23d2f170a40" + }, + "renv": { + "Package": "renv", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "41b847654f567341725473431dd0d5ab" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "utils" + ], + "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.26", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "9b148e7f95d33aac01f31282d49e4f44" + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.16.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "96710351d642b70e8f02ddeb237c46a7" + }, + "sass": { + "Package": "sass", + "Version": "0.4.9", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "d53dbfddf695303ea4ad66f86e99b95d" + }, + "spelling": { + "Package": "spelling", + "Version": "2.3.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "commonmark", + "hunspell", + "knitr", + "xml2" + ], + "Hash": "632e9e83d3dc774d361b9415b15642bb" + }, + "stringi": { + "Package": "stringi", + "Version": "1.8.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "stats", + "tools", + "utils" + ], + "Hash": "058aebddea264f4c99401515182e656a" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ], + "Hash": "960e2ae9e09656611e0b8214ad543207" + }, + "sys": { + "Package": "sys", + "Version": "3.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" + }, + "systemfonts": { + "Package": "systemfonts", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cpp11", + "lifecycle" + ], + "Hash": "213b6b8ed5afbf934843e6c3b090d418" + }, + "testthat": { + "Package": "testthat", + "Version": "3.2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "brio", + "callr", + "cli", + "desc", + "digest", + "evaluate", + "jsonlite", + "lifecycle", + "magrittr", + "methods", + "pkgload", + "praise", + "processx", + "ps", + "rlang", + "utils", + "waldo", + "withr" + ], + "Hash": "3f6e7e5e2220856ff865e4834766bf2b" + }, + "textshaping": { + "Package": "textshaping", + "Version": "0.3.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cpp11", + "systemfonts" + ], + "Hash": "997aac9ad649e0ef3b97f96cddd5622b" + }, + "tibble": { + "Package": "tibble", + "Version": "3.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "fansi", + "lifecycle", + "magrittr", + "methods", + "pillar", + "pkgconfig", + "rlang", + "utils", + "vctrs" + ], + "Hash": "a84e2cc86d07289b3b6f5069df7a004c" + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "cpp11", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "915fb7ce036c22a6a33b5a8adb712eb1" + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang", + "vctrs", + "withr" + ], + "Hash": "829f27b9c4919c16b593794a6344d6c0" + }, + "timechange": { + "Package": "timechange", + "Version": "0.3.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "c5f3c201b931cd6474d17d8700ccb1c8" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.51", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "d44e2fcd2e4e076f0aac540208559d1d" + }, + "tzdb": { + "Package": "tzdb", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "f561504ec2897f4d46f0c7657e488ae1" + }, + "usethis": { + "Package": "usethis", + "Version": "2.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "clipr", + "crayon", + "curl", + "desc", + "fs", + "gert", + "gh", + "glue", + "jsonlite", + "lifecycle", + "purrr", + "rappdirs", + "rlang", + "rprojroot", + "rstudioapi", + "stats", + "utils", + "whisker", + "withr", + "yaml" + ], + "Hash": "d524fd42c517035027f866064417d7e6" + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "62b65c52671e6665f803ff02954446e9" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "c03fa420630029418f7e6da3667aac4a" + }, + "vroom": { + "Package": "vroom", + "Version": "1.6.5", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "bit64", + "cli", + "cpp11", + "crayon", + "glue", + "hms", + "lifecycle", + "methods", + "progress", + "rlang", + "stats", + "tibble", + "tidyselect", + "tzdb", + "vctrs", + "withr" + ], + "Hash": "390f9315bc0025be03012054103d227c" + }, + "waldo": { + "Package": "waldo", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "diffobj", + "fansi", + "glue", + "methods", + "rematch2", + "rlang", + "tibble" + ], + "Hash": "c7d3fd6d29ab077cbac8f0e2751449e6" + }, + "whisker": { + "Package": "whisker", + "Version": "0.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c6abfa47a46d281a7d5159d0a8891e88" + }, + "withr": { + "Package": "withr", + "Version": "3.0.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "grDevices", + "graphics" + ], + "Hash": "d31b6c62c10dcf11ec530ca6b0dd5d35" + }, + "xfun": { + "Package": "xfun", + "Version": "0.44", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "stats", + "tools" + ], + "Hash": "317a0538d32f4a009658bcedb7923f4b" + }, + "xml2": { + "Package": "xml2", + "Version": "1.3.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "methods", + "rlang" + ], + "Hash": "1d0336142f4cd25d8d23cd3ba7a8fb61" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.8", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "29240487a071f535f5e5d5a323b7afbd" + }, + "zip": { + "Package": "zip", + "Version": "2.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fcc4bd8e6da2d2011eb64a5e5cc685ab" + } + } +} diff --git a/renv/profiles/4.4/renv/.gitignore b/renv/profiles/4.4/renv/.gitignore new file mode 100644 index 00000000..0ec0cbba --- /dev/null +++ b/renv/profiles/4.4/renv/.gitignore @@ -0,0 +1,7 @@ +library/ +local/ +cellar/ +lock/ +python/ +sandbox/ +staging/ From d08794b4519f84dcc0880196f9bb99024a64e688 Mon Sep 17 00:00:00 2001 From: Ramiro Magno Date: Sun, 26 May 2024 01:54:45 +0100 Subject: [PATCH 05/23] Basic support for conditioned data sets --- NAMESPACE | 4 ++ R/assign.R | 6 ++- R/assign_datetime.R | 7 ++- R/cnd_df.R | 39 +++++++++------- R/hardcode.R | 10 +++-- man/condition_by.Rd | 4 +- man/eval_conditions.Rd | 4 +- man/rm_cnd_df.Rd | 6 +-- man/tbl_sum.cnd_df.Rd | 2 +- tests/testthat/test-hardcode.R | 81 ++++++++++++++++++++++++++++++++++ 10 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 tests/testthat/test-hardcode.R diff --git a/NAMESPACE b/NAMESPACE index 472cb825..5ec1b0bd 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,7 @@ # Generated by roxygen2: do not edit by hand +S3method(ctl_new_rowid_pillar,cnd_df) +S3method(mutate,cnd_df) S3method(print,iso8601) S3method(tbl_sum,cnd_df) export(assign_ct) @@ -19,6 +21,8 @@ export(problems) export(read_ct_spec) export(read_ct_spec_example) export(rm_cnd_df) +importFrom(dplyr,mutate) +importFrom(pillar,ctl_new_rowid_pillar) importFrom(pillar,tbl_sum) importFrom(rlang,"%||%") importFrom(rlang,":=") diff --git a/R/assign.R b/R/assign.R index a91eacaf..c9c1d831 100644 --- a/R/assign.R +++ b/R/assign.R @@ -61,13 +61,17 @@ sdtm_assign <- function(raw_dat, der_dat <- raw_dat |> dplyr::select(c(id_vars, raw_var)) |> - dplyr::mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() + mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() dplyr::select(-rlang::sym(raw_var)) # If a target dataset is supplied, then join the so far derived dataset with # the target dataset (`tgt_dat`), otherwise leave it be. der_dat <- if (!is.null(tgt_dat)) { + # If variable `tgt_var` exists in `tgt_dat` remove it as we want to + # keep the derived variable in `der_dat`. + tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) + der_dat |> dplyr::right_join(y = tgt_dat, by = id_vars) |> dplyr::relocate(tgt_var, .after = dplyr::last_col()) diff --git a/R/assign_datetime.R b/R/assign_datetime.R index 4622f579..d8d4ec8b 100644 --- a/R/assign_datetime.R +++ b/R/assign_datetime.R @@ -179,12 +179,15 @@ assign_datetime <- der_dat <- raw_dat |> - dplyr::select(c(id_vars, raw_var)) |> + dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |> dplyr::mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() - dplyr::select(-raw_var) + dplyr::select(-dplyr::any_of(raw_var)) der_dat <- if (!is.null(tgt_dat)) { + # If variable `tgt_var` exists in `tgt_dat` remove it as we want to + # keep the derived variable in `der_dat`. + tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) der_dat |> dplyr::right_join(y = tgt_dat, by = id_vars) |> dplyr::relocate(tgt_var, .after = dplyr::last_col()) diff --git a/R/cnd_df.R b/R/cnd_df.R index f9640294..9ef23a83 100644 --- a/R/cnd_df.R +++ b/R/cnd_df.R @@ -69,6 +69,7 @@ new_cnd_df <- function(dat, cnd, .warn = TRUE) { } if (!is_cnd_df) { + dat <- tibble::as_tibble(dat) class(dat) <- c("cnd_df", class(dat)) } @@ -103,13 +104,13 @@ get_cnd_df_cnd_sum <- function(dat) { } } -#' Remove the cnd_df class from a data frame +#' Remove the `cnd_df` class from a data frame #' -#' This function removes the 'cnd_df' class, along with its attributes, if +#' This function removes the `cnd_df` class, along with its attributes, if #' applicable. #' #' @param dat A data frame. -#' @return The input `dat` without the 'cnd_df' class. +#' @return The input `dat` without the `cnd_df` class. #' #' @export rm_cnd_df <- function(dat) { @@ -125,7 +126,7 @@ rm_cnd_df <- function(dat) { #' #' Blah #' -#' @param x A conditioned tibble of class 'cnd_df'. +#' @param x A conditioned tibble of class `cnd_df`. #' @param ... Additional arguments passed to the default print method. #' #' @importFrom pillar tbl_sum @@ -142,6 +143,8 @@ lgl_to_chr <- function(x) { ifelse(is.na(x), "-", ifelse(x, "T", "F")) } +#' @importFrom pillar ctl_new_rowid_pillar +#' @export ctl_new_rowid_pillar.cnd_df <- function(controller, x, width, ...) { out <- NextMethod() @@ -188,10 +191,10 @@ ctl_new_rowid_pillar.cnd_df <- function(controller, x, width, ...) { #' #' @param dat A data frame #' @param ... A set of logical conditions, e.g. `y & z, x | z` (`x`, `y`, `z` -#' would have to exist either as columns in `dat` or in the enviroment +#' would have to exist either as columns in `dat` or in the environment #' `.env`). If multiple expressions are included, they are combined with the #' `&` operator. -#' @param .na Return value to be used when the conditions evalute to `NA`. +#' @param .na Return value to be used when the conditions evaluate to `NA`. #' @param .env An optional environment to look for variables involved in logical #' expression passed in `...`. A data frame or a list can also be passed that #' will be coerced to an environment internally. @@ -262,9 +265,9 @@ eval_conditions <- function(dat, #' #' @param dat A tibble. #' @param ... Conditions to filter the tibble. -#' @return A tibble with an additional class 'cnd_df' and a logical vector +#' @return A tibble with an additional class `cnd_df` and a logical vector #' attribute indicating matching rows. -#' @param .na Return value to be used when the conditions evalute to `NA`. +#' @param .na Return value to be used when the conditions evaluate to `NA`. #' @param .env An optional environment to look for variables involved in logical #' expression passed in `...`. A data frame or a list can also be passed that #' will be coerced to an environment internally. @@ -283,17 +286,23 @@ condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { new_cnd_df(dat, cnd = cnd, .warn = FALSE) } -#' @keywords internal -derive_by_condition <- function(dat, ...) { +#' @importFrom dplyr mutate +#' @export +mutate.cnd_df <- function(.data, + ..., + .by = NULL, + .keep = c("all", "used", "unused", "none"), + .before = NULL, + .after = NULL) { + + cnd <- get_cnd_df_cnd(.data) + dat <- rm_cnd_df(.data) # avoids recursive S3 method dispatch. - cnd <- get_cnd_df_cnd(dat) derivations <- rlang::enquos(...) derived_vars <- names(derivations) lst <- purrr::map(derivations, ~ rlang::expr(dplyr::if_else({{cnd}}, !!.x, NA))) lst <- rlang::set_names(lst, derived_vars) - dat2 <- dplyr::mutate({{dat}}, !!!lst) - rm_cnd_df(dat2) -} - + dplyr::mutate(dat, !!!lst) +} diff --git a/R/hardcode.R b/R/hardcode.R index 31938689..ffce1bd7 100644 --- a/R/hardcode.R +++ b/R/hardcode.R @@ -63,14 +63,18 @@ sdtm_hardcode <- function(raw_dat, # `der_dat`: derived dataset. der_dat <- raw_dat |> - dplyr::select(c(id_vars, raw_var)) |> - dplyr::mutate("{tgt_var}" := recode(x = !!rlang::sym(raw_var), to = tgt_val)) |> # nolint object_name_linter() - dplyr::select(-rlang::sym(raw_var)) + dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |> + mutate("{tgt_var}" := recode(x = !!rlang::sym(raw_var), to = tgt_val)) |> # nolint object_name_linter() + dplyr::select(-dplyr::any_of(raw_var)) # If a target dataset is supplied, then join the so far derived dataset with # the target dataset (`tgt_dat`), otherwise leave it be. der_dat <- if (!is.null(tgt_dat)) { + # If variable `tgt_var` exists in `tgt_dat` remove it as we want to + # keep the derived variable in `der_dat`. + tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) + der_dat |> dplyr::right_join(y = tgt_dat, by = id_vars) |> dplyr::relocate(tgt_var, .after = dplyr::last_col()) diff --git a/man/condition_by.Rd b/man/condition_by.Rd index f3d0cf7e..e1b7cb2a 100644 --- a/man/condition_by.Rd +++ b/man/condition_by.Rd @@ -11,14 +11,14 @@ condition_by(dat, ..., .na = NA, .env = rlang::env()) \item{...}{Conditions to filter the tibble.} -\item{.na}{Return value to be used when the conditions evalute to \code{NA}.} +\item{.na}{Return value to be used when the conditions evaluate to \code{NA}.} \item{.env}{An optional environment to look for variables involved in logical expression passed in \code{...}. A data frame or a list can also be passed that will be coerced to an environment internally.} } \value{ -A tibble with an additional class 'cnd_df' and a logical vector +A tibble with an additional class \code{cnd_df} and a logical vector attribute indicating matching rows. } \description{ diff --git a/man/eval_conditions.Rd b/man/eval_conditions.Rd index 3de50b96..ce5286d4 100644 --- a/man/eval_conditions.Rd +++ b/man/eval_conditions.Rd @@ -10,11 +10,11 @@ eval_conditions(dat, ..., .na = NA, .env = rlang::env()) \item{dat}{A data frame} \item{...}{A set of logical conditions, e.g. \verb{y & z, x | z} (\code{x}, \code{y}, \code{z} -would have to exist either as columns in \code{dat} or in the enviroment +would have to exist either as columns in \code{dat} or in the environment \code{.env}). If multiple expressions are included, they are combined with the \code{&} operator.} -\item{.na}{Return value to be used when the conditions evalute to \code{NA}.} +\item{.na}{Return value to be used when the conditions evaluate to \code{NA}.} \item{.env}{An optional environment to look for variables involved in logical expression passed in \code{...}. A data frame or a list can also be passed that diff --git a/man/rm_cnd_df.Rd b/man/rm_cnd_df.Rd index 21f096b6..531c972d 100644 --- a/man/rm_cnd_df.Rd +++ b/man/rm_cnd_df.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/cnd_df.R \name{rm_cnd_df} \alias{rm_cnd_df} -\title{Remove the cnd_df class from a data frame} +\title{Remove the \code{cnd_df} class from a data frame} \usage{ rm_cnd_df(dat) } @@ -10,9 +10,9 @@ rm_cnd_df(dat) \item{dat}{A data frame.} } \value{ -The input \code{dat} without the 'cnd_df' class. +The input \code{dat} without the \code{cnd_df} class. } \description{ -This function removes the 'cnd_df' class, along with its attributes, if +This function removes the \code{cnd_df} class, along with its attributes, if applicable. } diff --git a/man/tbl_sum.cnd_df.Rd b/man/tbl_sum.cnd_df.Rd index 5a0f301f..f8a50544 100644 --- a/man/tbl_sum.cnd_df.Rd +++ b/man/tbl_sum.cnd_df.Rd @@ -7,7 +7,7 @@ \method{tbl_sum}{cnd_df}(x, ...) } \arguments{ -\item{x}{A conditioned tibble of class 'cnd_df'.} +\item{x}{A conditioned tibble of class \code{cnd_df}.} \item{...}{Additional arguments passed to the default print method.} } diff --git a/tests/testthat/test-hardcode.R b/tests/testthat/test-hardcode.R new file mode 100644 index 00000000..29af4b32 --- /dev/null +++ b/tests/testthat/test-hardcode.R @@ -0,0 +1,81 @@ +# `aesos`: example raw data set. +aesos <- tibble::tribble( + ~oak_id, ~raw_source, ~patient_number, ~AESO, ~AESOSP, ~AESEV, ~AESER, ~AETERM, + 1L, "RS1", 101L, 0L, "Pain", "Mild", "No", "Headache", + 2L, "RS1", 102L, 0L, NA, "Severe", "Yes", "Dizziness", + 3L, "RS2", 103L, 1L, NA, "Moderate", "No", NA, + 4L, "RS2", 104L, 1L, NA, "Mild", "No", "Eye issues", + 5L, "RS3", 105L, 1L, "Nausea", "Severe", "Yes", "Food Poisoning" +) + +# `oe_inter`: example target data set. +oe_inter <- tibble::tribble( + ~oak_id, ~raw_source, ~patient_number, + 1L, "RS1", 101L, + 3L, "RS2", 103L, + 4L, "RS2", 104L, + 5L, "RS3", 105L, +) + +test_that("hardcode_no_ct works as expected", { + aesos_cnd <- condition_by(aesos, AESO == 1L & !is.na(AESOSP)) + + result <- hardcode_no_ct( + raw_dat = aesos_cnd, + raw_var = "AESO", + tgt_var = "OEORRES", + tgt_val = "Y", + tgt_dat = oe_inter + ) + + expected_result <- tibble::tribble( + ~oak_id, ~raw_source, ~patient_number, ~OEORRES, + # NA because `aesos_cnd` is conditioned to be FALSE on this record. + 1L, "RS1", 101L, NA_character_, + # NA because `aesos_cnd` is conditioned to be FALSE on this record. + 3L, "RS2", 103L, NA_character_, + # NA because `aesos_cnd` is conditioned to be FALSE on this record. + 4L, "RS2", 104L, NA_character_, + # Successful derivation + 5L, "RS3", 105L, "Y" + ) + + expect_equal(result, expected_result) +}) + +test_that("hardcode_ct works as expected", { + aesos_cnd <- condition_by(aesos, AESO == 1L & is.na(AESOSP)) + ct_spec <- tibble::tibble( + codelist_code = "C117743", + term_code = "C178048", + CodedData = "HYPERMIA", + term_value = "HYPERMIA", + collected_value = "IOISYMPO", + term_synonyms = "IOISYMPO" + ) + + result <- + hardcode_ct( + raw_dat = aesos_cnd, + raw_var = "AETERM", + tgt_var = "OETESTCD", + tgt_val = "IOISYMPO", + ct_spec = ct_spec, + ct_clst = "C117743", + tgt_dat = oe_inter + ) + + expected_result <- tibble::tribble( + ~oak_id, ~raw_source, ~patient_number, ~OETESTCD, + # `NA` because `aesos_cnd` is conditioned to be FALSE for this record. + 1L, "RS1", 101L, NA_character_, + # `NA` because AETERM == NA for this record in `aesos_cnd`. + 3L, "RS2", 103L, NA_character_, + # Successful derivation: IOISYMPO -> HYPERMIA. + 4L, "RS2", 104L, "HYPERMIA", + # `NA` because `aesos_cnd` is conditioned to be FALSE for this record. + 5L, "RS3", 105L, NA_character_ + ) + + expect_equal(result, expected_result) +}) From 00e758af9974786b6cd921df54bed004e11583d8 Mon Sep 17 00:00:00 2001 From: Ramiro Magno Date: Wed, 29 May 2024 03:11:48 +0100 Subject: [PATCH 06/23] Extensive support for conditioned tibbles - Joins by raw and target data sets are now aware of conditioned tibbles - Transformation functions, namely `assign_datetime()`, `hardcode*()` and `assign*` are also conditioned-tibble aware - Unit test coverage for most cases indicated at #54 I believe the essential components are here to support the if_then_else algorithm via conditioned tibbles. Now, further testing, assertions and documentation is needed. --- R/assign.R | 34 ++---- R/assign_datetime.R | 34 +++--- R/cnd_df.R | 23 +++- R/hardcode.R | 33 ++---- R/join.R | 39 +++++++ R/sdtm_join.R | 39 +++++++ inst/WORDLIST | 1 + man/condition_by.Rd | 4 +- man/ctl_new_rowid_pillar.cnd_df.Rd | 20 ++++ man/mutate.cnd_df.Rd | 60 +++++++++++ man/sdtm_assign.Rd | 2 +- man/sdtm_hardcode.Rd | 2 +- man/sdtm_join.Rd | 35 ++++++ man/tbl_sum.cnd_df.Rd | 4 +- tests/testthat/test-assign.R | 167 +++++++++++++++++++++++++++++ tests/testthat/test-hardcode.R | 3 + 16 files changed, 420 insertions(+), 80 deletions(-) create mode 100644 R/join.R create mode 100644 R/sdtm_join.R create mode 100644 man/ctl_new_rowid_pillar.cnd_df.Rd create mode 100644 man/mutate.cnd_df.Rd create mode 100644 man/sdtm_join.Rd create mode 100644 tests/testthat/test-assign.R diff --git a/R/assign.R b/R/assign.R index c9c1d831..88dbf8c4 100644 --- a/R/assign.R +++ b/R/assign.R @@ -21,7 +21,7 @@ #' the variables indicated in `id_vars`. This parameter is optional, see #' section Value for how the output changes depending on this argument value. #' @param id_vars Key variables to be used in the join between the raw dataset -#' (`raw_dat`) and the target data set (`raw_dat`). +#' (`raw_dat`) and the target data set (`tgt_dat`). #' #' @returns The returned data set depends on the value of `tgt_dat`: #' - If no target dataset is supplied, meaning that `tgt_dat` defaults to @@ -53,33 +53,19 @@ sdtm_assign <- function(raw_dat, assert_ct_spec(ct_spec, optional = TRUE) assert_ct_clst(ct_spec = ct_spec, ct_clst = ct_clst, optional = TRUE) - # Recode the raw variable following terminology. - tgt_val <- ct_map(raw_dat[[raw_var]], ct_spec = ct_spec, ct_clst = ct_clst) - - # Apply derivation by assigning `raw_var` to `tgt_var`. - # `der_dat`: derived dataset. - der_dat <- + join_dat <- raw_dat |> - dplyr::select(c(id_vars, raw_var)) |> - mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() - dplyr::select(-rlang::sym(raw_var)) + dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |> + sdtm_join(tgt_dat = tgt_dat, id_vars = id_vars) - # If a target dataset is supplied, then join the so far derived dataset with - # the target dataset (`tgt_dat`), otherwise leave it be. - der_dat <- - if (!is.null(tgt_dat)) { - # If variable `tgt_var` exists in `tgt_dat` remove it as we want to - # keep the derived variable in `der_dat`. - tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) + # Recode the raw variable following terminology. + tgt_val <- ct_map(join_dat[[raw_var]], ct_spec = ct_spec, ct_clst = ct_clst) - der_dat |> - dplyr::right_join(y = tgt_dat, by = id_vars) |> - dplyr::relocate(tgt_var, .after = dplyr::last_col()) - } else { - der_dat - } + join_dat |> + mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() + dplyr::select(-dplyr::any_of(setdiff(raw_var, tgt_var))) |> + dplyr::relocate(dplyr::all_of(tgt_var), .after = dplyr::last_col()) - der_dat } #' Derive an SDTM variable diff --git a/R/assign_datetime.R b/R/assign_datetime.R index d8d4ec8b..e6881e8b 100644 --- a/R/assign_datetime.R +++ b/R/assign_datetime.R @@ -170,30 +170,20 @@ assign_datetime <- admiraldev::assert_character_vector(raw_unk) admiraldev::assert_logical_scalar(.warn) - tgt_val <- - create_iso8601(!!!raw_dat[raw_var], - .format = raw_fmt, - .na = raw_unk, - .warn = .warn - ) - - der_dat <- + join_dat <- raw_dat |> dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |> - dplyr::mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() - dplyr::select(-dplyr::any_of(raw_var)) + sdtm_join(tgt_dat = tgt_dat, id_vars = id_vars) - der_dat <- - if (!is.null(tgt_dat)) { - # If variable `tgt_var` exists in `tgt_dat` remove it as we want to - # keep the derived variable in `der_dat`. - tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) - der_dat |> - dplyr::right_join(y = tgt_dat, by = id_vars) |> - dplyr::relocate(tgt_var, .after = dplyr::last_col()) - } else { - der_dat - } + tgt_val <- + create_iso8601(!!!join_dat[raw_var], + .format = raw_fmt, + .na = raw_unk, + .warn = .warn + ) - der_dat + join_dat |> + mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter() + dplyr::select(-dplyr::any_of(setdiff(raw_var, tgt_var))) |> + dplyr::relocate(dplyr::all_of(tgt_var), .after = dplyr::last_col()) } diff --git a/R/cnd_df.R b/R/cnd_df.R index 9ef23a83..54dfc1d0 100644 --- a/R/cnd_df.R +++ b/R/cnd_df.R @@ -122,9 +122,7 @@ rm_cnd_df <- function(dat) { return(dat) } -#' Print -#' -#' Blah +#' Conditioned tibble header print method #' #' @param x A conditioned tibble of class `cnd_df`. #' @param ... Additional arguments passed to the default print method. @@ -143,6 +141,9 @@ lgl_to_chr <- function(x) { ifelse(is.na(x), "-", ifelse(x, "T", "F")) } +#' Conditioned tibble pillar print method +#' +#' @inheritParams pillar::ctl_new_rowid_pillar #' @importFrom pillar ctl_new_rowid_pillar #' @export ctl_new_rowid_pillar.cnd_df <- function(controller, x, width, ...) { @@ -261,7 +262,7 @@ eval_conditions <- function(dat, #' Condition a data set based on specified conditions #' #' This function tags records in a data set, indicating which rows match the -#' specified conditions. +#' specified conditions, resulting in a conditioned data frame. #' #' @param dat A tibble. #' @param ... Conditions to filter the tibble. @@ -272,6 +273,8 @@ eval_conditions <- function(dat, #' expression passed in `...`. A data frame or a list can also be passed that #' will be coerced to an environment internally. #' +#' @returns A conditioned data frame. +#' #' @export condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { @@ -286,6 +289,16 @@ condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { new_cnd_df(dat, cnd = cnd, .warn = FALSE) } +#' Mutate method for conditioned data frames +#' +#' [mutate.cnd_df()] is an S3 method to be dispatched by [mutate][dplyr::mutate] +#' generic on conditioned data frames. This function implements a conditional +#' mutate by only changing rows for which the condition stored in the +#' conditioned data frame is `TRUE`. +#' +#' @param .data A conditioned data frame. +#' +#' @inheritParams dplyr::mutate #' @importFrom dplyr mutate #' @export mutate.cnd_df <- function(.data, @@ -304,5 +317,5 @@ mutate.cnd_df <- function(.data, lst <- purrr::map(derivations, ~ rlang::expr(dplyr::if_else({{cnd}}, !!.x, NA))) lst <- rlang::set_names(lst, derived_vars) - dplyr::mutate(dat, !!!lst) + dplyr::mutate(dat, !!!lst, .by = .by, .keep = .keep, .after = .after) } diff --git a/R/hardcode.R b/R/hardcode.R index ffce1bd7..e893f6b7 100644 --- a/R/hardcode.R +++ b/R/hardcode.R @@ -23,7 +23,7 @@ #' the variables indicated in `id_vars`. This parameter is optional, see #' section Value for how the output changes depending on this argument value. #' @param id_vars Key variables to be used in the join between the raw dataset -#' (`raw_dat`) and the target data set (`raw_dat`). +#' (`raw_dat`) and the target data set (`tgt_dat`). #' #' @returns The returned data set depends on the value of `tgt_dat`: #' - If no target dataset is supplied, meaning that `tgt_dat` defaults to @@ -56,33 +56,18 @@ sdtm_hardcode <- function(raw_dat, assert_ct_spec(ct_spec, optional = TRUE) assert_ct_clst(ct_spec = ct_spec, ct_clst = ct_clst, optional = TRUE) - # Recode the hardcoded value following terminology. - tgt_val <- ct_map(tgt_val, ct_spec = ct_spec, ct_clst = ct_clst) - - # Apply derivation of the hardcoded value. - # `der_dat`: derived dataset. - der_dat <- + join_dat <- raw_dat |> dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |> - mutate("{tgt_var}" := recode(x = !!rlang::sym(raw_var), to = tgt_val)) |> # nolint object_name_linter() - dplyr::select(-dplyr::any_of(raw_var)) + sdtm_join(tgt_dat = tgt_dat, id_vars = id_vars) - # If a target dataset is supplied, then join the so far derived dataset with - # the target dataset (`tgt_dat`), otherwise leave it be. - der_dat <- - if (!is.null(tgt_dat)) { - # If variable `tgt_var` exists in `tgt_dat` remove it as we want to - # keep the derived variable in `der_dat`. - tgt_dat <- dplyr::select(tgt_dat, -dplyr::any_of(tgt_var)) - - der_dat |> - dplyr::right_join(y = tgt_dat, by = id_vars) |> - dplyr::relocate(tgt_var, .after = dplyr::last_col()) - } else { - der_dat - } + # Recode the hardcoded value following terminology. + tgt_val <- ct_map(tgt_val, ct_spec = ct_spec, ct_clst = ct_clst) - der_dat + join_dat |> + mutate("{tgt_var}" := recode(x = !!rlang::sym(raw_var), to = tgt_val)) |> # nolint object_name_linter() + dplyr::select(-dplyr::any_of(setdiff(raw_var, tgt_var))) |> + dplyr::relocate(dplyr::all_of(tgt_var), .after = dplyr::last_col()) } #' Derive an SDTM variable with a hardcoded value diff --git a/R/join.R b/R/join.R new file mode 100644 index 00000000..1e0e64b9 --- /dev/null +++ b/R/join.R @@ -0,0 +1,39 @@ +#' SDTM join +#' +#' [sdtm_join()] is a special join between a raw data set and a target data +#' set. This function supports conditioned data frames. +#' +#' @param raw_dat The raw dataset: a dataframe or a conditioned data frame. Must +#' include the variables passed in `id_vars`. +#' @param tgt_dat Target dataset: a data frame or a conditioned data frame to be +#' merged against `raw_dat` by the variables indicated in `id_vars`. +#' @param id_vars Key variables to be used in the join between the raw dataset +#' (`raw_dat`) and the target data set (`raw_dat`). +#' +#' @returns A data frame, or a conditioned data frame if at least one of the +#' input data sets is a conditioned data frame. +#' +#' @keywords internal +#' @importFrom rlang %||% +sdtm_join <- function(raw_dat, + tgt_dat = NULL, + id_vars = oak_id_vars()) { + raw_dat_cnd <- get_cnd_df_cnd(raw_dat) %||% rep(TRUE, nrow(raw_dat)) + tgt_dat <- tgt_dat %||% raw_dat[id_vars] + tgt_dat_cnd <- get_cnd_df_cnd(tgt_dat) %||% rep(TRUE, nrow(tgt_dat)) + + # `rm_cnd_df()` prevents `mutate` from dispatching. + raw_dat <- dplyr::mutate(rm_cnd_df(raw_dat), `__raw_dat_cond__` = raw_dat_cnd) + tgt_dat <- dplyr::mutate(rm_cnd_df(tgt_dat), `__tgt_dat_cond__` = tgt_dat_cnd) + + res <- dplyr::right_join(raw_dat, y = tgt_dat, by = id_vars) + + cnd <- res$`__raw_dat_cond__` & res$`__tgt_dat_cond__` + res |> + dplyr::select(-dplyr::all_of(c( + "__raw_dat_cond__", "__tgt_dat_cond__" + ))) |> + new_cnd_df(cnd = cnd, .warn = FALSE) + +} + diff --git a/R/sdtm_join.R b/R/sdtm_join.R new file mode 100644 index 00000000..fc973ead --- /dev/null +++ b/R/sdtm_join.R @@ -0,0 +1,39 @@ +#' SDTM join +#' +#' [sdtm_join()] is a special join between a raw data set and a target data +#' set. This function supports conditioned data frames. +#' +#' @param raw_dat The raw dataset: a dataframe or a conditioned data frame. Must +#' include the variables passed in `id_vars`. +#' @param tgt_dat Target dataset: a data frame or a conditioned data frame to be +#' merged against `raw_dat` by the variables indicated in `id_vars`. +#' @param id_vars Key variables to be used in the join between the raw dataset +#' (`raw_dat`) and the target data set (`tgt_dat`). +#' +#' @returns A data frame, or a conditioned data frame if, at least, one of the +#' input data sets is a conditioned data frame. +#' +#' @keywords internal +#' @importFrom rlang %||% +sdtm_join <- function(raw_dat, + tgt_dat = NULL, + id_vars = oak_id_vars()) { + raw_dat_cnd <- get_cnd_df_cnd(raw_dat) %||% rep(TRUE, nrow(raw_dat)) + tgt_dat <- tgt_dat %||% raw_dat[id_vars] + tgt_dat_cnd <- get_cnd_df_cnd(tgt_dat) %||% rep(TRUE, nrow(tgt_dat)) + + # `rm_cnd_df()` prevents `mutate` from dispatching. + raw_dat <- dplyr::mutate(rm_cnd_df(raw_dat), `__raw_dat_cond__` = raw_dat_cnd) + tgt_dat <- dplyr::mutate(rm_cnd_df(tgt_dat), `__tgt_dat_cond__` = tgt_dat_cnd) + + res <- dplyr::right_join(raw_dat, y = tgt_dat, by = id_vars) + + cnd <- res$`__raw_dat_cond__` & res$`__tgt_dat_cond__` + res |> + dplyr::select(-dplyr::all_of(c( + "__raw_dat_cond__", "__tgt_dat_cond__" + ))) |> + new_cnd_df(cnd = cnd, .warn = FALSE) + +} + diff --git a/inst/WORDLIST b/inst/WORDLIST index 538f7a2e..78f8f566 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -25,3 +25,4 @@ AE AESTDY CMSTDY DM +ungrouped diff --git a/man/condition_by.Rd b/man/condition_by.Rd index e1b7cb2a..7a5ff82c 100644 --- a/man/condition_by.Rd +++ b/man/condition_by.Rd @@ -20,8 +20,10 @@ will be coerced to an environment internally.} \value{ A tibble with an additional class \code{cnd_df} and a logical vector attribute indicating matching rows. + +A conditioned data frame. } \description{ This function tags records in a data set, indicating which rows match the -specified conditions. +specified conditions, resulting in a conditioned data frame. } diff --git a/man/ctl_new_rowid_pillar.cnd_df.Rd b/man/ctl_new_rowid_pillar.cnd_df.Rd new file mode 100644 index 00000000..dc70aa27 --- /dev/null +++ b/man/ctl_new_rowid_pillar.cnd_df.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{ctl_new_rowid_pillar.cnd_df} +\alias{ctl_new_rowid_pillar.cnd_df} +\title{Conditioned tibble pillar print method} +\usage{ +\method{ctl_new_rowid_pillar}{cnd_df}(controller, x, width, ...) +} +\arguments{ +\item{controller}{The object of class \code{"tbl"} currently printed.} + +\item{x}{A simple (one-dimensional) vector.} + +\item{width}{The available width, can be a vector for multiple tiers.} + +\item{...}{These dots are for future extensions and must be empty.} +} +\description{ +Conditioned tibble pillar print method +} diff --git a/man/mutate.cnd_df.Rd b/man/mutate.cnd_df.Rd new file mode 100644 index 00000000..d55b2134 --- /dev/null +++ b/man/mutate.cnd_df.Rd @@ -0,0 +1,60 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnd_df.R +\name{mutate.cnd_df} +\alias{mutate.cnd_df} +\title{Mutate method for conditioned data frames} +\usage{ +\method{mutate}{cnd_df}( + .data, + ..., + .by = NULL, + .keep = c("all", "used", "unused", "none"), + .before = NULL, + .after = NULL +) +} +\arguments{ +\item{.data}{A conditioned data frame.} + +\item{...}{<\code{\link[rlang:args_data_masking]{data-masking}}> Name-value pairs. +The name gives the name of the column in the output. + +The value can be: +\itemize{ +\item A vector of length 1, which will be recycled to the correct length. +\item A vector the same length as the current group (or the whole data frame +if ungrouped). +\item \code{NULL}, to remove the column. +\item A data frame or tibble, to create multiple columns in the output. +}} + +\item{.by}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> Optionally, a selection of columns to +group by for just this operation, functioning as an alternative to \code{\link[dplyr:group_by]{group_by()}}. For +details and examples, see \link[dplyr:dplyr_by]{?dplyr_by}.} + +\item{.keep}{Control which columns from \code{.data} are retained in the output. Grouping +columns and columns created by \code{...} are always kept. +\itemize{ +\item \code{"all"} retains all columns from \code{.data}. This is the default. +\item \code{"used"} retains only the columns used in \code{...} to create new +columns. This is useful for checking your work, as it displays inputs +and outputs side-by-side. +\item \code{"unused"} retains only the columns \emph{not} used in \code{...} to create new +columns. This is useful if you generate new columns, but no longer need +the columns used to generate them. +\item \code{"none"} doesn't retain any extra columns from \code{.data}. Only the grouping +variables and columns created by \code{...} are kept. +}} + +\item{.before, .after}{<\code{\link[dplyr:dplyr_tidy_select]{tidy-select}}> Optionally, control where new columns +should appear (the default is to add to the right hand side). See +\code{\link[dplyr:relocate]{relocate()}} for more details.} +} +\description{ +\code{\link[=mutate.cnd_df]{mutate.cnd_df()}} is an S3 method to be dispatched by \link[dplyr:mutate]{mutate} +generic on conditioned data frames. This function implements a conditional +mutate by only changing rows for which the condition stored in the +conditioned data frame is \code{TRUE}. +} diff --git a/man/sdtm_assign.Rd b/man/sdtm_assign.Rd index 676979dc..85601e3c 100644 --- a/man/sdtm_assign.Rd +++ b/man/sdtm_assign.Rd @@ -37,7 +37,7 @@ the variables indicated in \code{id_vars}. This parameter is optional, see section Value for how the output changes depending on this argument value.} \item{id_vars}{Key variables to be used in the join between the raw dataset -(\code{raw_dat}) and the target data set (\code{raw_dat}).} +(\code{raw_dat}) and the target data set (\code{tgt_dat}).} } \value{ The returned data set depends on the value of \code{tgt_dat}: diff --git a/man/sdtm_hardcode.Rd b/man/sdtm_hardcode.Rd index 5c3435b5..d8cb59a6 100644 --- a/man/sdtm_hardcode.Rd +++ b/man/sdtm_hardcode.Rd @@ -41,7 +41,7 @@ the variables indicated in \code{id_vars}. This parameter is optional, see section Value for how the output changes depending on this argument value.} \item{id_vars}{Key variables to be used in the join between the raw dataset -(\code{raw_dat}) and the target data set (\code{raw_dat}).} +(\code{raw_dat}) and the target data set (\code{tgt_dat}).} } \value{ The returned data set depends on the value of \code{tgt_dat}: diff --git a/man/sdtm_join.Rd b/man/sdtm_join.Rd new file mode 100644 index 00000000..1c7c02e7 --- /dev/null +++ b/man/sdtm_join.Rd @@ -0,0 +1,35 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/join.R, R/sdtm_join.R +\name{sdtm_join} +\alias{sdtm_join} +\title{SDTM join} +\usage{ +sdtm_join(raw_dat, tgt_dat = NULL, id_vars = oak_id_vars()) + +sdtm_join(raw_dat, tgt_dat = NULL, id_vars = oak_id_vars()) +} +\arguments{ +\item{raw_dat}{The raw dataset: a dataframe or a conditioned data frame. Must +include the variables passed in \code{id_vars}.} + +\item{tgt_dat}{Target dataset: a data frame or a conditioned data frame to be +merged against \code{raw_dat} by the variables indicated in \code{id_vars}.} + +\item{id_vars}{Key variables to be used in the join between the raw dataset +(\code{raw_dat}) and the target data set (\code{tgt_dat}).} +} +\value{ +A data frame, or a conditioned data frame if at least one of the +input data sets is a conditioned data frame. + +A data frame, or a conditioned data frame if, at least, one of the +input data sets is a conditioned data frame. +} +\description{ +\code{\link[=sdtm_join]{sdtm_join()}} is a special join between a raw data set and a target data +set. This function supports conditioned data frames. + +\code{\link[=sdtm_join]{sdtm_join()}} is a special join between a raw data set and a target data +set. This function supports conditioned data frames. +} +\keyword{internal} diff --git a/man/tbl_sum.cnd_df.Rd b/man/tbl_sum.cnd_df.Rd index f8a50544..760e5507 100644 --- a/man/tbl_sum.cnd_df.Rd +++ b/man/tbl_sum.cnd_df.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/cnd_df.R \name{tbl_sum.cnd_df} \alias{tbl_sum.cnd_df} -\title{Print} +\title{Conditioned tibble header print method} \usage{ \method{tbl_sum}{cnd_df}(x, ...) } @@ -12,5 +12,5 @@ \item{...}{Additional arguments passed to the default print method.} } \description{ -Blah +Conditioned tibble header print method } diff --git a/tests/testthat/test-assign.R b/tests/testthat/test-assign.R new file mode 100644 index 00000000..46d86a87 --- /dev/null +++ b/tests/testthat/test-assign.R @@ -0,0 +1,167 @@ +test_that("assign_ct works as expected with a conditioned `tgt_dat`", { + + vs_raw_dat <- tibble::tibble( + oak_id = 1:5, + raw_source = c("VS1", "VS2", "VS3", "VS4", "VS5"), + patient_number = c(101L, 102L, 103L, 104L, 105L), + TEMPLOC = c("Oral", "Axillary", "Rectal", "Tympanic", "Temporal") + ) + + vs_tgt_dat <- tibble::tibble( + oak_id = as.integer(rep(1:5, each = 4)), + raw_source = rep(c("VS1", "VS2", "VS3", "VS4", "VS5"), each = 4), + patient_number = as.integer(rep(c(101L, 102L, 103L, 104L, 105L), each = 4)), + VSTESTCD = c("TEMP", "BPSYS", "BPDIAS", "HR", + "TEMP", "BPSYS", "BPDIAS", "HR", + "TEMP", "BPSYS", "BPDIAS", "HR", + "TEMP", "BPSYS", "BPDIAS", "HR", + "TEMP", "BPSYS", "BPDIAS", "HR") + ) + + # vital signs' locations + vs_loc_raw <- c("Mouth", "Arm", "Arm", "Arm", "Armpit", "Arm", "Arm", "Arm", + "Rectum", "Arm", "Arm", "Arm", "auris", "Arm", "Arm", "Arm", "brow", "Arm", + "Arm", "Arm") + + vs_loc_tgt <- c( + "ORAL", + rep(NA, 3L), + "AXILLA", + rep(NA, 3L), + "ANUS", + rep(NA, 3L), + "EAR", + rep(NA, 3L), + "FOREHEAD", + rep(NA, 3L) + ) + + ct_spec <- tibble::tibble( + codelist_code = "C74456", + term_code = c("C32141", "C12674", "C12394", "C89803", "C43362"), + CodedData = c("ARM", "AXILLA", "EAR", "FOREHEAD", "ANUS"), + term_value = c("ARM", "AXILLA", "EAR", "FOREHEAD", "ANUS"), + collected_value = c("Arm", "Armpit", "auris", "brow", "anus"), + term_synonyms = c("Arm", "Axillary", "Tympanic", "Temporal", "Rectal") + ) + + result <- + assign_ct( + raw_dat = vs_raw_dat, + raw_var = "TEMPLOC", + tgt_var = "VSLOC", + ct_spec = ct_spec, + ct_clst = "C74456", + tgt_dat = condition_by(vs_tgt_dat, VSTESTCD == "TEMP") + ) + + expected_result <- + tibble::add_column( + vs_tgt_dat, + VSLOC = vs_loc_tgt + ) + + expect_equal(result, expected_result) +}) + + +test_that("assign_ct works as expected with both `raw_dat` and `tgt_dat` as conditioned data frames", { + + ct_spec <- tibble::tibble( + codelist_code = "C78734", + term_code = c("C150895", "C12434", "C13275", "C89803", "C12801"), + CodedData = c("SWABBED MATERIAL", "BLOOD", "SALIVA", "URINE", "TISSUE"), + term_value = c("SWABBED MATERIAL", "BLOOD", "SALIVA", "URINE", "TISSUE"), + collected_value = c("Nasopharyngeal Swab", "blood", "drool", "urine sample", "tissue"), + term_synonyms = c("Swab", "Blood", "Spit", "urinary excretion", "tissue sample") + ) + + fa_raw_dat <- tibble::tibble( + oak_id = as.integer(1:5), + raw_source = c("FA1", "FA2", "FA3", "FA4", "FA5"), + patient_number = 101:105, + SPCNM = c("Nasopharyngeal Swab", "Blood", "Saliva", "Urine", "Tissue"), + SPECTYP = c(NA, NA, "Swab", NA, NA) + ) + + fa_tgt_dat <- tibble::tibble( + oak_id = 1:5, + raw_source = c("FA1", "FA2", "FA3", "FA4", "FA5"), + patient_number = 101:105, + FATESTCD = c("STATUS", "OTHER", "STATUS", "STATUS", "OTHER"), + FAOBJ = c( + "Severe Acute Resp Syndrome Coronavirus 2", + "Other Condition", + "Severe Acute Resp Syndrome Coronavirus 2", + "Severe Acute Resp Syndrome Coronavirus 2", + "Other Condition" + ) + ) + + result <- + assign_ct( + raw_dat = condition_by(fa_raw_dat, is.na(SPECTYP)), + raw_var = "SPCNM", + tgt_var = "FASPEC", + ct_spec = ct_spec, + ct_clst = "C78734", + tgt_dat = condition_by( + fa_tgt_dat, + FATESTCD == "STATUS" & + FAOBJ == "Severe Acute Resp Syndrome Coronavirus 2" + ) + ) + + expected_result <- + fa_tgt_dat |> + tibble::add_column(FASPEC = c("SWABBED MATERIAL", NA, NA, "URINE", NA)) + + expect_equal(result, expected_result) +}) + +test_that("assign_ct works as expected with conditions across both data sets", { + + cm_raw_dat <- tibble::tibble( + oak_id = 1:5, + raw_source = paste0("MD", 1:5), + patient_number = 101:105, + CMMODIFY = c("ASPIRIN EC", "IBUPROFEN LYSINE" , "PARACETAMOL", "DICLOFENAC", "NAPROXEN") + ) + + cm_tgt_dat <- tibble::tibble( + oak_id = 1:5, + raw_source = paste0("MD", 1:5), + patient_number = 101:105, + CMTRT = c("ASPIRIN", "IBUPROFEN", "PARACETAMOL", "DICLOFENAC", "NAPROXEN") + ) + + # This only works if the raw data set and the target data set have the same + # number of records, otherwise the comparison CMMODIFY != CMTRT is not + # meaningful. + result1 <- + assign_no_ct( + raw_dat = cm_raw_dat, + raw_var = "CMMODIFY", + tgt_var = "CMMODIFY", + tgt_dat = condition_by(cm_tgt_dat, CMMODIFY != CMTRT, .env = cm_raw_dat) + ) + + # Because both data sets have to have the same number of records for the + # comparison to be meaningful, then we can just as well condition the + # raw data set itself. + result2 <- + assign_no_ct( + raw_dat = condition_by(cm_raw_dat, CMMODIFY != CMTRT, .env = cm_tgt_dat), + raw_var = "CMMODIFY", + tgt_var = "CMMODIFY", + tgt_dat = cm_tgt_dat + ) + + expected_result <- + cm_tgt_dat |> + tibble::add_column(CMMODIFY = c("ASPIRIN EC", "IBUPROFEN LYSINE", NA, NA, NA)) + + expect_equal(result1, expected_result) + expect_equal(result2, expected_result) + +}) diff --git a/tests/testthat/test-hardcode.R b/tests/testthat/test-hardcode.R index 29af4b32..9f7ec73e 100644 --- a/tests/testthat/test-hardcode.R +++ b/tests/testthat/test-hardcode.R @@ -79,3 +79,6 @@ test_that("hardcode_ct works as expected", { expect_equal(result, expected_result) }) + + + From 0d7861ab54aae4d0825a29c47a9a7a035aac6ba7 Mon Sep 17 00:00:00 2001 From: Ramiro Magno Date: Wed, 12 Jun 2024 16:19:29 +0100 Subject: [PATCH 07/23] Ramm's feedback integration - Move `tgt_dat` to the first position in the argument list for cleaner command pipes. - Rename `condition_by()` to `condition_add()`. - Export `oak_id_vars()` for direct user access. - Update tidyselections to align with the latest practices. --- NAMESPACE | 3 +- R/assign.R | 39 +++++++++++--------- R/assign_datetime.R | 21 ++++++----- R/cnd_df.R | 7 ++-- R/ct.R | 4 +- R/hardcode.R | 45 ++++++++++++----------- R/oak_id_vars.R | 8 ++-- man/assign.Rd | 32 ++++++++-------- man/assign_datetime.Rd | 32 ++++++++-------- man/{condition_by.Rd => condition_add.Rd} | 8 ++-- man/contains_oak_id_vars.Rd | 2 +- man/harcode.Rd | 38 +++++++++---------- man/oak_id_vars.Rd | 5 +-- man/sdtm_assign.Rd | 18 ++++----- man/sdtm_hardcode.Rd | 18 ++++----- tests/testthat/test-assign.R | 33 +++++++++-------- tests/testthat/test-assign_datetime.R | 10 ++--- tests/testthat/test-hardcode.R | 4 +- 18 files changed, 168 insertions(+), 159 deletions(-) rename man/{condition_by.Rd => condition_add.Rd} (80%) diff --git a/NAMESPACE b/NAMESPACE index 5ec1b0bd..c8dd2b14 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,7 +8,7 @@ export(assign_ct) export(assign_datetime) export(assign_no_ct) export(clear_cache) -export(condition_by) +export(condition_add) export(create_iso8601) export(ct_map) export(ct_spec_example) @@ -17,6 +17,7 @@ export(derive_study_day) export(fmt_cmp) export(hardcode_ct) export(hardcode_no_ct) +export(oak_id_vars) export(problems) export(read_ct_spec) export(read_ct_spec_example) diff --git a/R/assign.R b/R/assign.R index 88dbf8c4..d381f79b 100644 --- a/R/assign.R +++ b/R/assign.R @@ -35,13 +35,14 @@ #' #' @importFrom rlang := #' @keywords internal -sdtm_assign <- function(raw_dat, - raw_var, +sdtm_assign <- function(tgt_dat = NULL, tgt_var, + raw_dat, + raw_var, ct_spec = NULL, ct_clst = NULL, - tgt_dat = NULL, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) admiraldev::assert_character_vector(id_vars) @@ -117,9 +118,9 @@ sdtm_assign <- function(raw_dat, #' ) #' #' assign_no_ct( -#' raw_dat = md1, -#' raw_var = "MDIND", #' tgt_var = "CMINDC", +#' raw_dat = md1, +#' raw_var = "MDIND" #' ) #' #' cm_inter <- @@ -165,12 +166,12 @@ sdtm_assign <- function(raw_dat, #' (ct_spec <- read_ct_spec_example("ct-01-cm")) #' #' assign_ct( +#' tgt_dat = cm_inter, +#' tgt_var = "CMINDC", #' raw_dat = md1, #' raw_var = "MDIND", -#' tgt_var = "CMINDC", #' ct_spec = ct_spec, -#' ct_clst = "C66729", -#' tgt_dat = cm_inter +#' ct_clst = "C66729" #' ) #' #' @name assign @@ -179,11 +180,12 @@ NULL #' @order 1 #' @export #' @rdname assign -assign_no_ct <- function(raw_dat, - raw_var, +assign_no_ct <- function(tgt_dat = NULL, tgt_var, - tgt_dat = NULL, + raw_dat, + raw_var, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) admiraldev::assert_character_vector(id_vars) @@ -194,10 +196,10 @@ assign_no_ct <- function(raw_dat, admiraldev::assert_data_frame(tgt_dat, required_vars = rlang::syms(id_vars), optional = TRUE) sdtm_assign( + tgt_dat = tgt_dat, + tgt_var = tgt_var, raw_dat = raw_dat, raw_var = raw_var, - tgt_var = tgt_var, - tgt_dat = tgt_dat, id_vars = id_vars ) } @@ -205,13 +207,14 @@ assign_no_ct <- function(raw_dat, #' @order 2 #' @export #' @rdname assign -assign_ct <- function(raw_dat, - raw_var, +assign_ct <- function(tgt_dat = NULL, tgt_var, + raw_dat, + raw_var, ct_spec, ct_clst, - tgt_dat = NULL, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) admiraldev::assert_character_vector(id_vars) @@ -222,10 +225,10 @@ assign_ct <- function(raw_dat, admiraldev::assert_data_frame(tgt_dat, required_vars = rlang::syms(id_vars), optional = TRUE) sdtm_assign( + tgt_dat = tgt_dat, + tgt_var = tgt_var, raw_dat = raw_dat, raw_var = raw_var, - tgt_var = tgt_var, - tgt_dat = tgt_dat, id_vars = id_vars, ct_spec = ct_spec, ct_clst = ct_clst diff --git a/R/assign_datetime.R b/R/assign_datetime.R index e6881e8b..5af4f9e2 100644 --- a/R/assign_datetime.R +++ b/R/assign_datetime.R @@ -61,11 +61,11 @@ #' # indicating that these values are missing/unknown (unk). #' cm1 <- #' assign_datetime( +#' tgt_var = "CMSTDTC", #' raw_dat = md1, #' raw_var = "MDBDR", #' raw_fmt = "d-m-y", -#' raw_unk = c("UN", "UNK"), -#' tgt_var = "CMSTDTC" +#' raw_unk = c("UN", "UNK") #' ) #' #' cm1 @@ -120,11 +120,11 @@ #' # data set `cm_inter`. #' cm2 <- #' assign_datetime( +#' tgt_dat = cm_inter, +#' tgt_var = "CMSTDTC", #' raw_dat = md1, #' raw_var = "MDBDR", -#' raw_fmt = "d-m-y", -#' tgt_var = "CMSTDTC", -#' tgt_dat = cm_inter +#' raw_fmt = "d-m-y" #' ) #' #' cm2 @@ -137,11 +137,11 @@ #' # MDETM (correspondence is by positional matching). #' cm3 <- #' assign_datetime( +#' tgt_var = "CMSTDTC", #' raw_dat = md1, #' raw_var = c("MDEDR", "MDETM"), #' raw_fmt = c("d-m-y", "H:M:S"), -#' raw_unk = c("UN", "UNK"), -#' tgt_var = "CMSTDTC" +#' raw_unk = c("UN", "UNK") #' ) #' #' cm3 @@ -151,14 +151,15 @@ #' #' @export assign_datetime <- - function(raw_dat, + function(tgt_dat = NULL, + tgt_var, + raw_dat, raw_var, raw_fmt, - tgt_var, raw_unk = c("UN", "UNK"), - tgt_dat = NULL, id_vars = oak_id_vars(), .warn = TRUE) { + admiraldev::assert_character_vector(raw_var) admiraldev::assert_character_scalar(tgt_var) admiraldev::assert_character_vector(id_vars) diff --git a/R/cnd_df.R b/R/cnd_df.R index 54dfc1d0..2f8e87dd 100644 --- a/R/cnd_df.R +++ b/R/cnd_df.R @@ -20,7 +20,7 @@ # - `tbl_sum.cnd_df()`: Provide a tibble header print method for `cnd_df` tibbles. # - `ctl_new_rowid_pillar.cnd_df()`: A print method for the row ids cnd_df` tibbles. # - `eval_conditions()`: Find which rows match a set of conditions. -# - `condition_by()`: Create a conditioned data frame (user facing). +# - `condition_add()`: Create a conditioned data frame (user facing). # - `derive_by_condition()`: Perform a derivation on a conditioned data frame. #' Create a data frame with filtering tags @@ -269,14 +269,14 @@ eval_conditions <- function(dat, #' @return A tibble with an additional class `cnd_df` and a logical vector #' attribute indicating matching rows. #' @param .na Return value to be used when the conditions evaluate to `NA`. -#' @param .env An optional environment to look for variables involved in logical +#' @param .dat2 An optional environment to look for variables involved in logical #' expression passed in `...`. A data frame or a list can also be passed that #' will be coerced to an environment internally. #' #' @returns A conditioned data frame. #' #' @export -condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { +condition_add <- function(dat, ..., .na = NA, .dat2 = rlang::env()) { if (is_cnd_df(dat)) { rlang::warn( @@ -284,6 +284,7 @@ condition_by <- function(dat, ..., .na = NA, .env = rlang::env()) { "The previous condition will be replaced by the new one.") ) } + .env <- .dat2 cnd <- eval_conditions(dat = dat, ..., .na = .na, .env = .env) new_cnd_df(dat, cnd = cnd, .warn = FALSE) diff --git a/R/ct.R b/R/ct.R index e66c2d6d..ab5efb00 100644 --- a/R/ct.R +++ b/R/ct.R @@ -232,10 +232,10 @@ ct_mappings <- function(ct_spec, from = ct_spec_vars("from"), to = ct_spec_vars( values_to = "from", names_to = "type" ) |> - dplyr::select(c("type", "from", "to")) |> + dplyr::select(dplyr::all_of(c("type", "from", "to"))) |> dplyr::mutate(type = factor(.data$type, levels = cols)) |> dplyr::arrange(.data$type) |> - dplyr::select(-"type") |> + dplyr::select(-dplyr::all_of("type")) |> tidyr::drop_na("from") |> dplyr::mutate(from = str_split(.data$from)) |> tidyr::unnest(from) |> diff --git a/R/hardcode.R b/R/hardcode.R index e893f6b7..3562192f 100644 --- a/R/hardcode.R +++ b/R/hardcode.R @@ -36,14 +36,15 @@ #' #' @importFrom rlang := #' @keywords internal -sdtm_hardcode <- function(raw_dat, - raw_var, +sdtm_hardcode <- function(tgt_dat = NULL, tgt_var, + raw_dat, + raw_var, tgt_val, ct_spec = NULL, ct_clst = NULL, - tgt_dat = NULL, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) admiraldev::assert_character_scalar(tgt_val) @@ -122,10 +123,10 @@ sdtm_hardcode <- function(raw_dat, #' # Derive a new variable `CMCAT` by overwriting `MDRAW` with the #' # hardcoded value "GENERAL CONCOMITANT MEDICATIONS". #' hardcode_no_ct( +#' tgt_val = "GENERAL CONCOMITANT MEDICATIONS", #' raw_dat = md1, #' raw_var = "MDRAW", -#' tgt_var = "CMCAT", -#' tgt_val = "GENERAL CONCOMITANT MEDICATIONS" +#' tgt_var = "CMCAT" #' ) #' #' cm_inter <- @@ -142,11 +143,11 @@ sdtm_hardcode <- function(raw_dat, #' # hardcoded value "GENERAL CONCOMITANT MEDICATIONS" with a prior join to #' # `target_dataset`. #' hardcode_no_ct( +#' tgt_dat = cm_inter, +#' tgt_val = "GENERAL CONCOMITANT MEDICATIONS", #' raw_dat = md1, #' raw_var = "MDRAW", -#' tgt_var = "CMCAT", -#' tgt_val = "GENERAL CONCOMITANT MEDICATIONS", -#' tgt_dat = cm_inter +#' tgt_var = "CMCAT" #' ) #' #' # Controlled terminology specification @@ -156,13 +157,13 @@ sdtm_hardcode <- function(raw_dat, #' # involving terminology recoding. `NA` values in `MDRAW` are preserved in #' # `CMCAT`. #' hardcode_ct( +#' tgt_dat = cm_inter, +#' tgt_var = "CMCAT", #' raw_dat = md1, #' raw_var = "MDRAW", -#' tgt_var = "CMCAT", #' tgt_val = "GENERAL CONCOMITANT MEDICATIONS", #' ct_spec = ct_spec, -#' ct_clst = "C66729", -#' tgt_dat = cm_inter +#' ct_clst = "C66729" #' ) #' #' @name harcode @@ -170,12 +171,13 @@ NULL #' @export #' @rdname harcode -hardcode_no_ct <- function(raw_dat, +hardcode_no_ct <- function(tgt_dat = NULL, + tgt_val, + raw_dat, raw_var, tgt_var, - tgt_val, - tgt_dat = NULL, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) assertthat::assert_that(assertthat::is.scalar(tgt_val), @@ -189,11 +191,11 @@ hardcode_no_ct <- function(raw_dat, admiraldev::assert_data_frame(tgt_dat, required_vars = rlang::syms(id_vars), optional = TRUE) sdtm_hardcode( + tgt_dat = tgt_dat, + tgt_val = tgt_val, raw_dat = raw_dat, raw_var = raw_var, tgt_var = tgt_var, - tgt_val = tgt_val, - tgt_dat = tgt_dat, id_vars = id_vars ) } @@ -201,14 +203,15 @@ hardcode_no_ct <- function(raw_dat, #' @export #' @rdname harcode hardcode_ct <- - function(raw_dat, + function(tgt_dat = NULL, + tgt_val, + raw_dat, raw_var, tgt_var, - tgt_val, ct_spec, ct_clst, - tgt_dat = NULL, id_vars = oak_id_vars()) { + admiraldev::assert_character_scalar(raw_var) admiraldev::assert_character_scalar(tgt_var) assertthat::assert_that(assertthat::is.scalar(tgt_val), @@ -228,13 +231,13 @@ hardcode_ct <- assert_ct_clst(ct_spec = ct_spec, ct_clst = ct_clst, optional = FALSE) sdtm_hardcode( + tgt_dat = tgt_dat, + tgt_val = tgt_val, raw_dat = raw_dat, raw_var = raw_var, tgt_var = tgt_var, - tgt_val = tgt_val, ct_spec = ct_spec, ct_clst = ct_clst, - tgt_dat = tgt_dat, id_vars = id_vars ) } diff --git a/R/oak_id_vars.R b/R/oak_id_vars.R index 718d11da..c88007f8 100644 --- a/R/oak_id_vars.R +++ b/R/oak_id_vars.R @@ -13,11 +13,11 @@ #' as keys in raw datasets. #' #' @examples -#' sdtm.oak:::oak_id_vars() +#' oak_id_vars() #' -#' sdtm.oak:::oak_id_vars(extra_vars = "sample_id") +#' oak_id_vars(extra_vars = "sample_id") #' -#' @keywords internal +#' @export oak_id_vars <- function(extra_vars = NULL) { admiraldev::assert_character_vector(extra_vars, optional = TRUE) unique(c("oak_id", "raw_source", "patient_number", extra_vars)) @@ -37,7 +37,7 @@ oak_id_vars <- function(extra_vars = NULL) { #' # `oak_id_vars()` is the function that defines what are the minimal set of #' # oak keys. Hence, by definition, the following code should always return #' # `TRUE`. -#' sdtm.oak:::contains_oak_id_vars(sdtm.oak:::oak_id_vars()) +#' sdtm.oak:::contains_oak_id_vars(oak_id_vars()) #' #' # Returns `FALSE`. #' sdtm.oak:::contains_oak_id_vars(character()) diff --git a/man/assign.Rd b/man/assign.Rd index ff7df056..2f53ff73 100644 --- a/man/assign.Rd +++ b/man/assign.Rd @@ -7,37 +7,37 @@ \title{Derive an SDTM variable} \usage{ assign_no_ct( + tgt_dat = NULL, + tgt_var, raw_dat, raw_var, - tgt_var, - tgt_dat = NULL, id_vars = oak_id_vars() ) assign_ct( + tgt_dat = NULL, + tgt_var, raw_dat, raw_var, - tgt_var, ct_spec, ct_clst, - tgt_dat = NULL, id_vars = oak_id_vars() ) } \arguments{ +\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by +the variables indicated in \code{id_vars}. This parameter is optional, see +section Value for how the output changes depending on this argument value.} + +\item{tgt_var}{The target SDTM variable: a single string indicating the name +of variable to be derived.} + \item{raw_dat}{The raw dataset (dataframe); must include the variables passed in \code{id_vars} and \code{raw_var}.} \item{raw_var}{The raw variable: a single string indicating the name of the raw variable in \code{raw_dat}.} -\item{tgt_var}{The target SDTM variable: a single string indicating the name -of variable to be derived.} - -\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by -the variables indicated in \code{id_vars}. This parameter is optional, see -section Value for how the output changes depending on this argument value.} - \item{id_vars}{Key variables to be used in the join between the raw dataset (\code{raw_dat}) and the target data set (\code{raw_dat}).} @@ -82,9 +82,9 @@ md1 <- ) assign_no_ct( - raw_dat = md1, - raw_var = "MDIND", tgt_var = "CMINDC", + raw_dat = md1, + raw_var = "MDIND" ) cm_inter <- @@ -130,12 +130,12 @@ cm_inter <- (ct_spec <- read_ct_spec_example("ct-01-cm")) assign_ct( + tgt_dat = cm_inter, + tgt_var = "CMINDC", raw_dat = md1, raw_var = "MDIND", - tgt_var = "CMINDC", ct_spec = ct_spec, - ct_clst = "C66729", - tgt_dat = cm_inter + ct_clst = "C66729" ) } diff --git a/man/assign_datetime.Rd b/man/assign_datetime.Rd index 9130e775..b3564ddf 100644 --- a/man/assign_datetime.Rd +++ b/man/assign_datetime.Rd @@ -5,17 +5,24 @@ \title{Derive an ISO8601 date-time variable} \usage{ assign_datetime( + tgt_dat = NULL, + tgt_var, raw_dat, raw_var, raw_fmt, - tgt_var, raw_unk = c("UN", "UNK"), - tgt_dat = NULL, id_vars = oak_id_vars(), .warn = TRUE ) } \arguments{ +\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by +the variables indicated in \code{id_vars}. This parameter is optional, see +section Value for how the output changes depending on this argument value.} + +\item{tgt_var}{The target SDTM variable: a single string indicating the name +of variable to be derived.} + \item{raw_dat}{The raw dataset (dataframe); must include the variables passed in \code{id_vars} and \code{raw_var}.} @@ -30,16 +37,9 @@ element is taken as parsing format for each variable indicated in vector of formats. The first vector of formats is used for parsing the first variable in \code{raw_var}, and so on.} -\item{tgt_var}{The target SDTM variable: a single string indicating the name -of variable to be derived.} - \item{raw_unk}{A character vector of string literals to be regarded as missing values during parsing.} -\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by -the variables indicated in \code{id_vars}. This parameter is optional, see -section Value for how the output changes depending on this argument value.} - \item{id_vars}{Key variables to be used in the join between the raw dataset (\code{raw_dat}) and the target data set (\code{tgt_dat}).} @@ -88,11 +88,11 @@ md1 <- # indicating that these values are missing/unknown (unk). cm1 <- assign_datetime( + tgt_var = "CMSTDTC", raw_dat = md1, raw_var = "MDBDR", raw_fmt = "d-m-y", - raw_unk = c("UN", "UNK"), - tgt_var = "CMSTDTC" + raw_unk = c("UN", "UNK") ) cm1 @@ -147,11 +147,11 @@ cm_inter <- # data set `cm_inter`. cm2 <- assign_datetime( + tgt_dat = cm_inter, + tgt_var = "CMSTDTC", raw_dat = md1, raw_var = "MDBDR", - raw_fmt = "d-m-y", - tgt_var = "CMSTDTC", - tgt_dat = cm_inter + raw_fmt = "d-m-y" ) cm2 @@ -164,11 +164,11 @@ problems(cm2$CMSTDTC) # MDETM (correspondence is by positional matching). cm3 <- assign_datetime( + tgt_var = "CMSTDTC", raw_dat = md1, raw_var = c("MDEDR", "MDETM"), raw_fmt = c("d-m-y", "H:M:S"), - raw_unk = c("UN", "UNK"), - tgt_var = "CMSTDTC" + raw_unk = c("UN", "UNK") ) cm3 diff --git a/man/condition_by.Rd b/man/condition_add.Rd similarity index 80% rename from man/condition_by.Rd rename to man/condition_add.Rd index 7a5ff82c..900052ed 100644 --- a/man/condition_by.Rd +++ b/man/condition_add.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/cnd_df.R -\name{condition_by} -\alias{condition_by} +\name{condition_add} +\alias{condition_add} \title{Condition a data set based on specified conditions} \usage{ -condition_by(dat, ..., .na = NA, .env = rlang::env()) +condition_add(dat, ..., .na = NA, .dat2 = rlang::env()) } \arguments{ \item{dat}{A tibble.} @@ -13,7 +13,7 @@ condition_by(dat, ..., .na = NA, .env = rlang::env()) \item{.na}{Return value to be used when the conditions evaluate to \code{NA}.} -\item{.env}{An optional environment to look for variables involved in logical +\item{.dat2}{An optional environment to look for variables involved in logical expression passed in \code{...}. A data frame or a list can also be passed that will be coerced to an environment internally.} } diff --git a/man/contains_oak_id_vars.Rd b/man/contains_oak_id_vars.Rd index c872bbbe..21bc97fb 100644 --- a/man/contains_oak_id_vars.Rd +++ b/man/contains_oak_id_vars.Rd @@ -21,7 +21,7 @@ variables --- these are defined by the return value of \code{\link[=oak_id_vars] # `oak_id_vars()` is the function that defines what are the minimal set of # oak keys. Hence, by definition, the following code should always return # `TRUE`. -sdtm.oak:::contains_oak_id_vars(sdtm.oak:::oak_id_vars()) +sdtm.oak:::contains_oak_id_vars(oak_id_vars()) # Returns `FALSE`. sdtm.oak:::contains_oak_id_vars(character()) diff --git a/man/harcode.Rd b/man/harcode.Rd index e38424a5..573a267e 100644 --- a/man/harcode.Rd +++ b/man/harcode.Rd @@ -7,26 +7,33 @@ \title{Derive an SDTM variable with a hardcoded value} \usage{ hardcode_no_ct( + tgt_dat = NULL, + tgt_val, raw_dat, raw_var, tgt_var, - tgt_val, - tgt_dat = NULL, id_vars = oak_id_vars() ) hardcode_ct( + tgt_dat = NULL, + tgt_val, raw_dat, raw_var, tgt_var, - tgt_val, ct_spec, ct_clst, - tgt_dat = NULL, id_vars = oak_id_vars() ) } \arguments{ +\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by +the variables indicated in \code{id_vars}. This parameter is optional, see +section Value for how the output changes depending on this argument value.} + +\item{tgt_val}{The target SDTM value to be hardcoded into the variable +indicated in \code{tgt_var}.} + \item{raw_dat}{The raw dataset (dataframe); must include the variables passed in \code{id_vars} and \code{raw_var}.} @@ -36,13 +43,6 @@ raw variable in \code{raw_dat}.} \item{tgt_var}{The target SDTM variable: a single string indicating the name of variable to be derived.} -\item{tgt_val}{The target SDTM value to be hardcoded into the variable -indicated in \code{tgt_var}.} - -\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by -the variables indicated in \code{id_vars}. This parameter is optional, see -section Value for how the output changes depending on this argument value.} - \item{id_vars}{Key variables to be used in the join between the raw dataset (\code{raw_dat}) and the target data set (\code{raw_dat}).} @@ -87,10 +87,10 @@ md1 <- # Derive a new variable `CMCAT` by overwriting `MDRAW` with the # hardcoded value "GENERAL CONCOMITANT MEDICATIONS". hardcode_no_ct( + tgt_val = "GENERAL CONCOMITANT MEDICATIONS", raw_dat = md1, raw_var = "MDRAW", - tgt_var = "CMCAT", - tgt_val = "GENERAL CONCOMITANT MEDICATIONS" + tgt_var = "CMCAT" ) cm_inter <- @@ -107,11 +107,11 @@ cm_inter <- # hardcoded value "GENERAL CONCOMITANT MEDICATIONS" with a prior join to # `target_dataset`. hardcode_no_ct( + tgt_dat = cm_inter, + tgt_val = "GENERAL CONCOMITANT MEDICATIONS", raw_dat = md1, raw_var = "MDRAW", - tgt_var = "CMCAT", - tgt_val = "GENERAL CONCOMITANT MEDICATIONS", - tgt_dat = cm_inter + tgt_var = "CMCAT" ) # Controlled terminology specification @@ -121,13 +121,13 @@ hardcode_no_ct( # involving terminology recoding. `NA` values in `MDRAW` are preserved in # `CMCAT`. hardcode_ct( + tgt_dat = cm_inter, + tgt_var = "CMCAT", raw_dat = md1, raw_var = "MDRAW", - tgt_var = "CMCAT", tgt_val = "GENERAL CONCOMITANT MEDICATIONS", ct_spec = ct_spec, - ct_clst = "C66729", - tgt_dat = cm_inter + ct_clst = "C66729" ) } diff --git a/man/oak_id_vars.Rd b/man/oak_id_vars.Rd index af5550a3..86b9113b 100644 --- a/man/oak_id_vars.Rd +++ b/man/oak_id_vars.Rd @@ -22,9 +22,8 @@ oak_id, raw_source, and patient_number. Extra variable names may be indicated and passed in \code{extra_vars} which are appended to the default names. } \examples{ -sdtm.oak:::oak_id_vars() +oak_id_vars() -sdtm.oak:::oak_id_vars(extra_vars = "sample_id") +oak_id_vars(extra_vars = "sample_id") } -\keyword{internal} diff --git a/man/sdtm_assign.Rd b/man/sdtm_assign.Rd index 85601e3c..14b4ed03 100644 --- a/man/sdtm_assign.Rd +++ b/man/sdtm_assign.Rd @@ -5,25 +5,29 @@ \title{Derive an SDTM variable} \usage{ sdtm_assign( + tgt_dat = NULL, + tgt_var, raw_dat, raw_var, - tgt_var, ct_spec = NULL, ct_clst = NULL, - tgt_dat = NULL, id_vars = oak_id_vars() ) } \arguments{ +\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by +the variables indicated in \code{id_vars}. This parameter is optional, see +section Value for how the output changes depending on this argument value.} + +\item{tgt_var}{The target SDTM variable: a single string indicating the name +of variable to be derived.} + \item{raw_dat}{The raw dataset (dataframe); must include the variables passed in \code{id_vars} and \code{raw_var}.} \item{raw_var}{The raw variable: a single string indicating the name of the raw variable in \code{raw_dat}.} -\item{tgt_var}{The target SDTM variable: a single string indicating the name -of variable to be derived.} - \item{ct_spec}{Study controlled terminology specification: a dataframe with a minimal set of columns, see \code{\link[=ct_spec_vars]{ct_spec_vars()}} for details. This parameter is optional, if left as \code{NULL} no controlled terminology recoding is applied.} @@ -32,10 +36,6 @@ optional, if left as \code{NULL} no controlled terminology recoding is applied.} terminology to apply in the derivation. This parameter is optional, if left as \code{NULL}, all possible recodings in \code{ct_spec} are attempted.} -\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by -the variables indicated in \code{id_vars}. This parameter is optional, see -section Value for how the output changes depending on this argument value.} - \item{id_vars}{Key variables to be used in the join between the raw dataset (\code{raw_dat}) and the target data set (\code{tgt_dat}).} } diff --git a/man/sdtm_hardcode.Rd b/man/sdtm_hardcode.Rd index d8cb59a6..065d3942 100644 --- a/man/sdtm_hardcode.Rd +++ b/man/sdtm_hardcode.Rd @@ -5,26 +5,30 @@ \title{Derive an SDTM variable with a hardcoded value} \usage{ sdtm_hardcode( + tgt_dat = NULL, + tgt_var, raw_dat, raw_var, - tgt_var, tgt_val, ct_spec = NULL, ct_clst = NULL, - tgt_dat = NULL, id_vars = oak_id_vars() ) } \arguments{ +\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by +the variables indicated in \code{id_vars}. This parameter is optional, see +section Value for how the output changes depending on this argument value.} + +\item{tgt_var}{The target SDTM variable: a single string indicating the name +of variable to be derived.} + \item{raw_dat}{The raw dataset (dataframe); must include the variables passed in \code{id_vars} and \code{raw_var}.} \item{raw_var}{The raw variable: a single string indicating the name of the raw variable in \code{raw_dat}.} -\item{tgt_var}{The target SDTM variable: a single string indicating the name -of variable to be derived.} - \item{tgt_val}{The target SDTM value to be hardcoded into the variable indicated in \code{tgt_var}.} @@ -36,10 +40,6 @@ optional, if left as \code{NULL} no controlled terminology recoding is applied.} terminology to apply in the derivation. This parameter is optional, if left as \code{NULL}, all possible recodings in \code{ct_spec} are attempted.} -\item{tgt_dat}{Target dataset: a data frame to be merged against \code{raw_dat} by -the variables indicated in \code{id_vars}. This parameter is optional, see -section Value for how the output changes depending on this argument value.} - \item{id_vars}{Key variables to be used in the join between the raw dataset (\code{raw_dat}) and the target data set (\code{tgt_dat}).} } diff --git a/tests/testthat/test-assign.R b/tests/testthat/test-assign.R index 46d86a87..b26d7568 100644 --- a/tests/testthat/test-assign.R +++ b/tests/testthat/test-assign.R @@ -47,12 +47,12 @@ test_that("assign_ct works as expected with a conditioned `tgt_dat`", { result <- assign_ct( + tgt_dat = condition_add(vs_tgt_dat, VSTESTCD == "TEMP"), + tgt_var = "VSLOC", raw_dat = vs_raw_dat, raw_var = "TEMPLOC", - tgt_var = "VSLOC", ct_spec = ct_spec, - ct_clst = "C74456", - tgt_dat = condition_by(vs_tgt_dat, VSTESTCD == "TEMP") + ct_clst = "C74456" ) expected_result <- @@ -100,16 +100,16 @@ test_that("assign_ct works as expected with both `raw_dat` and `tgt_dat` as cond result <- assign_ct( - raw_dat = condition_by(fa_raw_dat, is.na(SPECTYP)), - raw_var = "SPCNM", - tgt_var = "FASPEC", - ct_spec = ct_spec, - ct_clst = "C78734", - tgt_dat = condition_by( + tgt_dat = condition_add( fa_tgt_dat, FATESTCD == "STATUS" & FAOBJ == "Severe Acute Resp Syndrome Coronavirus 2" - ) + ), + tgt_var = "FASPEC", + raw_dat = condition_add(fa_raw_dat, is.na(SPECTYP)), + raw_var = "SPCNM", + ct_spec = ct_spec, + ct_clst = "C78734" ) expected_result <- @@ -140,10 +140,10 @@ test_that("assign_ct works as expected with conditions across both data sets", { # meaningful. result1 <- assign_no_ct( - raw_dat = cm_raw_dat, - raw_var = "CMMODIFY", + tgt_dat = condition_add(cm_tgt_dat, CMMODIFY != CMTRT, .dat2 = cm_raw_dat), tgt_var = "CMMODIFY", - tgt_dat = condition_by(cm_tgt_dat, CMMODIFY != CMTRT, .env = cm_raw_dat) + raw_dat = cm_raw_dat, + raw_var = "CMMODIFY" ) # Because both data sets have to have the same number of records for the @@ -151,10 +151,10 @@ test_that("assign_ct works as expected with conditions across both data sets", { # raw data set itself. result2 <- assign_no_ct( - raw_dat = condition_by(cm_raw_dat, CMMODIFY != CMTRT, .env = cm_tgt_dat), - raw_var = "CMMODIFY", + tgt_dat = cm_tgt_dat, tgt_var = "CMMODIFY", - tgt_dat = cm_tgt_dat + raw_dat = condition_add(cm_raw_dat, CMMODIFY != CMTRT, .dat2 = cm_tgt_dat), + raw_var = "CMMODIFY" ) expected_result <- @@ -165,3 +165,4 @@ test_that("assign_ct works as expected with conditions across both data sets", { expect_equal(result2, expected_result) }) + diff --git a/tests/testthat/test-assign_datetime.R b/tests/testthat/test-assign_datetime.R index 5cb6e42c..36879636 100644 --- a/tests/testthat/test-assign_datetime.R +++ b/tests/testthat/test-assign_datetime.R @@ -22,22 +22,22 @@ test_that("assign_datetime: date and time conversion", { r"{There were 12 parsing problems\. Run `problems\(\)` on parsed results for details\.}" expect_warning(rlang::with_interactive( assign_datetime( + tgt_var = "CMSTDTC", raw_dat = md1, raw_var = c("MDEDR", "MDETM"), raw_fmt = c("d-m-y", "H:M:S"), - raw_unk = c("UN", "UNK"), - tgt_var = "CMSTDTC" + raw_unk = c("UN", "UNK") ) ), regexp = warning_msg) # If not run interactively then warnings should not be raised. expect_silent( cm1 <- assign_datetime( + tgt_var = "CMSTDTC", raw_dat = md1, raw_var = c("MDEDR", "MDETM"), raw_fmt = c("d-m-y", "H:M:S"), - raw_unk = c("UN", "UNK"), - tgt_var = "CMSTDTC" + raw_unk = c("UN", "UNK") ) ) @@ -72,7 +72,7 @@ test_that("assign_datetime: date and time conversion", { expected <- cm1 |> - dplyr::select("oak_id", "raw_source", "patient_number") |> + dplyr::select(dplyr::all_of(c("oak_id", "raw_source", "patient_number"))) |> dplyr::bind_cols(tibble::tibble(CMSTDTC = cmstdtc)) expect_equal(object = cm1, expected = expected) diff --git a/tests/testthat/test-hardcode.R b/tests/testthat/test-hardcode.R index 9f7ec73e..e95bb00f 100644 --- a/tests/testthat/test-hardcode.R +++ b/tests/testthat/test-hardcode.R @@ -18,7 +18,7 @@ oe_inter <- tibble::tribble( ) test_that("hardcode_no_ct works as expected", { - aesos_cnd <- condition_by(aesos, AESO == 1L & !is.na(AESOSP)) + aesos_cnd <- condition_add(aesos, AESO == 1L & !is.na(AESOSP)) result <- hardcode_no_ct( raw_dat = aesos_cnd, @@ -44,7 +44,7 @@ test_that("hardcode_no_ct works as expected", { }) test_that("hardcode_ct works as expected", { - aesos_cnd <- condition_by(aesos, AESO == 1L & is.na(AESOSP)) + aesos_cnd <- condition_add(aesos, AESO == 1L & is.na(AESOSP)) ct_spec <- tibble::tibble( codelist_code = "C117743", term_code = "C178048", From eea15807cd592c60fec4e3f112dbefb4776b5a5d Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Wed, 12 Jun 2024 18:52:42 +0000 Subject: [PATCH 08/23] A fix to derive study day --- R/derive_study_day.R | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/R/derive_study_day.R b/R/derive_study_day.R index 6a04c15c..679beb46 100644 --- a/R/derive_study_day.R +++ b/R/derive_study_day.R @@ -94,6 +94,10 @@ derive_study_day <- function(sdtm_in, ) } + # convert to character to verify the iso format + sdtm_in[[refdt]] <- as.character(sdtm_in[[refdt]]) + sdtm_in[[tgdt]] <- as.character(sdtm_in[[tgdt]]) + # refdt/tgdt should be in ISO format, otherwise throw warning sdtm_in[[refdt]] <- tryCatch( as.Date(sdtm_in[[refdt]], "%Y-%m-%d"), @@ -104,7 +108,7 @@ derive_study_day <- function(sdtm_in, e$message, call. = FALSE ) - NA + sdtm_in[[refdt]] } ) sdtm_in[[tgdt]] <- tryCatch( @@ -116,12 +120,12 @@ derive_study_day <- function(sdtm_in, e$message, call. = FALSE ) - NA + sdtm_in[[tgdt]] } ) - ref <- sdtm_in[[refdt]] - tgt <- sdtm_in[[tgdt]] + ref <- as.Date(sdtm_in[[refdt]]) + tgt <- as.Date(sdtm_in[[tgdt]]) # SDTMIG 4.4.4 Use of the Study Day Variables res <- ifelse(tgt >= ref, tgt - ref + 1L, tgt - ref) From 1b4c84957e6880fe43876c69755ff50a4713286c Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Wed, 12 Jun 2024 18:53:16 +0000 Subject: [PATCH 09/23] Algorithms Vignette update --- vignettes/articles/algo_sub_algo_combo.jpg | Bin 97016 -> 70345 bytes vignettes/articles/algorithms.Rmd | 153 +++++++++++---------- vignettes/articles/reusable_algorithms.jpg | Bin 173421 -> 113364 bytes 3 files changed, 80 insertions(+), 73 deletions(-) diff --git a/vignettes/articles/algo_sub_algo_combo.jpg b/vignettes/articles/algo_sub_algo_combo.jpg index ff9246da420c1bcc83d5bd7653eec04dc7f1eec7..cde7ff4a16f6728087c05a5bd5ed58458a463cd8 100644 GIT binary patch literal 70345 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Ö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

kxk#w!s>I*q7gjOMOo6*_+70u3y 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 If any collected study drug", - "causalities are 'Yes' then AE.AEREL is Y.
If all collected study", - "drug causalities are 'NA' then AE.AEREL is NA.
If no study drug", - "causalities are 'Yes' but there is at least one causality of 'No'", - "then AE.AEREL is N.
Individual study drug causality responses are", - "stored in AERELn in SUPPAE." + "One-to-one mapping between the raw source and a target that involves ", + "mapping a Date or time or datetime component. This mapping algorithm", + "also takes care of handling unknown dates and converting them into.", + "ISO8601 format." ), paste( "Mapping a hardcoded value to a target SDTM variable that is subject to terminology restrictions.", @@ -87,26 +88,30 @@ algorithms <- data.frame( "Mapping a hardcoded value to a target SDTM variable that has no terminology restrictions." ), paste( - "Indicates a dataset-level mapping. These mappings will", - "be applied to all SDTM records created from that source.", - "Also called a eCRF-level mappings in eCRF and dataset-level", - "mappings in eDT" + "Algorithm that is used to filter the source data and/or target domain", + "based on a condition. The mapping will be applied only if the condition is met.", + "The filter can be applied either at the source dataset or at target dataset or both.", + " This algorithm has to be used in conjunction with other algorithms, that is if the", + " condition is met perform the mapping using algorithms like assign_ct,", + "assign_no_ct, hardcode_ct, hardcode_no_ct, assign_datetime." ), paste( - "Instruction that `sdtm.oak` should not map the collected item to SDTM at all." + "Algorithm that is currently unique to AE.AEREL,", + "particularly when more than one drug is used in the study.
If any collected study drug", + "causalities are 'Yes' then AE.AEREL is Y.
If all collected study", + "drug causalities are 'NA' then AE.AEREL is NA.
If no study drug", + "causalities are 'Yes' but there is at least one causality of 'No'", + "then AE.AEREL is N.
Individual study drug causality responses are", + "stored in AERELn in SUPPAE." ), paste( - "Represents the If then else statement. This can be an if statement", - "with no else or with the else condition. This algorithm will be", - "used for the annotations where a condition has to be evaluated", - "before a mapping is performed. A sub-algorithm is required. If the", - "condition resolves to `TRUE`, the sub-algorithm will be executed." + "Indicates a dataset-level mapping. These mappings will", + "be applied to all SDTM records created from that source.", + "Also called an eCRF-level mappings in eCRF and dataset-level", + "mappings in eDT" ), paste( - "To indicate a join condition with a secondary source or multiple sources.", - "Merges are expressed at the domain level only", - "(not at data point or variable level).", - "This is a sub-algorithm and can only be used with algorithm DATASET_LEVEL." + "Instruction that `{sdtm.oak}` should not map the collected item to SDTM at all." ), paste( "Associate two domains based on the variables in each domain and how those are related.", @@ -115,7 +120,7 @@ algorithms <- data.frame( paste( "Consolidate the responses from more than one source variable into one target variable.", "Used when multiple responses may be given for a single SDTM column.", - "`sdtm.oak` will populate all target variable(s) after determining the number of responses provided." + "`{sdtm.oak}` will populate all target variable(s) after determining the number of responses provided." ), paste( "Consolidates the responses from more than one", @@ -125,57 +130,57 @@ algorithms <- data.frame( ), paste( "Sub-algorithm at the domain level that indicates some source records may", - "be removed during the `sdtm.oak` mapping process if determined to be duplicate records." + "be removed during the `{sdtm.oak}` mapping process if determined to be duplicate records." ), paste( "Sub-algorithm used at the domain level to group source records", "before mapping to SDTM. This is used in the event we need to collapse data", "collected across multiple rows into one row in SDTM but it is not a simple", "un-duplication effort. For example, the way infusion study drug", - "administration data requires us to create 1 SDTM record in EC from 1 or more source", - "records in the mixed log form. When there is more than one source record,", + "administration data requires us to create 1 SDTM record in EC from 1 or more sources", + "records. When there is more than one source record,", "we need to take the earliest collected infusion start date (for ECSTDTC) and", "the latest collected infusion end date within an eCRF instance." + ), + paste( + "To indicate a join condition with a secondary source or multiple sources.", + "Merges are expressed at the domain level only", + "(not at data point or variable level).", + "This is a sub-algorithm and can only be used with algorithm DATASET_LEVEL." ) ), `Example` = c( paste( "MH.MHTERM
", - "VS.VSDTC
", - "MH.MHTERM = [LNGCAHX1.HSTYP] || ' ' || 'NON-METASTATIC LUNG CANCER'
", - "CM.CMINDC = [MD9.MDCIND] || ' ' || [MD9.MDCINDSP]" + "AE.AETERM" ), paste("VS.VSPOS
", "VS.VSLAT"), - paste("For AE.AEREL and AERELn in SUPPAE"), + paste("MH.MHSTDTC
", "AE.AEENDTC"), paste( "MH.MHPRESP = 'Y'
", - "VS.VSTEST = 'Systolic Blood Pressure'
", - "VS.VSORRESU = 'mmHg'
" + "
VS.VSTEST = 'Systolic Blood Pressure'
", + "
VS.VSORRESU = 'mmHg'
" ), paste( "FA.FASCAT = 'COVID-19 PROBABLE CASE'
", - "CM.CMTRT = 'FLUIDS'" + "
CM.CMTRT = 'FLUIDS'" ), paste( - "VS = 'Vital Signs'
", - "MH.MHCAT = 'PROSTATE CANCER HISTORY'
" + "If If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE'.
", + "
VS.VSMETHOD when VSTESTCD = 'TEMP'
", + "
If collected value in raw variable DOS is numeric then CM.CMDOSE
", + "
If collected value in raw variable MOD is different to CMTRT then map to CM.CMMODIFY" ), - paste(""), + paste("For AE.AEREL and AERELn in SUPPAE"), paste( - "If 'Ongoing' then MH.MHENRTPT = 'ONGOING'
Else MH.MHENRTPT = 'BEFORE'

", - "If [HX1.STATUS] is present then MH.MHENTPT = 'FIRST DOSE OF STUDY DRUG'

", - "If checked then MH.MHSTTPT = 'SCREENING'
Else NOT SUBMITTED

", - "VS.VSMETHOD when VS.VSTESTCD = 'TEMP'", - "(Though the annotation text does not have the If condition,", - "we need to map VSMETHOD only if the VSTESTCD is TEMP. The IF_THEN_ELSE will be", - "used as the Algorithm for such cases even the 'If' condition is not explicitly", - "defined in the annotation text)" + "VS = 'Vital Signs'
", + "
MH.MHCAT = 'PROSTATE CANCER HISTORY'
" ), - paste("AE = 'Adverse Events' on the early phase SAE eCRF"), + paste(""), paste("BE record related to BS record via RELREC"), paste( "AE.AERELNST/ AERELNSn IN SUPPAE

", - "DM.RACE, if only one value is selected.
", + "
DM.RACE, if only one value is selected.
", "DM.RACE = MULTIPLE, if more than one value is selected.
", "RACEn in SUPPDM where n = 1 to N selected values" ), @@ -184,28 +189,30 @@ algorithms <- data.frame( "CRACE1 will be 'FILIPINO' and CRACE2 will be 'SAMOAN'.
", "If only Chinese is checked, CRACE1 will be 'CHINESE'." ), - paste("AE = 'Adverse Events' on early phase SAE form"), - paste("EC = 'Exposure as Collected'") - ), - stringsAsFactors = TRUE + paste("Remove duplicates on the Vital signs raw dataset based on subject number"), + paste("EC = 'Exposure as Collected'"), + paste( + "Merge AE raw dataset with SAE based on Subject number." + ) + ),stringsAsFactors = TRUE ) knitr::kable(algorithms) ``` ## Sub-algorithms -sdtm.oak supports two levels for defining algorithms. For example, there +{sdtm.oak} supports two levels for defining algorithms. For example, there are some SDTM mappings where a certain action has to be taken only when a condition is met. In such cases, the primary algorithm checks for the condition, and the sub-algorithm executes the mappings when the condition is met. -Currently, sub-algorithms must be provided for these main algorithms. +Currently, sub-algorithms must be provided for this main algorithms. -- IF_THEN_ELSE -- DATASET_LEVEL +- condition_add +- dataset_level -Algorithms can be interchangeably used as algorithms and as +Some algorithms can be interchangeably used as algorithms and as sub-algorithms as seen below (not an exhaustive list) ![](algo_sub_algo_combo.jpg){width="650px"} diff --git a/vignettes/articles/reusable_algorithms.jpg b/vignettes/articles/reusable_algorithms.jpg index 71c8962b72db260535b73b51d8d8f96afb0f927e..5b5bd0278031dc27ebfb499ff4088fb21f2a49bd 100644 GIT binary patch literal 113364 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�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 &0_k`I&;Sn1Gx^xJ>6@bZ=$kJ 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�I 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 Date: Wed, 12 Jun 2024 18:53:38 +0000 Subject: [PATCH 10/23] cm template code update --- inst/cm_domain/cm_sdtm_oak_ct.csv | 69 ++++++++-------- inst/cm_domain/create_cm_template.R | 124 ++++++++++++---------------- 2 files changed, 89 insertions(+), 104 deletions(-) diff --git a/inst/cm_domain/cm_sdtm_oak_ct.csv b/inst/cm_domain/cm_sdtm_oak_ct.csv index bf231e7e..ffbe0903 100644 --- a/inst/cm_domain/cm_sdtm_oak_ct.csv +++ b/inst/cm_domain/cm_sdtm_oak_ct.csv @@ -1,35 +1,34 @@ -codelist_code,term_code,CodedData,term_value,collected_value,term_preferred_term,term_synonyms,raw_codelist -C71113,C25473,QD,QD,QD (Every Day),Daily,/day; Daily; Per Day,FREQ_CV1 -C71113,C64496,BID,BID,BID (Twice a Day),Twice Daily,BD; Twice per day,FREQ_CV1 -C71113,C64499,PRN,PRN,PRN (As Needed),As Needed,As needed,FREQ_CV1 -C71113,C64516,Q2H,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours,FREQ_CV1 -C71113,C64530,QID,QID,QID (4 Times a Day),Four Times Daily,4 times per day,FREQ_CV1 -C66726,C25158,CAPSULE,CAPSULE,Capsule,Capsule Dosage Form,cap,FRM_CV1 -C66726,C25394,PILL,PILL,Pill,Pill Dosage Form,NA,FRM_CV1 -C66726,C29167,LOTION,LOTION,Lotion,Lotion Dosage Form,NA,FRM_CV1 -C66726,C42887,AEROSOL,AEROSOL,Aerosol,Aerosol Dosage Form,aer,FRM_CV1 -C66726,C42944,INHALANT,INHALANT,Inhalant,Inhalant Dosage Form,NA,FRM_CV1 -C66726,C42946,INJECTION,INJECTION,Injection,Injectable Dosage Form,NA,FRM_CV1 -C66726,C42953,LIQUID,LIQUID,Liquid,Liquid Dosage Form,NA,FRM_CV1 -C66726,C42998,TABLET,TABLET,Tablet,Tablet Dosage Form,tab,FRM_CV1 -C66742,C49488,Y,Y,Yes,Yes,Yes,NY_CV1 -C66729,C28161,INTRAMUSCULAR,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration,NA,ROUTE_CV1 -C66729,C38210,EPIDURAL,EPIDURAL,EP (Epidural),Epidural Route of Administration,NA,ROUTE_CV1 -C66729,C38222,INTRA-ARTERIAL,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration,NA,ROUTE_CV1 -C66729,C38223,INTRA-ARTICULAR,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration,NA,ROUTE_CV1 -C66729,C38287,OPHTHALMIC,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration,NA,ROUTE_CV1 -C66729,C38288,ORAL,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO,ROUTE_CV1 -C66729,C38305,TRANSDERMAL,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration,NA,ROUTE_CV1 -C66729,C38311,UNKNOWN,UNKNOWN,Unknown,Unknown Route of Administration,NA,ROUTE_CV1 -C71620,C25613,%,%,%,Percentage,Percentage,UNIT_CV1 -C71620,C28253,MG,mg,mg,Milligram,Milligram,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV1 -C71620,C48155,G,g,g,Gram,Gram,UNIT_CV1 -C71620,C48480,CAPSULE,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit,UNIT_CV1 -C71620,C48542,TABLET,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit,UNIT_CV1 -C71620,C48579,IU,IU,IU,International Unit,IE; International Unit,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV5 -C66728,C25629,BEFORE,BEFORE,Prior,Prior,,NA -C66728,C53279,ONGOING,ONGOING,Continue,Continue,Continuous,NA -C66734,C49568,CM,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications,NA -,,,,,,, \ No newline at end of file +codelist_code,term_code,CodedData,term_value,collected_value,term_preferred_term,term_synonyms,raw_codelist +C71113,C25473,QD,QD,QD (Every Day),Daily,/day; Daily; Per Day,FREQ_CV1 +C71113,C64496,BID,BID,BID (Twice a Day),Twice Daily,BD; Twice per day,FREQ_CV1 +C71113,C64499,PRN,PRN,PRN (As Needed),As Needed,As needed,FREQ_CV1 +C71113,C64516,Q2H,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours,FREQ_CV1 +C71113,C64530,QID,QID,QID (4 Times a Day),Four Times Daily,4 times per day,FREQ_CV1 +C66726,C25158,CAPSULE,CAPSULE,Capsule,Capsule Dosage Form,cap,FRM_CV1 +C66726,C25394,PILL,PILL,Pill,Pill Dosage Form,NA,FRM_CV1 +C66726,C29167,LOTION,LOTION,Lotion,Lotion Dosage Form,NA,FRM_CV1 +C66726,C42887,AEROSOL,AEROSOL,Aerosol,Aerosol Dosage Form,aer,FRM_CV1 +C66726,C42944,INHALANT,INHALANT,Inhalant,Inhalant Dosage Form,NA,FRM_CV1 +C66726,C42946,INJECTION,INJECTION,Injection,Injectable Dosage Form,NA,FRM_CV1 +C66726,C42953,LIQUID,LIQUID,Liquid,Liquid Dosage Form,NA,FRM_CV1 +C66726,C42998,TABLET,TABLET,Tablet,Tablet Dosage Form,tab,FRM_CV1 +C66742,C49488,Y,Y,Yes,Yes,Yes,NY_CV1 +C66729,C28161,INTRAMUSCULAR,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration,NA,ROUTE_CV1 +C66729,C38210,EPIDURAL,EPIDURAL,EP (Epidural),Epidural Route of Administration,NA,ROUTE_CV1 +C66729,C38222,INTRA-ARTERIAL,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration,NA,ROUTE_CV1 +C66729,C38223,INTRA-ARTICULAR,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration,NA,ROUTE_CV1 +C66729,C38287,OPHTHALMIC,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration,NA,ROUTE_CV1 +C66729,C38288,ORAL,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO,ROUTE_CV1 +C66729,C38305,TRANSDERMAL,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration,NA,ROUTE_CV1 +C66729,C38311,UNKNOWN,UNKNOWN,Unknown,Unknown Route of Administration,NA,ROUTE_CV1 +C71620,C25613,%,%,%,Percentage,Percentage,UNIT_CV1 +C71620,C28253,MG,mg,mg,Milligram,Milligram,UNIT_CV1 +C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV1 +C71620,C48155,G,g,g,Gram,Gram,UNIT_CV1 +C71620,C48480,CAPSULE,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit,UNIT_CV1 +C71620,C48542,TABLET,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit,UNIT_CV1 +C71620,C48579,IU,IU,IU,International Unit,IE; International Unit,UNIT_CV1 +C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV5 +C66728,C25629,BEFORE,BEFORE,Prior,Prior,,NA +C66728,C53279,ONGOING,ONGOING,Continue,Continue,Continuous,NA +C66734,C49568,CM,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications,NA diff --git a/inst/cm_domain/create_cm_template.R b/inst/cm_domain/create_cm_template.R index e0840125..8c7377de 100644 --- a/inst/cm_domain/create_cm_template.R +++ b/inst/cm_domain/create_cm_template.R @@ -20,7 +20,7 @@ study_ct <- read.csv(system.file("cm_domain/cm_sdtm_oak_ct.csv", # Read in raw data cm_raw <- read.csv(system.file("cm_domain/cm_raw_data.csv", - package = "sdtm.oak")) |> + package = "sdtm.oak")) %>% generate_oak_id_vars(pat_var = "PATNUM", raw_src = "cm_raw") @@ -32,47 +32,47 @@ cm <- raw_dat = cm_raw, raw_var = "MDRAW", tgt_var = "CMTRT" - ) |> + ) %>% # Derive CMGRPID assign_no_ct( raw_dat = cm_raw, raw_var = "MDNUM", tgt_var = "CMGRPID", id_vars = oak_id_vars() - ) |> + ) %>% # DERIVE CMINDC assign_no_ct( raw_dat = cm_raw, raw_var = "MDIND", tgt_var = "CMINDC", id_vars = oak_id_vars() - ) |> + ) %>% # Derive CMSTDTC. This function calls create_iso8601 assign_datetime( raw_dat = cm_raw, raw_var = c("MDBDR", "MDBTM"), tgt_var = "CMSTDTC", - raw_fmt = c("d-m-y", "H:M"), + raw_fmt = c(list(c("d-m-y", "dd mmm yyyy")), "H:M"), raw_unk = c("UN", "UNK") - ) |> + ) %>% # Derive qualifier CMSTRTPT Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE' hardcode_ct( - raw_dat = add_cond(cm_raw, MDPRIOR == "1"), + raw_dat = condition_by(cm_raw, MDPRIOR == "1"), raw_var = "MDPRIOR", tgt_var = "CMSTRTPT", tgt_val = "BEFORE", ct_spec = study_ct, ct_clst = "C66728", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMSTTPT Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING' hardcode_no_ct( - raw_dat = add_cond(cm_raw, MDPRIOR == "1"), + raw_dat = condition_by(cm_raw, MDPRIOR == "1"), raw_var = "MDPRIOR", tgt_var = "CMSTTPT", tgt_val = "SCREENING", id_vars = oak_id_vars() - ) |> + ) %>% # Derive CMENDTC. This function calls create_iso8601 assign_datetime( raw_dat = cm_raw, @@ -80,48 +80,48 @@ cm <- tgt_var = "CMENDTC", raw_fmt = c("d-m-y", "H:M"), raw_unk = c("UN", "UNK") - ) |> + ) %>% # Derive qualifier CMENRTPT Annotation text is If MDONG == 1 then CM.CMENRTPT = 'ONGOING' hardcode_ct( - raw_dat = add_cond(cm_raw, MDONG == "1"), + raw_dat = condition_by(cm_raw, MDONG == "1"), raw_var = "MDONG", tgt_var = "CMENRTPT", tgt_val = "ONGOING", ct_spec = study_ct, ct_clst = "C66728", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMENTPT Annotation text is If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' hardcode_no_ct( - raw_dat = add_cond(cm_raw, MDONG == "1"), + raw_dat = condition_by(cm_raw, MDONG == "1"), raw_var = "MDONG", tgt_var = "CMENTPT", tgt_val = "DATE OF LAST ASSESSMENT", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMDOS If collected value in raw_var DOS is numeric then CM.CMDOSE assign_no_ct( - raw_dat = add_cond(cm_raw, is.numeric(DOS)), + raw_dat = condition_by(cm_raw, is.numeric(DOS)), raw_var = "DOS", tgt_var = "CMDOS", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMDOS If collected value in raw_var DOS is character then CM.CMDOSTXT assign_no_ct( - raw_dat = add_cond(cm_raw, is.character(DOS)), + raw_dat = condition_by(cm_raw, is.character(DOS)), raw_var = "DOS", tgt_var = "CMDOSTXT", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMDOSU assign_ct( raw_dat = cm_raw, - raw_var = "MDFORM", - tgt_var = "DOSU", + raw_var = "DOSU", + tgt_var = "CMDOSU", ct_spec = study_ct, ct_clst = "C71620", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMDOSFRM assign_ct( raw_dat = cm_raw, @@ -130,107 +130,93 @@ cm <- ct_spec = study_ct, ct_clst = "C66726", id_vars = oak_id_vars() - ) |> + ) %>% # DERIVE CMROUTE assign_ct( raw_dat = cm_raw, - raw_var = MDFORM, - tgt_var = "MDRTE", + raw_var = "MDRTE", + tgt_var = "CMROUTE", ct_spec = study_ct, ct_clst = "C66729", id_vars = oak_id_vars() - ) |> + ) %>% # DERIVE CMDOSFRQ assign_ct( raw_dat = cm_raw, - raw_var = MDFRQ, - tgt_var = CMDOSFRQ, + raw_var = "MDFRQ", + tgt_var = "CMDOSFRQ", ct_spec = study_ct, ct_clst = "C71113", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMPROPH Annotation text is If MDPROPH == 1 then CM.CMPROPH = 'Y' hardcode_ct( - raw_dat = add_cond(cm_raw, MDPROPH == "1"), + raw_dat = condition_by(cm_raw, MDPROPH == "1"), raw_var = "MDPROPH", tgt_var = "CMPROPH", tgt_val = "Y", ct_spec = study_ct, ct_clst = "C66742", id_vars = oak_id_vars() - ) |> + ) %>% # Derive qualifier CMMODIFY Annotation text If collected value in CMMODIFY # in cm_raw is different to CM.CMTRT then # assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY) - assign_no_ct( + {assign_no_ct( raw_dat = cm_raw, raw_var = "CMMODIFY", - # add_cond = (cm_raw$CMMODIFY == .data$CMTRT), + tgt_dat = condition_by(. , CMMODIFY != CMTRT, .env = cm_raw), tgt_var = "CMMODIFY", id_vars = oak_id_vars() - ) |> + )} %>% # Derive CMDRG assign_no_ct( raw_dat = cm_raw, raw_var = "CMDRG", - tgt_var = "CMDRG" - ) |> + tgt_var = "CMDRG", + id_vars = oak_id_vars() + ) %>% # Derive CMDRGCD assign_no_ct( raw_dat = cm_raw, raw_var = "CMDRGCD", - tgt_var = "CMDRGCD" - ) |> + tgt_var = "CMDRGCD", + id_vars = oak_id_vars() + ) %>% # Derive CMDECOD assign_no_ct( raw_dat = cm_raw, - raw_var = CMDECOD, - tgt_var = CMDECOD - ) |> + raw_var = "CMDECOD", + tgt_var = "CMDECOD", + id_vars = oak_id_vars() + ) %>% # Derive CMPNCD assign_no_ct( raw_dat = cm_raw, raw_var = "CMPNCD", - tgt_var = "CMPNCD" - ) |> + tgt_var = "CMPNCD", + id_vars = oak_id_vars() + ) %>% dplyr::mutate( STUDYID = "test_study", DOMAIN = "CM", CMCAT = "GENERAL CONMED", - USUBJID = "test_study" || "-" || cm_raw$PATNUM - ) |> - # DERIVE VISIT - assign_ct( - raw_dat = cm_raw, - raw_var = "INSTANCE", - tgt_var = "VISIT", - ct_spec = study_ct, - ct_clst = "VISIT", - id_vars = oak_id_vars() - ) |> - # DERIVE VISITNUM - assign_ct( - raw_dat = cm_raw, - raw_var = "INSTANCE", - tgt_var = "VISITNUM", - ct_spec = study_ct, - ct_clst = "VISITNUM", - id_vars = oak_id_vars() - ) |> - derive_seq(tgt_var = "VSSEQ", - rec_vars= c("USUBJID", "CMTRT")) |> + USUBJID = paste0("test_study", "-", cm_raw$PATNUM) + ) %>% + # derive_seq(tgt_var = "VSSEQ", + # rec_vars= c("USUBJID", "CMTRT")) %>% derive_study_day( - sdtm_in = .data, + sdtm_in = ., dm_domain = dm, tgdt = "CMENDTC", refdt = "RFXSTDTC", study_day_var = "CMENDY" - ) |> + ) %>% derive_study_day( - sdtm_in = .data, + sdtm_in = ., dm_domain = dm, tgdt = "CMSTDTC", refdt = "RFXSTDTC", study_day_var = "CMSTDY" - ) |> + ) %>% dplyr::select("STUDYID", "USUBJID", everything()) From 99ea4280837730c8653b5132ab090321b859f823 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Fri, 14 Jun 2024 06:18:48 +0000 Subject: [PATCH 11/23] A function to help display of dataset in Vignette --- NAMESPACE | 2 + R/dataset_oak_vignette.R | 85 +++++++++++++++++++++++++++++++++++++ inst/www/style.css | 16 +++++++ man/dataset_oak_vignette.Rd | 33 ++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 R/dataset_oak_vignette.R create mode 100644 inst/www/style.css create mode 100644 man/dataset_oak_vignette.Rd diff --git a/NAMESPACE b/NAMESPACE index c8dd2b14..e00ea373 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,8 +13,10 @@ export(create_iso8601) export(ct_map) export(ct_spec_example) export(ct_spec_vars) +export(dataset_oak_vignette) export(derive_study_day) export(fmt_cmp) +export(generate_oak_id_vars) export(hardcode_ct) export(hardcode_no_ct) export(oak_id_vars) diff --git a/R/dataset_oak_vignette.R b/R/dataset_oak_vignette.R new file mode 100644 index 00000000..67d3ac3f --- /dev/null +++ b/R/dataset_oak_vignette.R @@ -0,0 +1,85 @@ +#' Output a Dataset in a Vignette in the sdtm.oak Format +#' +#' Output a dataset in a vignette with the pre-specified sdtm.oak format. +#' +#' @param dataset Dataset to output in the vignette +#' +#' @param display_vars Variables selected to demonstrate the outcome of the mapping +#' +#' Permitted Values: list of variables +#' +#' Default is NULL +#' +#' If `display_vars` is not NULL, only the selected variables are visible in the vignette while the +#' other variables are hidden. They can be made visible by clicking the`Choose the columns to +#' display` button. +#' +#' @param filter Filter condition +#' +#' The specified condition is applied to the dataset before it is displayed. +#' +#' Permitted Values: a condition +#' +#' @return A HTML table +#' +#' @keywords dev_utility +#' +#' @export +#' +dataset_oak_vignette <- function(dataset, display_vars = NULL, filter = NULL) { + + #assert_data_frame(dataset, required_vars = display_vars) + filter <- admiraldev::assert_filter_cond(rlang::enexpr(filter), optional = TRUE) + + out <- dataset %>% + admiraldev::filter_if(filter) %>% + dplyr::mutate(across(where(is.character), as.factor)) + + # Create a short markdown table when this function is called outside {pkgdown} + if (!identical(Sys.getenv("IN_PKGDOWN"), "true")) { + if (is.null(display_vars)) { + return(knitr::kable(utils::head(out, 10))) + } else { + return(knitr::kable(utils::head(select(out, !!!display_vars), 10))) + } + } + + if (!is.null(display_vars)) { + hide_columns <- which(!(colnames(out) %in% vars2chr(display_vars))) + cols_to_hide <- list(list(targets = hide_columns - 1, visible = FALSE)) + } else { + cols_to_hide <- list() + } + htmltools::tagList( + htmltools::htmlDependency( + name = "dt-scroll", + version = "1.0.0", + src = "www", + stylesheet = "style.css", + package = "sdtm.oak" + ), + DT::datatable( + out, + rownames = FALSE, + filter = "top", + height = "auto", + width = "auto", + extensions = c("Buttons", "ColReorder", "Scroller"), + options = list( + columnDefs = cols_to_hide, + searchHighlight = TRUE, + searching = TRUE, + pageLength = 5, + lengthMenu = c(5, 10, 15, 20, 50, 100), + dom = "ipl>", + buttons = list(list( + extend = "colvis", + text = "Choose the columns to display", + scroller = TRUE, + collectionLayout = "fixed two-column" + )), + colReorder = TRUE + ) + ) + ) +} diff --git a/inst/www/style.css b/inst/www/style.css new file mode 100644 index 00000000..2dc98412 --- /dev/null +++ b/inst/www/style.css @@ -0,0 +1,16 @@ +.dt-scroll { + overflow-x: auto; + width: 100%; + max-height: 600px; +} +.dt-scroll .dataTable thead tr th, +.dt-scroll thead tr td { + position: sticky; + background-color: #FFFFFF; +} +.dt-scroll thead tr th { + top: 0; +} +.dt-scroll thead tr td { + top: 2.45em; +} diff --git a/man/dataset_oak_vignette.Rd b/man/dataset_oak_vignette.Rd new file mode 100644 index 00000000..eac9c55e --- /dev/null +++ b/man/dataset_oak_vignette.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dataset_oak_vignette.R +\name{dataset_oak_vignette} +\alias{dataset_oak_vignette} +\title{Output a Dataset in a Vignette in the sdtm.oak Format} +\usage{ +dataset_oak_vignette(dataset, display_vars = NULL, filter = NULL) +} +\arguments{ +\item{dataset}{Dataset to output in the vignette} + +\item{display_vars}{Variables selected to demonstrate the outcome of the mapping + +Permitted Values: list of variables + +Default is NULL + +If \code{display_vars} is not NULL, only the selected variables are visible in the vignette while the +other variables are hidden. They can be made visible by clicking the\verb{Choose the columns to display} button.} + +\item{filter}{Filter condition + +The specified condition is applied to the dataset before it is displayed. + +Permitted Values: a condition} +} +\value{ +A HTML table +} +\description{ +Output a dataset in a vignette with the pre-specified sdtm.oak format. +} +\keyword{dev_utility} From 128d4dc1d08b59eaf9c4d8165e60f442b3b76640 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Fri, 14 Jun 2024 06:19:24 +0000 Subject: [PATCH 12/23] Template update --- inst/cm_domain/create_cm_template.R | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/inst/cm_domain/create_cm_template.R b/inst/cm_domain/create_cm_template.R index 8c7377de..79e7b3b7 100644 --- a/inst/cm_domain/create_cm_template.R +++ b/inst/cm_domain/create_cm_template.R @@ -57,7 +57,7 @@ cm <- ) %>% # Derive qualifier CMSTRTPT Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE' hardcode_ct( - raw_dat = condition_by(cm_raw, MDPRIOR == "1"), + raw_dat = condition_add(cm_raw, MDPRIOR == "1"), raw_var = "MDPRIOR", tgt_var = "CMSTRTPT", tgt_val = "BEFORE", @@ -67,7 +67,7 @@ cm <- ) %>% # Derive qualifier CMSTTPT Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING' hardcode_no_ct( - raw_dat = condition_by(cm_raw, MDPRIOR == "1"), + raw_dat = condition_add(cm_raw, MDPRIOR == "1"), raw_var = "MDPRIOR", tgt_var = "CMSTTPT", tgt_val = "SCREENING", @@ -83,7 +83,7 @@ cm <- ) %>% # Derive qualifier CMENRTPT Annotation text is If MDONG == 1 then CM.CMENRTPT = 'ONGOING' hardcode_ct( - raw_dat = condition_by(cm_raw, MDONG == "1"), + raw_dat = condition_add(cm_raw, MDONG == "1"), raw_var = "MDONG", tgt_var = "CMENRTPT", tgt_val = "ONGOING", @@ -93,7 +93,7 @@ cm <- ) %>% # Derive qualifier CMENTPT Annotation text is If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' hardcode_no_ct( - raw_dat = condition_by(cm_raw, MDONG == "1"), + raw_dat = condition_add(cm_raw, MDONG == "1"), raw_var = "MDONG", tgt_var = "CMENTPT", tgt_val = "DATE OF LAST ASSESSMENT", @@ -101,14 +101,14 @@ cm <- ) %>% # Derive qualifier CMDOS If collected value in raw_var DOS is numeric then CM.CMDOSE assign_no_ct( - raw_dat = condition_by(cm_raw, is.numeric(DOS)), + raw_dat = condition_add(cm_raw, is.numeric(DOS)), raw_var = "DOS", tgt_var = "CMDOS", id_vars = oak_id_vars() ) %>% # Derive qualifier CMDOS If collected value in raw_var DOS is character then CM.CMDOSTXT assign_no_ct( - raw_dat = condition_by(cm_raw, is.character(DOS)), + raw_dat = condition_add(cm_raw, is.character(DOS)), raw_var = "DOS", tgt_var = "CMDOSTXT", id_vars = oak_id_vars() @@ -151,7 +151,7 @@ cm <- ) %>% # Derive qualifier CMPROPH Annotation text is If MDPROPH == 1 then CM.CMPROPH = 'Y' hardcode_ct( - raw_dat = condition_by(cm_raw, MDPROPH == "1"), + raw_dat = condition_add(cm_raw, MDPROPH == "1"), raw_var = "MDPROPH", tgt_var = "CMPROPH", tgt_val = "Y", @@ -165,7 +165,7 @@ cm <- {assign_no_ct( raw_dat = cm_raw, raw_var = "CMMODIFY", - tgt_dat = condition_by(. , CMMODIFY != CMTRT, .env = cm_raw), + tgt_dat = condition_add(. , CMMODIFY != CMTRT, .env = cm_raw), tgt_var = "CMMODIFY", id_vars = oak_id_vars() )} %>% From 754d6c78ac66aab626bbd1061976c5adc07d0bde Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Fri, 14 Jun 2024 06:19:45 +0000 Subject: [PATCH 13/23] Raw data change --- inst/cm_domain/cm_raw_data.csv | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/inst/cm_domain/cm_raw_data.csv b/inst/cm_domain/cm_raw_data.csv index 5ffc75bf..10390854 100644 --- a/inst/cm_domain/cm_raw_data.csv +++ b/inst/cm_domain/cm_raw_data.csv @@ -1,15 +1,15 @@ -PATNUM,SUBJSTAT,SITENM,INSTANCE,INSTRN,FOLDER,FOLDERL,FOLDERSQ,FORM,FORML,DATAPGID,PGREPNUM,RECORDDT,RECORDID,RECPOS,RECSTAT,MDNUM,MDNUM_RAW,MDREC,MDRAW,MDIND,MDBDR,MDBDTU,MDBTM,MDBTMU,MDPRIOR,MDEDR,MDEDT,MDETM,MDETMU,MDONG,DOS,DOSU,DOSUV,MDFORM,MDRTE,MDFRQ,MDPROPH,TERMID,SRCLN,RAVRFID,CMMODIFY,CMDRG,CMDRGCD,CMDECOD,CMPNCD,SPLIT,OMIT,ACTTYP,ACTTEXT,CMDICT,CMCLAS,CMCLASCD,CMATC4,CMATC4CD,CMATC3,CMATC3CD,CMATC2,CMATC2CD,CMATC1,CMATC1CD,CLASSNUM -375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111885785,1,N,1,1,No,BABY ASPIRIN,,,1,,1,1,,,,0,1,10,mg,MG,Tablet,PO (Oral),QD (Every Day),0,109576058,20,5652739,BABY ASPIRIN,BABY ASPIRIN,2701701,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 -375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111969387,2,N,2,2,No,CORTISPORIN,NAUSEA,15-Sep-20,0,,1,0,,,,0,1,50,g,G,Pill,PO (Oral),,0,105820348,28,5533807,CORTISPORIN (UNITED STATES),CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03C,OPHTHALMOLOGICAL AND OTOLOGICAL PREPARATIONS,S03,SENSORY ORGANS,S,1 -376,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56407664,0,,111939965,1,N,1,1,No,ASPIRIN,ANEMIA,17-Feb-21,0,8:00,0,0,17-Feb-21,2/17/21,,0,0,,,,,,,0,80619660,8,4297014,ASPIRIN,ASPIRIN [ACETYLSALICYLIC ACID],2701004,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,111942855,1,N,1,1,No,DIPHENHYDRAMINE HCL,NAUSEA,4-Oct-20,0,9:00,0,0,,,,0,1,50,mg,MG,Capsule,PO (Oral),BID (Twice a Day),0,79751919,3,4240092,DIPHENHYDRAMINE HCL,DIPHENHYDRAMINE HCL,402246,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972536,2,N,2,2,No,PARCETEMOL,PYREXIA,20-Jan-20,0,10:00,0,0,20-Jan-20,1/20/20,10:00,0,0,,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,129972536,2,,,,,,,,,,,,,,,,,,,,,, -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972541,3,N,3,3,No,VOMIKIND,VOMITINGS,UN UNK 2019,1,,1,0,UN UNK 2019,6/15/19,,1,0,,Tablet,TABLET,,PO (Oral),PRN (As Needed),1,129972541,3,,,,,,,,,,,,,,,,,,,,,, -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972568,4,N,5,5,No,ZENFLOX OZ,DIARHHEA,20 UNK 2019,0,10:00,0,0,20 UNK 2019,6/15/19,,1,0,,mL,ML,Injection,IM (Intramuscular),PRN (As Needed),1,129972568,4,,,,,,,,,,,,,,,,,,,,,, -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472439,4,N,4,4,No,AMITRYPTYLINE,COLD,UN UNK 2020,0,,1,1,UN UNK 2020,6/15/20,,1,0,12,g,G,Inhalant,IA (Intra-arterial),QD (Every Day),0,81845879,6,4382628,AMITRIPTYLINE,AMITRIPTYLINE,2201001,AMITRIPTYLINE,2201001,,,SPELLING UPDATE,AMITRIPTYLINE,"WHODRUG GLOBAL B3 MARCH 1, 2021",DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,UROLOGICALS,G04B,UROLOGICALS,G04,GENITO URINARY SYSTEM AND SEX HORMONES,G,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472436,1,N,1,1,No,BENADRYL,FEVER,26-Jan-20,0,9:00,0,0,26-Jan-20,1/26/20,7:00,0,0,100,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,95547017,4,5211852,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472437,2,N,2,2,Yes,DIPHENHYDRAMINE HYDROCHLORIDE,LEG PAIN,28-Jan-20,1,,1,1,1-Feb-20,2/1/20,,1,1,100,Capsule,CAPSULE,Capsule,Unknown,QD (Every Day),0,94095723,13,5084095,DIPHENHYDRAMINE HYDROCHLORIDE,DIPHENHYDRAMINE HYDROCHLORIDE,402001,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472438,3,N,3,3,Yes,TETRACYCLINE,FEVER,12-Feb-20,0,12:12,0,1,18-Feb-20,2/18/20,,0,0,10,mg,MG,Capsule,DE (Transdermal),BID (Twice a Day),1,84246445,6,4537684,TETRACYCLINE,TETRACYCLINE,1701001,TETRACYCLINE,1701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",ANTIBIOTICS,S01AA,ANTIBIOTICS,S01AA,ANTIINFECTIVES,S01A,OPHTHALMOLOGICALS,S01,SENSORY ORGANS,S,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472565,3,N,1,1,No,BENADRYL,COLD,10 UNK 2020,0,,0,0,20 UNK 2020,6/15/20,,0,0,12,IU,IU,Lotion,IJ (Intra-articular), , ,84734661,12,4567194,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472563,1,N,2,2,No,SOMINEX,COLD,,1,,1,0,,,,1,1,,mL,ML,Liquid,EP (Epidural),PRN (As Needed),0,82746644,5,4580551,SOMINEX (UNITED STATES),SOMINEX [DIPHENHYDRAMINE HYDROCHLORIDE],402060,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472564,2,N,3,3,No,ZQUILL,PAIN,,1,,1,0,17-Feb-20,2/17/20,,1,0,5,%,%,Aerosol,OP (Ophthalmic),Q2H (Every 2 Hours),0,99707553,22,5330876,ZZZQUIL,ZZZQUIL,402326,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,SPELLING UPDATE,ZZZQUIL,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 \ No newline at end of file +PATNUM,SUBJSTAT,SITENM,INSTANCE,INSTRN,FOLDER,FOLDERL,FOLDERSQ,FORM,FORML,DATAPGID,PGREPNUM,RECORDDT,RECORDID,RECPOS,RECSTAT,MDNUM,MDNUM_RAW,MDREC,MDRAW,MDIND,MDBDR,MDBDTU,MDBTM,MDBTMU,MDPRIOR,MDEDR,MDEDT,MDETM,MDETMU,MDONG,DOS,DOSU,DOSUV,MDFORM,MDRTE,MDFRQ,MDPROPH,TERMID,SRCLN,RAVRFID,MODIFY,CMDRG,CMDRGCD,CMDECOD,CMPNCD,SPLIT,OMIT,ACTTYP,ACTTEXT,CMDICT,CMCLAS,CMCLASCD,CMATC4,CMATC4CD,CMATC3,CMATC3CD,CMATC2,CMATC2CD,CMATC1,CMATC1CD,CLASSNUM +375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111885785,1,N,1,1,No,BABY ASPIRIN,,,1,,1,1,,,,0,1,10,mg,MG,Tablet,PO (Oral),QD (Every Day),0,109576058,20,5652739,BABY ASPIRIN,BABY ASPIRIN,2701701,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 +375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111969387,2,N,2,2,No,CORTISPORIN,NAUSEA,15-Sep-20,0,,1,0,,,,0,1,50,g,G,Pill,PO (Oral),,0,105820348,28,5533807,CORTISPORIN (UNITED STATES),CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03C,OPHTHALMOLOGICAL AND OTOLOGICAL PREPARATIONS,S03,SENSORY ORGANS,S,1 +376,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56407664,0,,111939965,1,N,1,1,No,ASPIRIN,ANEMIA,17-Feb-21,0,8:00,0,0,17-Feb-21,2/17/21,,0,0,,,,,,,0,80619660,8,4297014,ASPIRIN,ASPIRIN [ACETYLSALICYLIC ACID],2701004,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,111942855,1,N,1,1,No,DIPHENHYDRAMINE HCL,NAUSEA,4-Oct-20,0,9:00,0,0,,,,0,1,50,mg,MG,Capsule,PO (Oral),BID (Twice a Day),0,79751919,3,4240092,DIPHENHYDRAMINE HCL,DIPHENHYDRAMINE HCL,402246,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972536,2,N,2,2,No,PARCETEMOL,PYREXIA,20-Jan-20,0,10:00,0,0,20-Jan-20,1/20/20,10:00,0,0,,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,129972536,2,,,,,,,,,,,,,,,,,,,,,, +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972541,3,N,3,3,No,VOMIKIND,VOMITINGS,UN UNK 2019,1,,1,0,UN UNK 2019,6/15/19,,1,0,,Tablet,TABLET,,PO (Oral),PRN (As Needed),1,129972541,3,,,,,,,,,,,,,,,,,,,,,, +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972568,4,N,5,5,No,ZENFLOX OZ,DIARHHEA,20 UNK 2019,0,10:00,0,0,20 UNK 2019,6/15/19,,1,0,,mL,ML,Injection,IM (Intramuscular),PRN (As Needed),1,129972568,4,,,,,,,,,,,,,,,,,,,,,, +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472439,4,N,4,4,No,AMITRYPTYLINE,COLD,UN UNK 2020,0,,1,1,UN UNK 2020,6/15/20,,1,0,12,g,G,Inhalant,IA (Intra-arterial),QD (Every Day),0,81845879,6,4382628,AMITRIPTYLINE,AMITRIPTYLINE,2201001,AMITRIPTYLINE,2201001,,,SPELLING UPDATE,AMITRIPTYLINE,"WHODRUG GLOBAL B3 MARCH 1, 2021",DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,UROLOGICALS,G04B,UROLOGICALS,G04,GENITO URINARY SYSTEM AND SEX HORMONES,G,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472436,1,N,1,1,No,BENADRYL,FEVER,26-Jan-20,0,9:00,0,0,26-Jan-20,1/26/20,7:00,0,0,100,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,95547017,4,5211852,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472437,2,N,2,2,Yes,DIPHENHYDRAMINE HYDROCHLORIDE,LEG PAIN,28-Jan-20,1,,1,1,1-Feb-20,2/1/20,,1,1,100,Capsule,CAPSULE,Capsule,Unknown,QD (Every Day),0,94095723,13,5084095,DIPHENHYDRAMINE HYDROCHLORIDE,DIPHENHYDRAMINE HYDROCHLORIDE,402001,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472438,3,N,3,3,Yes,TETRACYCLINE,FEVER,12-Feb-20,0,12:12,0,1,18-Feb-20,2/18/20,,0,0,10,mg,MG,Capsule,DE (Transdermal),BID (Twice a Day),1,84246445,6,4537684,TETRACYCLINE,TETRACYCLINE,1701001,TETRACYCLINE,1701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",ANTIBIOTICS,S01AA,ANTIBIOTICS,S01AA,ANTIINFECTIVES,S01A,OPHTHALMOLOGICALS,S01,SENSORY ORGANS,S,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472565,3,N,1,1,No,BENADRYL,COLD,10 UNK 2020,0,,0,0,20 UNK 2020,6/15/20,,0,0,12,IU,IU,Lotion,IJ (Intra-articular), , ,84734661,12,4567194,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472563,1,N,2,2,No,SOMINEX,COLD,,1,,1,0,,,,1,1,,mL,ML,Liquid,EP (Epidural),PRN (As Needed),0,82746644,5,4580551,SOMINEX (UNITED STATES),SOMINEX [DIPHENHYDRAMINE HYDROCHLORIDE],402060,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472564,2,N,3,3,No,ZQUILL,PAIN,,1,,1,0,17-Feb-20,2/17/20,,1,0,5,%,%,Aerosol,OP (Ophthalmic),Q2H (Every 2 Hours),0,99707553,22,5330876,ZZZQUIL,ZZZQUIL,402326,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,SPELLING UPDATE,ZZZQUIL,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 From c8479352941d030fd17cd710dac85680e182e745 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Fri, 14 Jun 2024 06:19:58 +0000 Subject: [PATCH 14/23] DM domain csv --- inst/cm_domain/dm.csv | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 inst/cm_domain/dm.csv diff --git a/inst/cm_domain/dm.csv b/inst/cm_domain/dm.csv new file mode 100644 index 00000000..5d58d228 --- /dev/null +++ b/inst/cm_domain/dm.csv @@ -0,0 +1,6 @@ +"STUDYID","DOMAIN","USUBJID","SUBJID","RFSTDTC","RFENDTC","RFXSTDTC","RFXENDTC","RFICDTC","RFPENDTC","DTHDTC","DTHFL","SITEID","INVID","INVNAM","BRTHDTC","AGE","AGEU","SEX","RACE","ETHNIC","ARMCD","ARM","ACTARMCD","ACTARM","COUNTRY","DMDTC","DMDY","RACE1","RACE2","RACE3" +"test_study","DM","test_study-375","test_study-375","1999-04-14T08:36","2013-01-21","2023-04-14T08:36","2021-01-11T07:50","2007-01-15","2020-04-02","2020-04-02","Y","111111","90009","Dr doctor9",NA,NA,NA,"F","MULTIPLE",NA,NA,NA,NA,NA,"US",NA,NA,"NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER","WHITE",NA +"test_study","DM","test_study-376","test_study-376","2001-03-21","2007-05-21","2020-03-21","2017-09-14T18:49",NA,"2011-12-18","2011-12-18",NA,"111111","90009","Dr doctor9","1981-02-26T18:07",42,"YEARS","M","MULTIPLE","NOT HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,"BLACK OR AFRICAN AMERICAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" +"test_study","DM","test_study-377","test_study-377","1999-03-14","2021-05-05","2020-03-14","2013-08-23T12:37","2015-10-07","2021-05-05","2019-06-29",NA,"111111","90009","Dr doctor9","1968-03-19T04:36",56,"YEARS",NA,"MULTIPLE","NOT REPORTED",NA,NA,NA,NA,"US",NA,NA,"ASIAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" +"test_study","DM","test_study-378","test_study-378","2003-02-06T06:33","2021-04-24T09:06","2021-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11",NA,"111111","90009","Dr doctor9","1979-09-24",45,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA +"test_study","DM","test_study-379","test_study-379","2003-02-06T06:33","2021-04-24T09:06","2022-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11","Y","111111","90009","Dr doctor9","1963-09-24",61,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA From 503c145248b688ec55a0a13b55b9d7d180fb5587 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Fri, 14 Jun 2024 06:20:42 +0000 Subject: [PATCH 15/23] Events domain article --- vignettes/articles/cm_raw_data.csv | 15 + vignettes/articles/cm_sdtm_oak_ct.csv | 34 ++ vignettes/articles/dm.csv | 6 + vignettes/articles/events_domain.Rmd | 556 ++++++++++++++++++++++++++ 4 files changed, 611 insertions(+) create mode 100644 vignettes/articles/cm_raw_data.csv create mode 100644 vignettes/articles/cm_sdtm_oak_ct.csv create mode 100644 vignettes/articles/dm.csv create mode 100644 vignettes/articles/events_domain.Rmd diff --git a/vignettes/articles/cm_raw_data.csv b/vignettes/articles/cm_raw_data.csv new file mode 100644 index 00000000..10390854 --- /dev/null +++ b/vignettes/articles/cm_raw_data.csv @@ -0,0 +1,15 @@ +PATNUM,SUBJSTAT,SITENM,INSTANCE,INSTRN,FOLDER,FOLDERL,FOLDERSQ,FORM,FORML,DATAPGID,PGREPNUM,RECORDDT,RECORDID,RECPOS,RECSTAT,MDNUM,MDNUM_RAW,MDREC,MDRAW,MDIND,MDBDR,MDBDTU,MDBTM,MDBTMU,MDPRIOR,MDEDR,MDEDT,MDETM,MDETMU,MDONG,DOS,DOSU,DOSUV,MDFORM,MDRTE,MDFRQ,MDPROPH,TERMID,SRCLN,RAVRFID,MODIFY,CMDRG,CMDRGCD,CMDECOD,CMPNCD,SPLIT,OMIT,ACTTYP,ACTTEXT,CMDICT,CMCLAS,CMCLASCD,CMATC4,CMATC4CD,CMATC3,CMATC3CD,CMATC2,CMATC2CD,CMATC1,CMATC1CD,CLASSNUM +375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111885785,1,N,1,1,No,BABY ASPIRIN,,,1,,1,1,,,,0,1,10,mg,MG,Tablet,PO (Oral),QD (Every Day),0,109576058,20,5652739,BABY ASPIRIN,BABY ASPIRIN,2701701,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 +375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111969387,2,N,2,2,No,CORTISPORIN,NAUSEA,15-Sep-20,0,,1,0,,,,0,1,50,g,G,Pill,PO (Oral),,0,105820348,28,5533807,CORTISPORIN (UNITED STATES),CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03C,OPHTHALMOLOGICAL AND OTOLOGICAL PREPARATIONS,S03,SENSORY ORGANS,S,1 +376,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56407664,0,,111939965,1,N,1,1,No,ASPIRIN,ANEMIA,17-Feb-21,0,8:00,0,0,17-Feb-21,2/17/21,,0,0,,,,,,,0,80619660,8,4297014,ASPIRIN,ASPIRIN [ACETYLSALICYLIC ACID],2701004,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,111942855,1,N,1,1,No,DIPHENHYDRAMINE HCL,NAUSEA,4-Oct-20,0,9:00,0,0,,,,0,1,50,mg,MG,Capsule,PO (Oral),BID (Twice a Day),0,79751919,3,4240092,DIPHENHYDRAMINE HCL,DIPHENHYDRAMINE HCL,402246,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972536,2,N,2,2,No,PARCETEMOL,PYREXIA,20-Jan-20,0,10:00,0,0,20-Jan-20,1/20/20,10:00,0,0,,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,129972536,2,,,,,,,,,,,,,,,,,,,,,, +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972541,3,N,3,3,No,VOMIKIND,VOMITINGS,UN UNK 2019,1,,1,0,UN UNK 2019,6/15/19,,1,0,,Tablet,TABLET,,PO (Oral),PRN (As Needed),1,129972541,3,,,,,,,,,,,,,,,,,,,,,, +377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972568,4,N,5,5,No,ZENFLOX OZ,DIARHHEA,20 UNK 2019,0,10:00,0,0,20 UNK 2019,6/15/19,,1,0,,mL,ML,Injection,IM (Intramuscular),PRN (As Needed),1,129972568,4,,,,,,,,,,,,,,,,,,,,,, +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472439,4,N,4,4,No,AMITRYPTYLINE,COLD,UN UNK 2020,0,,1,1,UN UNK 2020,6/15/20,,1,0,12,g,G,Inhalant,IA (Intra-arterial),QD (Every Day),0,81845879,6,4382628,AMITRIPTYLINE,AMITRIPTYLINE,2201001,AMITRIPTYLINE,2201001,,,SPELLING UPDATE,AMITRIPTYLINE,"WHODRUG GLOBAL B3 MARCH 1, 2021",DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,UROLOGICALS,G04B,UROLOGICALS,G04,GENITO URINARY SYSTEM AND SEX HORMONES,G,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472436,1,N,1,1,No,BENADRYL,FEVER,26-Jan-20,0,9:00,0,0,26-Jan-20,1/26/20,7:00,0,0,100,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,95547017,4,5211852,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472437,2,N,2,2,Yes,DIPHENHYDRAMINE HYDROCHLORIDE,LEG PAIN,28-Jan-20,1,,1,1,1-Feb-20,2/1/20,,1,1,100,Capsule,CAPSULE,Capsule,Unknown,QD (Every Day),0,94095723,13,5084095,DIPHENHYDRAMINE HYDROCHLORIDE,DIPHENHYDRAMINE HYDROCHLORIDE,402001,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472438,3,N,3,3,Yes,TETRACYCLINE,FEVER,12-Feb-20,0,12:12,0,1,18-Feb-20,2/18/20,,0,0,10,mg,MG,Capsule,DE (Transdermal),BID (Twice a Day),1,84246445,6,4537684,TETRACYCLINE,TETRACYCLINE,1701001,TETRACYCLINE,1701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",ANTIBIOTICS,S01AA,ANTIBIOTICS,S01AA,ANTIINFECTIVES,S01A,OPHTHALMOLOGICALS,S01,SENSORY ORGANS,S,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472565,3,N,1,1,No,BENADRYL,COLD,10 UNK 2020,0,,0,0,20 UNK 2020,6/15/20,,0,0,12,IU,IU,Lotion,IJ (Intra-articular), , ,84734661,12,4567194,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472563,1,N,2,2,No,SOMINEX,COLD,,1,,1,0,,,,1,1,,mL,ML,Liquid,EP (Epidural),PRN (As Needed),0,82746644,5,4580551,SOMINEX (UNITED STATES),SOMINEX [DIPHENHYDRAMINE HYDROCHLORIDE],402060,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 +379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472564,2,N,3,3,No,ZQUILL,PAIN,,1,,1,0,17-Feb-20,2/17/20,,1,0,5,%,%,Aerosol,OP (Ophthalmic),Q2H (Every 2 Hours),0,99707553,22,5330876,ZZZQUIL,ZZZQUIL,402326,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,SPELLING UPDATE,ZZZQUIL,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 diff --git a/vignettes/articles/cm_sdtm_oak_ct.csv b/vignettes/articles/cm_sdtm_oak_ct.csv new file mode 100644 index 00000000..ffbe0903 --- /dev/null +++ b/vignettes/articles/cm_sdtm_oak_ct.csv @@ -0,0 +1,34 @@ +codelist_code,term_code,CodedData,term_value,collected_value,term_preferred_term,term_synonyms,raw_codelist +C71113,C25473,QD,QD,QD (Every Day),Daily,/day; Daily; Per Day,FREQ_CV1 +C71113,C64496,BID,BID,BID (Twice a Day),Twice Daily,BD; Twice per day,FREQ_CV1 +C71113,C64499,PRN,PRN,PRN (As Needed),As Needed,As needed,FREQ_CV1 +C71113,C64516,Q2H,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours,FREQ_CV1 +C71113,C64530,QID,QID,QID (4 Times a Day),Four Times Daily,4 times per day,FREQ_CV1 +C66726,C25158,CAPSULE,CAPSULE,Capsule,Capsule Dosage Form,cap,FRM_CV1 +C66726,C25394,PILL,PILL,Pill,Pill Dosage Form,NA,FRM_CV1 +C66726,C29167,LOTION,LOTION,Lotion,Lotion Dosage Form,NA,FRM_CV1 +C66726,C42887,AEROSOL,AEROSOL,Aerosol,Aerosol Dosage Form,aer,FRM_CV1 +C66726,C42944,INHALANT,INHALANT,Inhalant,Inhalant Dosage Form,NA,FRM_CV1 +C66726,C42946,INJECTION,INJECTION,Injection,Injectable Dosage Form,NA,FRM_CV1 +C66726,C42953,LIQUID,LIQUID,Liquid,Liquid Dosage Form,NA,FRM_CV1 +C66726,C42998,TABLET,TABLET,Tablet,Tablet Dosage Form,tab,FRM_CV1 +C66742,C49488,Y,Y,Yes,Yes,Yes,NY_CV1 +C66729,C28161,INTRAMUSCULAR,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration,NA,ROUTE_CV1 +C66729,C38210,EPIDURAL,EPIDURAL,EP (Epidural),Epidural Route of Administration,NA,ROUTE_CV1 +C66729,C38222,INTRA-ARTERIAL,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration,NA,ROUTE_CV1 +C66729,C38223,INTRA-ARTICULAR,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration,NA,ROUTE_CV1 +C66729,C38287,OPHTHALMIC,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration,NA,ROUTE_CV1 +C66729,C38288,ORAL,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO,ROUTE_CV1 +C66729,C38305,TRANSDERMAL,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration,NA,ROUTE_CV1 +C66729,C38311,UNKNOWN,UNKNOWN,Unknown,Unknown Route of Administration,NA,ROUTE_CV1 +C71620,C25613,%,%,%,Percentage,Percentage,UNIT_CV1 +C71620,C28253,MG,mg,mg,Milligram,Milligram,UNIT_CV1 +C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV1 +C71620,C48155,G,g,g,Gram,Gram,UNIT_CV1 +C71620,C48480,CAPSULE,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit,UNIT_CV1 +C71620,C48542,TABLET,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit,UNIT_CV1 +C71620,C48579,IU,IU,IU,International Unit,IE; International Unit,UNIT_CV1 +C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV5 +C66728,C25629,BEFORE,BEFORE,Prior,Prior,,NA +C66728,C53279,ONGOING,ONGOING,Continue,Continue,Continuous,NA +C66734,C49568,CM,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications,NA diff --git a/vignettes/articles/dm.csv b/vignettes/articles/dm.csv new file mode 100644 index 00000000..5d58d228 --- /dev/null +++ b/vignettes/articles/dm.csv @@ -0,0 +1,6 @@ +"STUDYID","DOMAIN","USUBJID","SUBJID","RFSTDTC","RFENDTC","RFXSTDTC","RFXENDTC","RFICDTC","RFPENDTC","DTHDTC","DTHFL","SITEID","INVID","INVNAM","BRTHDTC","AGE","AGEU","SEX","RACE","ETHNIC","ARMCD","ARM","ACTARMCD","ACTARM","COUNTRY","DMDTC","DMDY","RACE1","RACE2","RACE3" +"test_study","DM","test_study-375","test_study-375","1999-04-14T08:36","2013-01-21","2023-04-14T08:36","2021-01-11T07:50","2007-01-15","2020-04-02","2020-04-02","Y","111111","90009","Dr doctor9",NA,NA,NA,"F","MULTIPLE",NA,NA,NA,NA,NA,"US",NA,NA,"NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER","WHITE",NA +"test_study","DM","test_study-376","test_study-376","2001-03-21","2007-05-21","2020-03-21","2017-09-14T18:49",NA,"2011-12-18","2011-12-18",NA,"111111","90009","Dr doctor9","1981-02-26T18:07",42,"YEARS","M","MULTIPLE","NOT HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,"BLACK OR AFRICAN AMERICAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" +"test_study","DM","test_study-377","test_study-377","1999-03-14","2021-05-05","2020-03-14","2013-08-23T12:37","2015-10-07","2021-05-05","2019-06-29",NA,"111111","90009","Dr doctor9","1968-03-19T04:36",56,"YEARS",NA,"MULTIPLE","NOT REPORTED",NA,NA,NA,NA,"US",NA,NA,"ASIAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" +"test_study","DM","test_study-378","test_study-378","2003-02-06T06:33","2021-04-24T09:06","2021-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11",NA,"111111","90009","Dr doctor9","1979-09-24",45,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA +"test_study","DM","test_study-379","test_study-379","2003-02-06T06:33","2021-04-24T09:06","2022-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11","Y","111111","90009","Dr doctor9","1963-09-24",61,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA diff --git a/vignettes/articles/events_domain.Rmd b/vignettes/articles/events_domain.Rmd new file mode 100644 index 00000000..4b89e3b3 --- /dev/null +++ b/vignettes/articles/events_domain.Rmd @@ -0,0 +1,556 @@ +--- +title: "Creating an Events SDTM domain" +output: + rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Creating an Events SDTM domain} + %\VignetteEncoding{UTF-8} + %\VignetteEngine{knitr::rmarkdown} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) + +#library(sdtm.oak) +library(admiraldev) +library(rlang) +library(dplyr, warn.conflicts = FALSE) +``` + +```{r, include=FALSE} +devtools::load_all(".") +``` +# Introduction + +This article describes creating an Events SDTM domain using the `sdtm.oak` package. Examples are currently presented and tested in the context of the CM domain. + +# Raw data + +Raw datasets can be exported from the EDC systems in the format they are collected. The example used provides a raw dataset for Concomitant medications, where the collected data is represented as columns for each subject. For example, the Medication Name(MDRAW), Medication Start Date (MDBDR), Start Time (MDBTM), End Date (MDEDR), End time (MDETM), etc. are represented as columns.This format is commonly used in most EDC systems. + +The raw dataset is presented below: + +```{r eval=TRUE} +cm_raw <- as_tibble(read.csv("cm_raw_data.csv", stringsAsFactors = FALSE)) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm_raw, + display_vars = exprs( + PATNUM, FORML, MDNUM, MDRAW, MDIND, MDBDR, MDBTM, MDPRIOR, MDEDR, + MDETM, MDONG, DOS, DOSU, MDFORM, MDRTE, MDFRQ, MDPROPH + ) +) +``` + +# Programming workflow + +In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (example Concomitant medications (OID - cm_raw), Targeted Concomitant Medications (OID - cm_t_raw)) can be stacked together before processing. + +* [Read in data](#readdata) +* [Create oak_id_vars](#oakidvars) +* [Read in CT](#readct) +* [Map Topic Variable](#maptopic) +* [Map Qualifies, Identifiers, and Timing Variables](#mapqualifiers) + +Repeat the above steps for different raw datasets before proceeding with the below steps. + +* [Create SDTM derived variables](#derivedvars) +* [Add Labels and Attributes](#attributes) + +## Read in data {#readdata} + +Read all the raw datasets into the environment. In this example, the raw dataset name is `cm_raw`. Users can read it from the package using the below code: + +```{r eval=FALSE} +cm_raw <- read.csv(system.file("cm_domain/cm_raw_data.csv", + package = "sdtm.oak")) + +dm <- read.csv(system.file("cm_domain/dm.csv", + package = "sdtm.oak")) +``` + +## Create oak_id_vars {#oakidvars} + +The `oak_id_vars` is a crucial link between the raw datasets and the mapped SDTM domain. As the user derives each SDTM variable, it is merged with the corresponding topic variable using `oak_id_vars`. In {sdtm.oak}, the variables oak_id, raw_source, and patient_number are considered as `oak_id_vars`. These three variables must be added to all raw datasets. They are used in multiple places in the programming. + +oak_id:- Type: numeric- Value: equal to the raw dataframe row number. + +raw_source:- Type: Character- Value: equal to the raw dataset (eCRF) name or eDT dataset name. + +patient_number:- Type: numeric- Value: equal to the subject number in CRF or NonCRF data source. + +```{r eval=TRUE} +cm_raw <- cm_raw %>% + generate_oak_id_vars(pat_var = "PATNUM", + raw_src = "cm_raw") +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm_raw, + display_vars = exprs( + oak_id, raw_source, patient_number, PATNUM, FORML, MDNUM, MDRAW + ) +) +``` + +Reead in the DM domain + +```{r eval=TRUE} +dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) +``` + + +## Read in CT {#readct} + +Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `cm_sdtm_oak_ct.csv`. Users can read it from the package using the below code: + +```{r eval=FALSE} +study_ct <- read.csv(system.file("cm_domain/cm_sdtm_oak_ct.csv", + package = "sdtm.oak")) +``` + +```{r eval=TRUE} +study_ct <- as_tibble(read.csv("cm_sdtm_oak_ct.csv", stringsAsFactors = FALSE)) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + study_ct, + display_vars = exprs( + codelist_code, term_code, term_value, collected_value, term_preferred_term, + term_synonyms + ) +) +``` + +## Map Topic Variable {#maptopic} + +The topic variable is mapped as a first step in the mapping process. It is the primary variable in the SDTM domain. The rest of the variables add further definition to the topic variable. In this example, the topic variable is `CMTRT`. It is mapped from the raw dataset column `MDRAW`. The mapping logic is `Map the collected value in the cm_raw dataset MDRAW variable to CM.CMTRT`. + +This mapping does not involve any controlled terminology. The `assign_no_ct` function is used for mapping. Once the topic variable is mapped, the Qualifier, Identifier, and Timing variables can be mapped. + +```{r eval=TRUE} +cm <- + # Map topic variable + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MDRAW", + tgt_var = "CMTRT" + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT + ) +) +``` +## Map Qualifiers, Identifiers, and Timing Variables {#mapqualifiers} + +The Qualifiers, Identifiers, and Timing Variables can be mapped in any order. In this example, we will map each variable one by one to demonstrate different mapping algorithms. + +### `assign_no_ct` + +The mapping logic for `CMGRPID` is `Map the collected value in the cm_raw dataset MDNUM variable to CM.CMGRPID`. + + +```{r eval=TRUE} +cm <- cm %>% + # Map CMGRPID + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MDNUM", + tgt_var = "CMGRPID", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID + ) +) +``` + +The CMGRPID is added to the corresponding CMTRT based on the 'oak_id_vars'. When calling the function, the parameter 'id_vars = oak_id_vars()' matches the raw dataset 'oak_id_vars' to the 'oak_id_vars' in the cm domain created in the previous step. It's important to note that the 'oak_id_vars' can be extended to include user-defined variables. But in most cases, the three variables should suffice. + +### `assign_ct` + +The mapping logic for `CMDOSU` is `Map the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU`. The controlled terminology is used to map the collected value to the standard value. `assign_ct` is the right algorithm to perform this mapping. + +```{r eval=TRUE} +cm <- cm %>% + # Map qualifier CMDOSU + assign_ct( + raw_dat = cm_raw, + raw_var = "DOSU", + tgt_var = "CMDOSU", + ct_spec = study_ct, + ct_clst = "C71620", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU + ) +) +``` + +### `assign_datetime` + +The mapping logic for `CMSTDTC` is `Map the collected value in the cm_raw dataset MDBDR (start date) variable and MDBTM (start time) to CM.CMSTDTC`. The collected date value is in the format 'dd mmm yyyy'. The collected time value is in 'H"M' format. The `assign_datetime` function is used to map the collected value in ISO8601 format. + +```{r eval=TRUE} +cm <- cm %>% +# Map CMSTDTC. This function calls create_iso8601 + assign_datetime( + raw_dat = cm_raw, + raw_var = c("MDBDR", "MDBTM"), + tgt_var = "CMSTDTC", + raw_fmt = c(list(c("d-m-y", "dd mmm yyyy")), "H:M"), + raw_unk = c("UN", "UNK"), + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC + ) +) +``` + +### `hardcode_ct` and `condition_add` + +The mapping logic for `CMSTRTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTRTPT == 'BEFORE'.` The `hardcode_ct` function is used to map the CMSTRTPT as it involves hardcoding a specific value to an SDTM variable with controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_ct` function performs the mapping. + +When these two functions are used together, the `condition_add` function first filters the raw dataset based on the specified condition. Next, the filtered dataset is then passed to the `hardcode_ct` function to assign the appropriate value. This example illustrates how the `hardcode_ct` algorithm functions as a sub-algorithm to `condition_add`. + +```{r eval=TRUE} +cm <- cm %>% + # Map qualifier CMSTRTPT Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE' + hardcode_ct( + raw_dat = condition_add(cm_raw, MDPRIOR == "1"), + raw_var = "MDPRIOR", + tgt_var = "CMSTRTPT", + tgt_val = "BEFORE", + ct_spec = study_ct, + ct_clst = "C66728", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT + ) +) +``` + +The `condition_add` function adds additional metadata to the records in the raw dataset that meets the condition. Refer to the function documentation for more details. `hardcode_ct` function uses the addtional metadata to find the records that meet the criteria and map them accordingly. + +## hardcode_no_ct and condition_add + +The mapping logic for `CMSTTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTTPT == 'SCREENING'.` The `hardcode_no_ct` function is used to map the CMSTTPT as it involves hardcoding a specific value to an SDTM variable without controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_no_ct` function performs the mapping. + +```{r eval=TRUE} +cm <- cm %>% + # Map qualifier CMSTTPT Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING' + hardcode_no_ct( + raw_dat = condition_add(cm_raw, MDPRIOR == "1"), + raw_var = "MDPRIOR", + tgt_var = "CMSTTPT", + tgt_val = "SCREENING", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT + ) +) +``` + +### condition_add involving target domain + +In the mapping for `CMSTRTPT` and `CMSTTTPT`, the `condition_add` function is used in the raw dataset. In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. + +The mapping logic for `CMDOSFRQ` is `If CMTRT is not null, then map the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ.` This may or may not represent a valid SDTM mapping in an actual study, but it can be used as an example. + +In this mapping, the `condition_add` function filters the cm domain created in the previous step and adds metadata to the records where it meets the condition. The `assign_ct` function uses the additional metadata to find the records that meet the criteria and map them accordingly. + +```{r eval=TRUE} +cm <- cm %>% + # Map qualifier CMDOSFRQ Annotation text is If CMTRT is not null then map the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ + {assign_ct( + raw_dat = cm_raw, + raw_var = "MDFRQ", + tgt_dat = condition_add(. , !is.na(CMTRT)), + tgt_var = "CMDOSFRQ", + ct_spec = study_ct, + ct_clst = "C66728", + id_vars = oak_id_vars() + )} +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ + ) +) +``` + +Remember to use additional curly braces in the function call when using the `condition_add` function on the target dataset. This is necessary because the input target dataset is represented as a `.` and is passed on from the previous step using the {magrittr} pipe operator. Currently, there is a limitation when using a nested function call with `.` to reference one of the input parameters, and this [recommended approach](https://magrittr.tidyverse.org/reference/pipe.html#using-the-dot-for-secondary-purposes) will overcome that. + +The placeholder `.` is for use with {magrittr} pipe `%>%` operator. We encourage using `.` and {magrittr} pipe `%>%` operator when using {sdtm.oak} functions. + +Another way to achieve the same outcome is by moving the 'condition_by' call up one level, as illustrated below: it is not required to use the {magrittr} pipe `%>%` or curly braces in this case. + +```{r eval=FALSE} +cm <- cm %>% + condition_add(!is.na(CMTRT)) %>% + assign_ct( + raw_dat = cm_raw, + raw_var = "DOSU", + tgt_var = "CMDOSU", + ct_spec = study_ct, + ct_clst = "C71620", + id_vars = oak_id_vars() + ) +``` + +### condition_add involving raw dataset and target domain + +In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. + +The mapping logic for `CMMODIFY` is `If collected value in MODIFY in cm_raw is different to CM.CMTRT then assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY)`. The `assign_no_ct` function is used to map the CMMODIFY as it involves mapping the collected value to the SDTM variable without controlled terminology. The `condition_add` function filters the raw dataset & target dataset based on a particular condition, and the `assign_no_ct` function performs the mapping. + +```{r eval=TRUE} +cm <- cm %>% + # Map CMMODIFY Annotation text If collected value in MODIFY in cm_raw is different to CM.CMTRT then assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY) + {assign_no_ct( + raw_dat = cm_raw, + raw_var = "MODIFY", + tgt_dat = condition_add(. , MODIFY != CMTRT, .dat2 = cm_raw), + tgt_var = "CMMODIFY", + id_vars = oak_id_vars() + )} +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY + ) +) +``` + +Another way to achieve the same outcome is by moving the 'condition_by' call up one level, as illustrated below: it is not required to use the {magrittr} pipe `%>%` or curly braces in this case. + +```{r eval=FALSE} +cm <- cm %>% + condition_add(MODIFY != CMTRT, .dat2 = cm_raw) %>% + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MODIFY", + tgt_var = "CMMODIFY", + id_vars = oak_id_vars() + ) +``` + +### Map rest of the variables + +```{r eval=TRUE} +cm <- cm %>% + # Map CMINDC as the collected value in MDIND to CM.CMINDC + assign_no_ct( + raw_dat = cm_raw, + raw_var = "MDIND", + tgt_var = "CMINDC", + id_vars = oak_id_vars() + ) %>% + # Map CMENDTC as the collected value in MDEDR and MDETM to CM.CMENDTC. + # This function calls create_iso8601 + assign_datetime( + raw_dat = cm_raw, + raw_var = c("MDEDR", "MDETM"), + tgt_var = "CMENDTC", + raw_fmt = c("d-m-y", "H:M"), + raw_unk = c("UN", "UNK") + ) %>% + # Map qualifier CMENRTPT as If MDONG == 1 then CM.CMENRTPT = 'ONGOING' + hardcode_ct( + raw_dat = condition_add(cm_raw, MDONG == "1"), + raw_var = "MDONG", + tgt_var = "CMENRTPT", + tgt_val = "ONGOING", + ct_spec = study_ct, + ct_clst = "C66728", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMENTPT as If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' + hardcode_no_ct( + raw_dat = condition_add(cm_raw, MDONG == "1"), + raw_var = "MDONG", + tgt_var = "CMENTPT", + tgt_val = "DATE OF LAST ASSESSMENT", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMDOS as If collected value in raw_var DOS is numeric then CM.CMDOSE + assign_no_ct( + raw_dat = condition_add(cm_raw, is.numeric(DOS)), + raw_var = "DOS", + tgt_var = "CMDOS", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMDOS as If collected value in raw_var DOS is character then CM.CMDOSTXT + assign_no_ct( + raw_dat = condition_add(cm_raw, is.character(DOS)), + raw_var = "DOS", + tgt_var = "CMDOSTXT", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMDOSU as the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU + assign_ct( + raw_dat = cm_raw, + raw_var = "DOSU", + tgt_var = "CMDOSU", + ct_spec = study_ct, + ct_clst = "C71620", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMDOSFRM as the collected value in the cm_raw dataset MDFORM variable to CM.CMDOSFRM + assign_ct( + raw_dat = cm_raw, + raw_var = "MDFORM", + tgt_var = "CMDOSFRM", + ct_spec = study_ct, + ct_clst = "C66726", + id_vars = oak_id_vars() + ) %>% + # Map CMROUTE as the collected value in the cm_raw dataset MDRTE variable to CM.CMROUTE + assign_ct( + raw_dat = cm_raw, + raw_var = "MDRTE", + tgt_var = "CMROUTE", + ct_spec = study_ct, + ct_clst = "C66729", + id_vars = oak_id_vars() + ) %>% + # Map qualifier CMPROPH as If MDPROPH == 1 then CM.CMPROPH = 'Y' + hardcode_ct( + raw_dat = condition_add(cm_raw, MDPROPH == "1"), + raw_var = "MDPROPH", + tgt_var = "CMPROPH", + tgt_val = "Y", + ct_spec = study_ct, + ct_clst = "C66742", + id_vars = oak_id_vars() + ) %>% + # Map CMDRG as the collected value in the cm_raw dataset CMDRG variable to CM.CMDRG + assign_no_ct( + raw_dat = cm_raw, + raw_var = "CMDRG", + tgt_var = "CMDRG", + id_vars = oak_id_vars() + ) %>% + # Map CMDRGCD as the collected value in the cm_raw dataset CMDRGCD variable to CM.CMDRGCD + assign_no_ct( + raw_dat = cm_raw, + raw_var = "CMDRGCD", + tgt_var = "CMDRGCD", + id_vars = oak_id_vars() + ) %>% + # Map CMDECOD as the collected value in the cm_raw dataset CMDECOD variable to CM.CMDECOD + assign_no_ct( + raw_dat = cm_raw, + raw_var = "CMDECOD", + tgt_var = "CMDECOD", + id_vars = oak_id_vars() + ) %>% + # Map CMPNCD as the collected value in the cm_raw dataset CMPNCD variable to CM.CMPNCD + assign_no_ct( + raw_dat = cm_raw, + raw_var = "CMPNCD", + tgt_var = "CMPNCD", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY, CMINDC, CMENDTC, CMENRTPT, CMENTPT, CMDOS, CMDOSTXT, CMDOSU, CMDOSFRM, CMROUTE, CMPROPH, CMDRG, CMDRGCD, CMDECOD, CMPNCD + ) +) +``` + +## Create SDTM derived variables {#derivedvars} + +The SDTM derived variables or any SDTM mapping that is applicable to all the records in the `cm` dataset produced in the previous step cam be created now. In this example, we will create the `CMSEQ` variable. The mapping logic is `Create a sequence number for each record in the CM domain`. + +```{r eval=TRUE} + cm <- cm %>% + # The below mappings are applicable to all the records in the cm domain, + # hence can be derived using mutate statement. + dplyr::mutate( + STUDYID = "test_study", + DOMAIN = "CM", + CMCAT = "GENERAL CONMED", + USUBJID = paste0("test_study", "-", cm_raw$PATNUM) + ) %>% + # derive sequence number + # derive_seq(tgt_var = "CMSEQ", + # rec_vars= c("USUBJID", "CMGRPID")) %>% + derive_study_day( + sdtm_in = ., + dm_domain = dm, + tgdt = "CMENDTC", + refdt = "RFXSTDTC", + study_day_var = "CMENDY" + ) %>% + derive_study_day( + sdtm_in = ., + dm_domain = dm, + tgdt = "CMSTDTC", + refdt = "RFXSTDTC", + study_day_var = "CMSTDY" + ) %>% + # Add code for derive Baseline flag. + dplyr::select("STUDYID", "DOMAIN" , "USUBJID", everything()) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + cm, + display_vars = exprs( + oak_id, raw_source, patient_number, STUDYID, DOMAIN, USUBJID, CMGRPID, CMTRT, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY, CMINDC, CMENDTC, CMENRTPT, CMENTPT, CMDOS, CMDOSTXT, CMDOSU, CMDOSFRM, CMROUTE, CMPROPH, CMDRG, CMDRGCD, CMDECOD, CMPNCD, CMSTDY, CMENDY + ) +) +``` + From 2b134f6b7ce1a15464c4b872cf3c256874d08d5b Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Sat, 15 Jun 2024 00:23:29 +0000 Subject: [PATCH 16/23] update controlled terminology --- inst/cm_domain/cm_sdtm_oak_ct.csv | 34 ------------ inst/cm_domain/sdtm_ct.csv | 75 +++++++++++++++++++++++++++ vignettes/articles/cm_sdtm_oak_ct.csv | 34 ------------ vignettes/articles/sdtm_ct.csv | 75 +++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 68 deletions(-) delete mode 100644 inst/cm_domain/cm_sdtm_oak_ct.csv create mode 100644 inst/cm_domain/sdtm_ct.csv delete mode 100644 vignettes/articles/cm_sdtm_oak_ct.csv create mode 100644 vignettes/articles/sdtm_ct.csv diff --git a/inst/cm_domain/cm_sdtm_oak_ct.csv b/inst/cm_domain/cm_sdtm_oak_ct.csv deleted file mode 100644 index ffbe0903..00000000 --- a/inst/cm_domain/cm_sdtm_oak_ct.csv +++ /dev/null @@ -1,34 +0,0 @@ -codelist_code,term_code,CodedData,term_value,collected_value,term_preferred_term,term_synonyms,raw_codelist -C71113,C25473,QD,QD,QD (Every Day),Daily,/day; Daily; Per Day,FREQ_CV1 -C71113,C64496,BID,BID,BID (Twice a Day),Twice Daily,BD; Twice per day,FREQ_CV1 -C71113,C64499,PRN,PRN,PRN (As Needed),As Needed,As needed,FREQ_CV1 -C71113,C64516,Q2H,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours,FREQ_CV1 -C71113,C64530,QID,QID,QID (4 Times a Day),Four Times Daily,4 times per day,FREQ_CV1 -C66726,C25158,CAPSULE,CAPSULE,Capsule,Capsule Dosage Form,cap,FRM_CV1 -C66726,C25394,PILL,PILL,Pill,Pill Dosage Form,NA,FRM_CV1 -C66726,C29167,LOTION,LOTION,Lotion,Lotion Dosage Form,NA,FRM_CV1 -C66726,C42887,AEROSOL,AEROSOL,Aerosol,Aerosol Dosage Form,aer,FRM_CV1 -C66726,C42944,INHALANT,INHALANT,Inhalant,Inhalant Dosage Form,NA,FRM_CV1 -C66726,C42946,INJECTION,INJECTION,Injection,Injectable Dosage Form,NA,FRM_CV1 -C66726,C42953,LIQUID,LIQUID,Liquid,Liquid Dosage Form,NA,FRM_CV1 -C66726,C42998,TABLET,TABLET,Tablet,Tablet Dosage Form,tab,FRM_CV1 -C66742,C49488,Y,Y,Yes,Yes,Yes,NY_CV1 -C66729,C28161,INTRAMUSCULAR,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration,NA,ROUTE_CV1 -C66729,C38210,EPIDURAL,EPIDURAL,EP (Epidural),Epidural Route of Administration,NA,ROUTE_CV1 -C66729,C38222,INTRA-ARTERIAL,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration,NA,ROUTE_CV1 -C66729,C38223,INTRA-ARTICULAR,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration,NA,ROUTE_CV1 -C66729,C38287,OPHTHALMIC,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration,NA,ROUTE_CV1 -C66729,C38288,ORAL,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO,ROUTE_CV1 -C66729,C38305,TRANSDERMAL,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration,NA,ROUTE_CV1 -C66729,C38311,UNKNOWN,UNKNOWN,Unknown,Unknown Route of Administration,NA,ROUTE_CV1 -C71620,C25613,%,%,%,Percentage,Percentage,UNIT_CV1 -C71620,C28253,MG,mg,mg,Milligram,Milligram,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV1 -C71620,C48155,G,g,g,Gram,Gram,UNIT_CV1 -C71620,C48480,CAPSULE,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit,UNIT_CV1 -C71620,C48542,TABLET,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit,UNIT_CV1 -C71620,C48579,IU,IU,IU,International Unit,IE; International Unit,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV5 -C66728,C25629,BEFORE,BEFORE,Prior,Prior,,NA -C66728,C53279,ONGOING,ONGOING,Continue,Continue,Continuous,NA -C66734,C49568,CM,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications,NA diff --git a/inst/cm_domain/sdtm_ct.csv b/inst/cm_domain/sdtm_ct.csv new file mode 100644 index 00000000..d078d6ed --- /dev/null +++ b/inst/cm_domain/sdtm_ct.csv @@ -0,0 +1,75 @@ +codelist_code,term_code,term_value,collected_value,term_preferred_term,term_synonyms +C66726,C25158,CAPSULE,Capsule,Capsule Dosage Form,cap +C66726,C25394,PILL,Pill,Pill Dosage Form, +C66726,C29167,LOTION,Lotion,Lotion Dosage Form, +C66726,C42887,AEROSOL,Aerosol,Aerosol Dosage Form,aer +C66726,C42944,INHALANT,Inhalant,Inhalant Dosage Form, +C66726,C42946,INJECTION,Injection,Injectable Dosage Form, +C66726,C42953,LIQUID,Liquid,Liquid Dosage Form, +C66726,C42998,TABLET,Tablet,Tablet Dosage Form,tab +C66728,C25629,BEFORE,Prior,Prior, +C66728,C53279,ONGOING,Continue,Continue,Continuous +C66729,C28161,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration, +C66729,C38210,EPIDURAL,EP (Epidural),Epidural Route of Administration, +C66729,C38222,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration, +C66729,C38223,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration, +C66729,C38287,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration, +C66729,C38288,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO +C66729,C38305,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration, +C66729,C38311,UNKNOWN,Unknown,Unknown Route of Administration, +C66734,C49568,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications +C66741,C174446,TEMP,Body Temperature,Body Temperature,Body Temperature; Temperature +C66741,C25298,SYSBP,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure +C66741,C25299,DIABP,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure +C66741,C49676,PULSE,Pulse Rate,Pulse Rate,Pulse Rate +C66741,C49678,RESP,Respiratory Rate,Respiratory Rate,Respiratory Rate +C66741,C60832,OXYSAT,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation +C66741,V00224,VSALL,VS Domain ALL Tests,VS Domain ALL Tests, +C66742,C49488,Y,Yes,Yes,Yes +C66770,C25613,%,Percentage,Percentage,Percentage +C66770,C42559,C,Degree Celsius,Degree Celsius,Degree Celsius +C66770,C49670,mmHg,Millimeter of Mercury,Millimeter of Mercury,Millimeter of Mercury +C66770,C49673,beats/min,Beats per Minute,Beats per Minute,Beats per Minute; BPM; bpm +C66770,C49674,breaths/min,Breaths per Minute,Breaths per Minute,Breaths per Minute +C66789,C49484,NOT DONE,Not Done,Not Done, +C67153,C174446,Temperature,Body Temperature,Body Temperature,Body Temperature; Temperature +C67153,C25298,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure +C67153,C25299,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure +C67153,C49676,Pulse Rate,Pulse Rate,Pulse Rate,Pulse Rate +C67153,C49678,Respiratory Rate,Respiratory Rate,Respiratory Rate,Respiratory Rate +C67153,C60832,Oxygen Saturation,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation +C67153,V00224,Vital Signs,VS Domain ALL Tests,VS Domain ALL Tests, +C71113,C25473,QD,QD (Every Day),Daily,/day; Daily; Per Day +C71113,C64496,BID,BID (Twice a Day),Twice Daily,BD; Twice per day +C71113,C64499,PRN,PRN (As Needed),As Needed,As needed +C71113,C64516,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours +C71113,C64530,QID,QID (4 Times a Day),Four Times Daily,4 times per day +C71148,C111310,SEMI-RECUMBENT,Semi-Supine,Semi-Supine,Semi-Supine +C71148,C62122,SITTING,Sitting,Sitting,Sitting +C71148,C62165,PRONE,Prone,Prone,Prone +C71148,C62166,STANDING,Standing,Standing,Orthostatic; Standing +C71148,C62167,SUPINE,Supine,Supine,Supine +C71620,C25613,%,%,Percentage,Percentage +C71620,C28253,mg,mg,Milligram,Milligram +C71620,C28254,mL,mL,Milliliter,cm3; Milliliter +C71620,C48155,g,g,Gram,Gram +C71620,C48480,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit +C71620,C48542,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit +C71620,C48579,IU,IU,International Unit,IE; International Unit +C74456,C12390,RECTUM,Rectum,Rectum, +C74456,C12421,ORAL CAVITY,Oral Cavity,Oral Cavity,Buccal cavity; Mouth +C74456,C12470,SKIN,Skin,Skin,Integument; Skin +C74456,C12502,TYMPANIC MEMBRANE,Tympanic Membrane,Tympanic Membrane,Tympanic Membrane +C74456,C12674,AXILLA,Axilla,Axilla,Armpit; Axilla +C74456,C32608,FINGER,FINGER,FINGER,Finger +C74456,C89803,FOREHEAD,Forehead,Forehead,Forehead +C99073,C25228,RIGHT,Right,Right, +C99073,C25229,LEFT,Left,Left, +TPT,TPT,PREDOSE,Pre-dose,, +TPT,TPT,POSTDOSE,Post-dose,, +TPTNUM,TPTNUM,1,Pre-dose,, +TPTNUM,TPTNUM,2,Post-dose,, +VISITNUM,VISITNUM,1,Screening,, +VISITNUM,VISITNUM,2,Visit 1,, +VISIT,VISIT,SCREENING,Screening,, +VISIT,VISIT,VISIT 1,Visit 1,, \ No newline at end of file diff --git a/vignettes/articles/cm_sdtm_oak_ct.csv b/vignettes/articles/cm_sdtm_oak_ct.csv deleted file mode 100644 index ffbe0903..00000000 --- a/vignettes/articles/cm_sdtm_oak_ct.csv +++ /dev/null @@ -1,34 +0,0 @@ -codelist_code,term_code,CodedData,term_value,collected_value,term_preferred_term,term_synonyms,raw_codelist -C71113,C25473,QD,QD,QD (Every Day),Daily,/day; Daily; Per Day,FREQ_CV1 -C71113,C64496,BID,BID,BID (Twice a Day),Twice Daily,BD; Twice per day,FREQ_CV1 -C71113,C64499,PRN,PRN,PRN (As Needed),As Needed,As needed,FREQ_CV1 -C71113,C64516,Q2H,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours,FREQ_CV1 -C71113,C64530,QID,QID,QID (4 Times a Day),Four Times Daily,4 times per day,FREQ_CV1 -C66726,C25158,CAPSULE,CAPSULE,Capsule,Capsule Dosage Form,cap,FRM_CV1 -C66726,C25394,PILL,PILL,Pill,Pill Dosage Form,NA,FRM_CV1 -C66726,C29167,LOTION,LOTION,Lotion,Lotion Dosage Form,NA,FRM_CV1 -C66726,C42887,AEROSOL,AEROSOL,Aerosol,Aerosol Dosage Form,aer,FRM_CV1 -C66726,C42944,INHALANT,INHALANT,Inhalant,Inhalant Dosage Form,NA,FRM_CV1 -C66726,C42946,INJECTION,INJECTION,Injection,Injectable Dosage Form,NA,FRM_CV1 -C66726,C42953,LIQUID,LIQUID,Liquid,Liquid Dosage Form,NA,FRM_CV1 -C66726,C42998,TABLET,TABLET,Tablet,Tablet Dosage Form,tab,FRM_CV1 -C66742,C49488,Y,Y,Yes,Yes,Yes,NY_CV1 -C66729,C28161,INTRAMUSCULAR,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration,NA,ROUTE_CV1 -C66729,C38210,EPIDURAL,EPIDURAL,EP (Epidural),Epidural Route of Administration,NA,ROUTE_CV1 -C66729,C38222,INTRA-ARTERIAL,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration,NA,ROUTE_CV1 -C66729,C38223,INTRA-ARTICULAR,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration,NA,ROUTE_CV1 -C66729,C38287,OPHTHALMIC,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration,NA,ROUTE_CV1 -C66729,C38288,ORAL,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO,ROUTE_CV1 -C66729,C38305,TRANSDERMAL,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration,NA,ROUTE_CV1 -C66729,C38311,UNKNOWN,UNKNOWN,Unknown,Unknown Route of Administration,NA,ROUTE_CV1 -C71620,C25613,%,%,%,Percentage,Percentage,UNIT_CV1 -C71620,C28253,MG,mg,mg,Milligram,Milligram,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV1 -C71620,C48155,G,g,g,Gram,Gram,UNIT_CV1 -C71620,C48480,CAPSULE,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit,UNIT_CV1 -C71620,C48542,TABLET,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit,UNIT_CV1 -C71620,C48579,IU,IU,IU,International Unit,IE; International Unit,UNIT_CV1 -C71620,C28254,ML,mL,mL,Milliliter,cm3; Milliliter,UNIT_CV5 -C66728,C25629,BEFORE,BEFORE,Prior,Prior,,NA -C66728,C53279,ONGOING,ONGOING,Continue,Continue,Continuous,NA -C66734,C49568,CM,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications,NA diff --git a/vignettes/articles/sdtm_ct.csv b/vignettes/articles/sdtm_ct.csv new file mode 100644 index 00000000..d078d6ed --- /dev/null +++ b/vignettes/articles/sdtm_ct.csv @@ -0,0 +1,75 @@ +codelist_code,term_code,term_value,collected_value,term_preferred_term,term_synonyms +C66726,C25158,CAPSULE,Capsule,Capsule Dosage Form,cap +C66726,C25394,PILL,Pill,Pill Dosage Form, +C66726,C29167,LOTION,Lotion,Lotion Dosage Form, +C66726,C42887,AEROSOL,Aerosol,Aerosol Dosage Form,aer +C66726,C42944,INHALANT,Inhalant,Inhalant Dosage Form, +C66726,C42946,INJECTION,Injection,Injectable Dosage Form, +C66726,C42953,LIQUID,Liquid,Liquid Dosage Form, +C66726,C42998,TABLET,Tablet,Tablet Dosage Form,tab +C66728,C25629,BEFORE,Prior,Prior, +C66728,C53279,ONGOING,Continue,Continue,Continuous +C66729,C28161,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration, +C66729,C38210,EPIDURAL,EP (Epidural),Epidural Route of Administration, +C66729,C38222,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration, +C66729,C38223,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration, +C66729,C38287,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration, +C66729,C38288,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO +C66729,C38305,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration, +C66729,C38311,UNKNOWN,Unknown,Unknown Route of Administration, +C66734,C49568,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications +C66741,C174446,TEMP,Body Temperature,Body Temperature,Body Temperature; Temperature +C66741,C25298,SYSBP,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure +C66741,C25299,DIABP,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure +C66741,C49676,PULSE,Pulse Rate,Pulse Rate,Pulse Rate +C66741,C49678,RESP,Respiratory Rate,Respiratory Rate,Respiratory Rate +C66741,C60832,OXYSAT,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation +C66741,V00224,VSALL,VS Domain ALL Tests,VS Domain ALL Tests, +C66742,C49488,Y,Yes,Yes,Yes +C66770,C25613,%,Percentage,Percentage,Percentage +C66770,C42559,C,Degree Celsius,Degree Celsius,Degree Celsius +C66770,C49670,mmHg,Millimeter of Mercury,Millimeter of Mercury,Millimeter of Mercury +C66770,C49673,beats/min,Beats per Minute,Beats per Minute,Beats per Minute; BPM; bpm +C66770,C49674,breaths/min,Breaths per Minute,Breaths per Minute,Breaths per Minute +C66789,C49484,NOT DONE,Not Done,Not Done, +C67153,C174446,Temperature,Body Temperature,Body Temperature,Body Temperature; Temperature +C67153,C25298,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure +C67153,C25299,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure +C67153,C49676,Pulse Rate,Pulse Rate,Pulse Rate,Pulse Rate +C67153,C49678,Respiratory Rate,Respiratory Rate,Respiratory Rate,Respiratory Rate +C67153,C60832,Oxygen Saturation,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation +C67153,V00224,Vital Signs,VS Domain ALL Tests,VS Domain ALL Tests, +C71113,C25473,QD,QD (Every Day),Daily,/day; Daily; Per Day +C71113,C64496,BID,BID (Twice a Day),Twice Daily,BD; Twice per day +C71113,C64499,PRN,PRN (As Needed),As Needed,As needed +C71113,C64516,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours +C71113,C64530,QID,QID (4 Times a Day),Four Times Daily,4 times per day +C71148,C111310,SEMI-RECUMBENT,Semi-Supine,Semi-Supine,Semi-Supine +C71148,C62122,SITTING,Sitting,Sitting,Sitting +C71148,C62165,PRONE,Prone,Prone,Prone +C71148,C62166,STANDING,Standing,Standing,Orthostatic; Standing +C71148,C62167,SUPINE,Supine,Supine,Supine +C71620,C25613,%,%,Percentage,Percentage +C71620,C28253,mg,mg,Milligram,Milligram +C71620,C28254,mL,mL,Milliliter,cm3; Milliliter +C71620,C48155,g,g,Gram,Gram +C71620,C48480,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit +C71620,C48542,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit +C71620,C48579,IU,IU,International Unit,IE; International Unit +C74456,C12390,RECTUM,Rectum,Rectum, +C74456,C12421,ORAL CAVITY,Oral Cavity,Oral Cavity,Buccal cavity; Mouth +C74456,C12470,SKIN,Skin,Skin,Integument; Skin +C74456,C12502,TYMPANIC MEMBRANE,Tympanic Membrane,Tympanic Membrane,Tympanic Membrane +C74456,C12674,AXILLA,Axilla,Axilla,Armpit; Axilla +C74456,C32608,FINGER,FINGER,FINGER,Finger +C74456,C89803,FOREHEAD,Forehead,Forehead,Forehead +C99073,C25228,RIGHT,Right,Right, +C99073,C25229,LEFT,Left,Left, +TPT,TPT,PREDOSE,Pre-dose,, +TPT,TPT,POSTDOSE,Post-dose,, +TPTNUM,TPTNUM,1,Pre-dose,, +TPTNUM,TPTNUM,2,Post-dose,, +VISITNUM,VISITNUM,1,Screening,, +VISITNUM,VISITNUM,2,Visit 1,, +VISIT,VISIT,SCREENING,Screening,, +VISIT,VISIT,VISIT 1,Visit 1,, \ No newline at end of file From 6266fe0653e0ab927eb0286566a91b47af079bdc Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Sat, 15 Jun 2024 00:24:03 +0000 Subject: [PATCH 17/23] Updated CM template --- inst/cm_domain/create_cm_template.R | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/inst/cm_domain/create_cm_template.R b/inst/cm_domain/create_cm_template.R index 79e7b3b7..f6c6b1e4 100644 --- a/inst/cm_domain/create_cm_template.R +++ b/inst/cm_domain/create_cm_template.R @@ -2,19 +2,18 @@ # # Label: R program to create CM Domain # -# Input raw data: -# study_sdtm_spec -# study_controlled_terminology -# study_raw_datasets +# Input raw data: cm_raw +# study_controlled_terminology : study_ct # # library(sdtm.oak) library(dplyr) + # Read Specification -study_ct <- read.csv(system.file("cm_domain/cm_sdtm_oak_ct.csv", +study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", package = "sdtm.oak")) # Read in raw data @@ -24,6 +23,9 @@ cm_raw <- read.csv(system.file("cm_domain/cm_raw_data.csv", generate_oak_id_vars(pat_var = "PATNUM", raw_src = "cm_raw") +dm <- read.csv(system.file("cm_domain/dm.csv", + package = "sdtm.oak")) + # Create CM domain. The first step in creating CM domain is to create the topic variable cm <- @@ -159,13 +161,13 @@ cm <- ct_clst = "C66742", id_vars = oak_id_vars() ) %>% - # Derive qualifier CMMODIFY Annotation text If collected value in CMMODIFY + # Derive qualifier CMMODIFY Annotation text If collected value in MODIFY # in cm_raw is different to CM.CMTRT then # assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY) {assign_no_ct( raw_dat = cm_raw, - raw_var = "CMMODIFY", - tgt_dat = condition_add(. , CMMODIFY != CMTRT, .env = cm_raw), + raw_var = "MODIFY", + tgt_dat = condition_add(. , MODIFY != CMTRT, .dat2 = cm_raw), tgt_var = "CMMODIFY", id_vars = oak_id_vars() )} %>% From 7ae3275df3287c233ac7b1344d21266c609230c3 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Sat, 15 Jun 2024 00:24:42 +0000 Subject: [PATCH 18/23] VS domain template and Vignette --- inst/cm_domain/create_vs_template.R | 402 ++++++++++++++++++ inst/cm_domain/vitals_raw_data.csv | 7 + vignettes/articles/findings_domain.Rmd | 564 +++++++++++++++++++++++++ vignettes/articles/vitals_raw_data.csv | 7 + 4 files changed, 980 insertions(+) create mode 100644 inst/cm_domain/create_vs_template.R create mode 100644 inst/cm_domain/vitals_raw_data.csv create mode 100644 vignettes/articles/findings_domain.Rmd create mode 100644 vignettes/articles/vitals_raw_data.csv diff --git a/inst/cm_domain/create_vs_template.R b/inst/cm_domain/create_vs_template.R new file mode 100644 index 00000000..8e1efb20 --- /dev/null +++ b/inst/cm_domain/create_vs_template.R @@ -0,0 +1,402 @@ +# Name: VS domain +# +# Label: R program to create VS Domain +# +# Input raw data: vitals_raw +# study_controlled_terminology : study_ct +# +# + +library(sdtm.oak) +library(dplyr) + + +# Read Specification + +study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", + package = "sdtm.oak")) + +# Read in raw data + +vs_raw <- read.csv(system.file("cm_domain/vitals_raw_data.csv", + package = "sdtm.oak")) %>% + generate_oak_id_vars(pat_var = "PATNUM", + raw_src = "vitals") + +dm <- read.csv(system.file("cm_domain/dm.csv", + package = "sdtm.oak")) + +# Create VS domain. +# Create the topic variable and corresponding qualifiers for the VS domain. + +# Map topic variable SYSBP and its qualifiers. +vs_sysbp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSTESTCD", + tgt_val = "SYSBP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + # Filter for records where VSTESTCD is not empty. + # Only these records need qualifier mappings. + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSTEST", + tgt_val = "Systolic Blood Pressure", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSORRESU", + tgt_val = "mmHg", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSPOS using assign_ct algorithm + assign_ct( + raw_dat = vs_raw, + raw_var = "SUBPOS", + tgt_var = "VSPOS", + ct_spec = study_ct, + ct_clst = "C71148", + id_vars = oak_id_vars() + ) + +# Map topic variable DIABP and its qualifiers. +vs_diabp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSTESTCD", + tgt_val = "DIABP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSTEST", + tgt_val = "Diastolic Blood Pressure", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSORRESU", + tgt_val = "mmHg", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSPOS using assign_ct algorithm + assign_ct( + raw_dat = vs_raw, + raw_var = "SUBPOS", + tgt_var = "VSPOS", + ct_spec = study_ct, + ct_clst = "C71148", + id_vars = oak_id_vars() + ) + +# Map topic variable PULSE and its qualifiers. +vs_pulse <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSTESTCD", + tgt_val = "PULSE", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSTEST", + tgt_val = "Pulse Rate", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSORRESU", + tgt_val = "beats/min", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) + +# Map topic variable RESP from the raw variable RESPRT and its qualifiers. +vs_resp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSTESTCD", + tgt_val = "RESP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSTEST", + tgt_val = "Respiratory Rate", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSORRESU", + tgt_val = "breaths/min", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) + +# Map topic variable TEMP from raw variable TEMP and its qualifiers. +vs_temp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSTESTCD", + tgt_val = "TEMP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSTEST", + tgt_val = "Temperature", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSORRESU", + tgt_val = "C", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSLOC from TEMPLOC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TEMPLOC", + tgt_var = "VSLOC", + ct_spec = study_ct, + ct_clst = "C74456", + id_vars = oak_id_vars() + ) + +# Map topic variable OXYSAT from raw variable OXY_SAT and its qualifiers. +vs_oxysat <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSTESTCD", + tgt_val = "OXYSAT", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSTEST", + tgt_val = "Oxygen Saturation", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSORRESU", + tgt_val = "%", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSLAT using assign_ct from raw variable LAT + assign_ct( + raw_dat = vs_raw, + raw_var = "LAT", + tgt_var = "VSLAT", + ct_spec = study_ct, + ct_clst = "C99073", + id_vars = oak_id_vars() + ) %>% + # Map VSLOC using assign_ct from raw variable LOC + assign_ct( + raw_dat = vs_raw, + raw_var = "LOC", + tgt_var = "VSLOC", + ct_spec = study_ct, + ct_clst = "C74456", + id_vars = oak_id_vars() + ) + +# Map topic variable VSALL from raw variable ASMNTDN with the logic if ASMNTDN == 1 then VSTESTCD = VSALL +vs_vsall <- + hardcode_ct( + raw_dat = condition_add(vs_raw, ASMNTDN == 1), + raw_var = "ASMNTDN", + tgt_var = "VSTESTCD", + tgt_val = "VSALL", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "ASMNTDN", + tgt_var = "VSTEST", + tgt_val = "Vital Signs", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) + +# Combine all the topic variables into a single data frame. +vs_combined <- dplyr::bind_rows(vs_vsall, vs_sysbp, vs_diabp, vs_pulse, vs_resp, + vs_temp, vs_oxysat) + +# Map qualifiers common to all topic variables + +vs <- vs_combined %>% + # Map VSDTC using assign_ct algorithm + assign_datetime( + raw_dat = vs_raw, + raw_var = c("VTLD", "VTLTM"), + tgt_var = "VSDTC", + raw_fmt = c(list(c("d-m-y", "dd-mmm-yyyy")), "H:M") + ) %>% + # Map VSTPT from TMPTC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TMPTC", + tgt_var = "VSTPT", + ct_spec = study_ct, + ct_clst = "TPT", + id_vars = oak_id_vars() + ) %>% + # Map VSTPTNUM from TMPTC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TMPTC", + tgt_var = "VSTPTNUM", + ct_spec = study_ct, + ct_clst = "TPTNUM", + id_vars = oak_id_vars() + ) %>% + # Map VISIT from INSTANCE using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "INSTANCE", + tgt_var = "VISIT", + ct_spec = study_ct, + ct_clst = "VISIT", + id_vars = oak_id_vars() + ) %>% + # Map VISITNUM from INSTANCE using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "INSTANCE", + tgt_var = "VISITNUM", + ct_spec = study_ct, + ct_clst = "VISITNUM", + id_vars = oak_id_vars() + ) %>% + dplyr::mutate( + STUDYID = "test_study", + DOMAIN = "VS", + VSCAT = "VITAL SIGNS", + USUBJID = paste0("test_study", "-", .data$patient_number) + ) %>% + # derive_seq(tgt_var = "VSSEQ", + # rec_vars= c("USUBJID", "CMTRT")) %>% + derive_study_day( + sdtm_in = ., + dm_domain = dm, + tgdt = "VSDTC", + refdt = "RFXSTDTC", + study_day_var = "VSDY" + ) %>% + dplyr::select("STUDYID", "DOMAIN", "USUBJID", everything()) + + diff --git a/inst/cm_domain/vitals_raw_data.csv b/inst/cm_domain/vitals_raw_data.csv new file mode 100644 index 00000000..8b164c22 --- /dev/null +++ b/inst/cm_domain/vitals_raw_data.csv @@ -0,0 +1,7 @@ +STUDY,PATNUM,SUBJSTAT,SITENM,INSTANCE,FORM,FORML,DATAPGID,RECORDID,RECPOS,ASMNTDN,TMPTC,VTLD,VTLTM,SUBPOS,SYS_BP,DIA_BP,PULSE,RESPRT,TEMP,TEMPLOC,OXY_SAT,LAT,LOC,VSO2SRC,NEWS107 +Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1752329,5734754,0,0,Pre-dose,16-May-15,7:25,PRONE,158,92,63,17,40.48,SKIN,98,RIGHT,FINGER,MASK OXYGEN THERAPY,UNRESPONSIVE +Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,8153061,3712412,1,0,Post-dose,16-May-15,10:25,SEMI-RECUMBENT,94,78,76,20,36.75,TYMPANIC MEMBRANE,99,LEFT,FINGER,ROOM AIR,NEW CONFUSION +Test Study,375,Randomized,Test Study,Screening,VTLS1,Vital Signs,3463516,1229594,0,0,,6-May-18,2:01,PRONE,117,62,66,15,29.45,ORAL CAVITY,96,LEFT,FINGER,ROOM AIR,VERBAL RESPONSIVE +Test Study,376,Randomized,Test Study,Screening,VTLS1,Vital Signs,8423253,9767053,0,1,,,,,,,,,,,,,,, +Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1211365,1567778,0,0,Pre-dose,23-Oct-08,1:19,PRONE,85,68,73,21,38.25,AXILLA,93,RIGHT,FINGER,ROOM AIR,ALERT +Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,5880552,7060998,0,0,Post-dose,23-Oct-08,3:19,PRONE,126,81,56,18,38.08,TYMPANIC MEMBRANE,93,LEFT,FINGER,MASK OXYGEN THERAPY,PAIN RESPONSIVE \ No newline at end of file diff --git a/vignettes/articles/findings_domain.Rmd b/vignettes/articles/findings_domain.Rmd new file mode 100644 index 00000000..bf9ed5ae --- /dev/null +++ b/vignettes/articles/findings_domain.Rmd @@ -0,0 +1,564 @@ +--- +title: "Creating an Findings SDTM domain" +output: + rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Creating an Findings SDTM domain} + %\VignetteEncoding{UTF-8} + %\VignetteEngine{knitr::rmarkdown} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) + +#library(sdtm.oak) +library(admiraldev) +library(rlang) +library(dplyr, warn.conflicts = FALSE) +``` + +```{r, include=FALSE} +devtools::load_all(".") +``` +# Introduction + +This article describes how to create a Findings SDTM domain using the {sdtm.oak} package. Examples are currently presented and tested in the context of the VS domain. + +Before reading this article, it is recommended that users review the "Creating an Events Domain" article, which provides a detailed explanation of various concepts in {sdtm.oak}, such as `oak_id_vars`, `condition_add`, etc. It also offers guidance on which mapping algorithms or functions to use for different mappings and provides a more detailed explanation of how these mapping algorithms or functions work. + +In this article, we will dive directly into programming and provide further explanation only where it is required. + +# Programming workflow + +In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (example Concomitant medications (OID - cm_raw), Targeted Concomitant Medications (OID - cm_t_raw)) can be stacked together before processing. + +* [Read in data](#readdata) +* [Create oak_id_vars](#oakidvars) +* [Read in CT](#readct) +* [Map Topic Variable](#maptopic) +* [Map Rest of the Variables](#maprest) +* [Repeat Map Topic and Map Rest](#repeatsteps) + +Repeat the above steps for different raw datasets before proceeding with the below steps. + +* [Create SDTM derived variables](#derivedvars) +* [Add Labels and Attributes](#attributes) + +## Read in data {#readdata} + +Read all the raw datasets into the environment. In this example, the raw dataset name is `cm_raw`. Users can read it from the package using the below code: + +```{r eval=FALSE} +vs_raw <- read.csv(system.file("cm_domain/vitals_raw_data.csv", + package = "sdtm.oak")) + +dm <- read.csv(system.file("cm_domain/dm.csv", + package = "sdtm.oak")) +``` + +```{r eval=TRUE, echo=FALSE} +vs_raw <- as_tibble(read.csv("vitals_raw_data.csv", stringsAsFactors = FALSE)) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs_raw, + display_vars = exprs( + PATNUM, FORML, ASMNTDN, TMPTC, VTLD, VTLTM, SUBPOS, SYS_BP, DIA_BP, + PULSE, RESPRT, TEMP, TEMPLOC, OXY_SAT, LAT, LOC + ) +) +``` + +## Create oak_id_vars {#oakidvars} + +```{r eval=TRUE} +vs_raw <- vs_raw %>% + generate_oak_id_vars(pat_var = "PATNUM", + raw_src = "vitals") +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs_raw, + display_vars = exprs( + oak_id, raw_source, patient_number, PATNUM, FORML, SYS_BP, DIA_BP + ) +) +``` + +Read in the DM domain + +```{r eval=TRUE, echo=FALSE} +dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) +``` + + +## Read in CT {#readct} + +Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `sdtm_ct.csv`. Users can read it from the package using the below code: + +```{r eval=FALSE} +study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", + package = "sdtm.oak")) +``` + +```{r eval=TRUE, echo=FALSE} +study_ct <- as_tibble(read.csv("sdtm_ct.csv", stringsAsFactors = FALSE)) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + study_ct, + display_vars = exprs( + codelist_code, term_code, term_value, collected_value, term_preferred_term, + term_synonyms + ) +) +``` + +## Map Topic Variable {#maptopic} + +This raw dataset has multiple topic variables. Lets start with the first topic variable. Map topic variable SYSBP from the raw variable SYS_BP. + +```{r eval=TRUE} +# Map topic variable SYSBP and its qualifiers. +vs_sysbp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSTESTCD", + tgt_val = "SYSBP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + # Filter for records where VSTESTCD is not empty. + # Only these records need qualifier mappings. + dplyr::filter(!is.na(.data$VSTESTCD)) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs_sysbp, + display_vars = exprs( + oak_id, raw_source, patient_number, VSTESTCD + ) +) +``` + +## Map Rest of the Variables {#maprest} + +Map rest of the variables applicable to the topic variable SYSBP. This can include qualifiers, identifier and timing variables. + +```{r eval=TRUE} +# Map topic variable SYSBP and its qualifiers. +vs_sysbp <- vs_sysbp %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSTEST", + tgt_val = "Systolic Blood Pressure", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "SYS_BP", + tgt_var = "VSORRESU", + tgt_val = "mmHg", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSPOS using assign_ct algorithm + assign_ct( + raw_dat = vs_raw, + raw_var = "SUBPOS", + tgt_var = "VSPOS", + ct_spec = study_ct, + ct_clst = "C71148", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs_sysbp, + display_vars = exprs( + oak_id, raw_source, patient_number, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS + ) +) +``` + +## Repeat Map Topic and Map Rest {#repeatsteps} + +This raw data source has other topic variables DIABP, PULSE, RESP, TEMP, OXYSAT, VSALL and its corresponding qualifiers. Repeat mapping topic and qualifiers for each topic variable. + +```{r eval=TRUE} +# Map topic variable DIABP and its qualifiers. +vs_diabp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSTESTCD", + tgt_val = "DIABP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSTEST", + tgt_val = "Diastolic Blood Pressure", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "DIA_BP", + tgt_var = "VSORRESU", + tgt_val = "mmHg", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSPOS using assign_ct algorithm + assign_ct( + raw_dat = vs_raw, + raw_var = "SUBPOS", + tgt_var = "VSPOS", + ct_spec = study_ct, + ct_clst = "C71148", + id_vars = oak_id_vars() + ) + +# Map topic variable PULSE and its qualifiers. +vs_pulse <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSTESTCD", + tgt_val = "PULSE", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSTEST", + tgt_val = "Pulse Rate", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "PULSE", + tgt_var = "VSORRESU", + tgt_val = "beats/min", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) + +# Map topic variable RESP from the raw variable RESPRT and its qualifiers. +vs_resp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSTESTCD", + tgt_val = "RESP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSTEST", + tgt_val = "Respiratory Rate", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "RESPRT", + tgt_var = "VSORRESU", + tgt_val = "breaths/min", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) + +# Map topic variable TEMP from raw variable TEMP and its qualifiers. +vs_temp <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSTESTCD", + tgt_val = "TEMP", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSTEST", + tgt_val = "Temperature", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "TEMP", + tgt_var = "VSORRESU", + tgt_val = "C", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSLOC from TEMPLOC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TEMPLOC", + tgt_var = "VSLOC", + ct_spec = study_ct, + ct_clst = "C74456", + id_vars = oak_id_vars() + ) + +# Map topic variable OXYSAT from raw variable OXY_SAT and its qualifiers. +vs_oxysat <- + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSTESTCD", + tgt_val = "OXYSAT", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSTEST", + tgt_val = "Oxygen Saturation", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) %>% + # Map VSORRES using assign_no_ct algorithm + assign_no_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSORRES", + id_vars = oak_id_vars() + ) %>% + # Map VSORRESU using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "OXY_SAT", + tgt_var = "VSORRESU", + tgt_val = "%", + ct_spec = study_ct, + ct_clst = "C66770", + id_vars = oak_id_vars() + ) %>% + # Map VSLAT using assign_ct from raw variable LAT + assign_ct( + raw_dat = vs_raw, + raw_var = "LAT", + tgt_var = "VSLAT", + ct_spec = study_ct, + ct_clst = "C99073", + id_vars = oak_id_vars() + ) %>% + # Map VSLOC using assign_ct from raw variable LOC + assign_ct( + raw_dat = vs_raw, + raw_var = "LOC", + tgt_var = "VSLOC", + ct_spec = study_ct, + ct_clst = "C74456", + id_vars = oak_id_vars() + ) + +# Map topic variable VSALL from raw variable ASMNTDN with the logic if ASMNTDN == 1 then VSTESTCD = VSALL +vs_vsall <- + hardcode_ct( + raw_dat = condition_add(vs_raw, ASMNTDN == 1), + raw_var = "ASMNTDN", + tgt_var = "VSTESTCD", + tgt_val = "VSALL", + ct_spec = study_ct, + ct_clst = "C66741" + ) %>% + dplyr::filter(!is.na(.data$VSTESTCD)) %>% + # Map VSTEST using hardcode_ct algorithm + hardcode_ct( + raw_dat = vs_raw, + raw_var = "ASMNTDN", + tgt_var = "VSTEST", + tgt_val = "Vital Signs", + ct_spec = study_ct, + ct_clst = "C67153", + id_vars = oak_id_vars() + ) +``` + +Now that all the topic variable and its qualifier mappings are complete, combine all the datasets and proceed with mapping qualifiers, identifiers and timing variables appicable to all topic variables. + +```{r, eval=TRUE} +# Combine all the topic variables into a single data frame and map qualifiers +# applicable to all topic variables +vs <- dplyr::bind_rows(vs_vsall, vs_sysbp, vs_diabp, vs_pulse, vs_resp, + vs_temp, vs_oxysat) %>% + # Map qualifiers common to all topic variables + # Map VSDTC using assign_ct algorithm + assign_datetime( + raw_dat = vs_raw, + raw_var = c("VTLD", "VTLTM"), + tgt_var = "VSDTC", + raw_fmt = c(list(c("d-m-y", "dd-mmm-yyyy")), "H:M") + ) %>% + # Map VSTPT from TMPTC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TMPTC", + tgt_var = "VSTPT", + ct_spec = study_ct, + ct_clst = "TPT", + id_vars = oak_id_vars() + ) %>% + # Map VSTPTNUM from TMPTC using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "TMPTC", + tgt_var = "VSTPTNUM", + ct_spec = study_ct, + ct_clst = "TPTNUM", + id_vars = oak_id_vars() + ) %>% + # Map VISIT from INSTANCE using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "INSTANCE", + tgt_var = "VISIT", + ct_spec = study_ct, + ct_clst = "VISIT", + id_vars = oak_id_vars() + ) %>% + # Map VISITNUM from INSTANCE using assign_ct + assign_ct( + raw_dat = vs_raw, + raw_var = "INSTANCE", + tgt_var = "VISITNUM", + ct_spec = study_ct, + ct_clst = "VISITNUM", + id_vars = oak_id_vars() + ) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs, + display_vars = exprs( + oak_id, raw_source, patient_number, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS, + VSLAT, VSDTC, VSTPT, VSTPTNUM, VISIT, VISITNUM + ) +) +``` + +## Create SDTM derived variables {#derivedvars} + +Create derived variables applicable to all topic variables. + +```{r eval=TRUE} +vs <- vs %>% + dplyr::mutate( + STUDYID = "test_study", + DOMAIN = "VS", + VSCAT = "VITAL SIGNS", + USUBJID = paste0("test_study", "-", .data$patient_number) + ) %>% + # derive_seq(tgt_var = "VSSEQ", + # rec_vars= c("USUBJID", "CMTRT")) %>% + derive_study_day( + sdtm_in = ., + dm_domain = dm, + tgdt = "VSDTC", + refdt = "RFXSTDTC", + study_day_var = "VSDY" + ) %>% + dplyr::select("STUDYID", "DOMAIN", "USUBJID", everything()) +``` + +```{r, eval=TRUE, echo=FALSE} +dataset_oak_vignette( + vs, + display_vars = exprs( + STUDYID, DOMAIN, USUBJID, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS, + VSLAT, VSTPT, VSTPTNUM, VISIT, VISITNUM, VSDTC, VSDY + ) +) +``` + +## Add Labels and Attributes {#attributes} + +Yet to be devleoped. diff --git a/vignettes/articles/vitals_raw_data.csv b/vignettes/articles/vitals_raw_data.csv new file mode 100644 index 00000000..8b164c22 --- /dev/null +++ b/vignettes/articles/vitals_raw_data.csv @@ -0,0 +1,7 @@ +STUDY,PATNUM,SUBJSTAT,SITENM,INSTANCE,FORM,FORML,DATAPGID,RECORDID,RECPOS,ASMNTDN,TMPTC,VTLD,VTLTM,SUBPOS,SYS_BP,DIA_BP,PULSE,RESPRT,TEMP,TEMPLOC,OXY_SAT,LAT,LOC,VSO2SRC,NEWS107 +Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1752329,5734754,0,0,Pre-dose,16-May-15,7:25,PRONE,158,92,63,17,40.48,SKIN,98,RIGHT,FINGER,MASK OXYGEN THERAPY,UNRESPONSIVE +Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,8153061,3712412,1,0,Post-dose,16-May-15,10:25,SEMI-RECUMBENT,94,78,76,20,36.75,TYMPANIC MEMBRANE,99,LEFT,FINGER,ROOM AIR,NEW CONFUSION +Test Study,375,Randomized,Test Study,Screening,VTLS1,Vital Signs,3463516,1229594,0,0,,6-May-18,2:01,PRONE,117,62,66,15,29.45,ORAL CAVITY,96,LEFT,FINGER,ROOM AIR,VERBAL RESPONSIVE +Test Study,376,Randomized,Test Study,Screening,VTLS1,Vital Signs,8423253,9767053,0,1,,,,,,,,,,,,,,, +Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1211365,1567778,0,0,Pre-dose,23-Oct-08,1:19,PRONE,85,68,73,21,38.25,AXILLA,93,RIGHT,FINGER,ROOM AIR,ALERT +Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,5880552,7060998,0,0,Post-dose,23-Oct-08,3:19,PRONE,126,81,56,18,38.08,TYMPANIC MEMBRANE,93,LEFT,FINGER,MASK OXYGEN THERAPY,PAIN RESPONSIVE \ No newline at end of file From 48ed54402297b3266aac0c17ccebb813adff23e2 Mon Sep 17 00:00:00 2001 From: Rammprasad Ganapathy Date: Sat, 15 Jun 2024 00:24:59 +0000 Subject: [PATCH 19/23] CM domain Vignette update --- vignettes/articles/events_domain.Rmd | 46 +++++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/vignettes/articles/events_domain.Rmd b/vignettes/articles/events_domain.Rmd index 4b89e3b3..9a9156db 100644 --- a/vignettes/articles/events_domain.Rmd +++ b/vignettes/articles/events_domain.Rmd @@ -33,7 +33,7 @@ Raw datasets can be exported from the EDC systems in the format they are collect The raw dataset is presented below: -```{r eval=TRUE} +```{r eval=TRUE, echo=FALSE} cm_raw <- as_tibble(read.csv("cm_raw_data.csv", stringsAsFactors = FALSE)) ``` @@ -55,7 +55,15 @@ In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (exampl * [Create oak_id_vars](#oakidvars) * [Read in CT](#readct) * [Map Topic Variable](#maptopic) -* [Map Qualifies, Identifiers, and Timing Variables](#mapqualifiers) +* [Map Rest of the Variables](#maprest) + * [assign_no_ct](#assign_no_ct) + * [assign_ct](#assign_ct) + * [assign_datetime](#assign_datetime) + * [hardcode_ct and condition_add](#hardcode_ct) + * [hardcode_no_ct and condition_add](#hardcode_no_ct) + * [condition_add involving target domain](#condition_add_tar) + * [condition_add involving raw dataset and target domain](#condition_add_raw_tar) +* [Repeat Map Topic and Map Rest](#repeatsteps) Repeat the above steps for different raw datasets before proceeding with the below steps. @@ -99,7 +107,7 @@ dataset_oak_vignette( ) ``` -Reead in the DM domain +Read in the DM domain ```{r eval=TRUE} dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) @@ -108,15 +116,15 @@ dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) ## Read in CT {#readct} -Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `cm_sdtm_oak_ct.csv`. Users can read it from the package using the below code: +Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `sdtm_ct.csv`. Users can read it from the package using the below code: ```{r eval=FALSE} -study_ct <- read.csv(system.file("cm_domain/cm_sdtm_oak_ct.csv", +study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", package = "sdtm.oak")) ``` ```{r eval=TRUE} -study_ct <- as_tibble(read.csv("cm_sdtm_oak_ct.csv", stringsAsFactors = FALSE)) +study_ct <- as_tibble(read.csv("sdtm_ct.csv", stringsAsFactors = FALSE)) ``` ```{r, eval=TRUE, echo=FALSE} @@ -153,11 +161,11 @@ dataset_oak_vignette( ) ) ``` -## Map Qualifiers, Identifiers, and Timing Variables {#mapqualifiers} +## Map Rest of the Variables {#maprest} The Qualifiers, Identifiers, and Timing Variables can be mapped in any order. In this example, we will map each variable one by one to demonstrate different mapping algorithms. -### `assign_no_ct` +### assign_no_ct {#assign_no_ct} The mapping logic for `CMGRPID` is `Map the collected value in the cm_raw dataset MDNUM variable to CM.CMGRPID`. @@ -184,7 +192,7 @@ dataset_oak_vignette( The CMGRPID is added to the corresponding CMTRT based on the 'oak_id_vars'. When calling the function, the parameter 'id_vars = oak_id_vars()' matches the raw dataset 'oak_id_vars' to the 'oak_id_vars' in the cm domain created in the previous step. It's important to note that the 'oak_id_vars' can be extended to include user-defined variables. But in most cases, the three variables should suffice. -### `assign_ct` +### assign_ct {#assign_ct} The mapping logic for `CMDOSU` is `Map the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU`. The controlled terminology is used to map the collected value to the standard value. `assign_ct` is the right algorithm to perform this mapping. @@ -210,7 +218,7 @@ dataset_oak_vignette( ) ``` -### `assign_datetime` +### assign_datetime {#assign_datetime} The mapping logic for `CMSTDTC` is `Map the collected value in the cm_raw dataset MDBDR (start date) variable and MDBTM (start time) to CM.CMSTDTC`. The collected date value is in the format 'dd mmm yyyy'. The collected time value is in 'H"M' format. The `assign_datetime` function is used to map the collected value in ISO8601 format. @@ -236,7 +244,7 @@ dataset_oak_vignette( ) ``` -### `hardcode_ct` and `condition_add` +### hardcode_ct and condition_add {#hardcode_ct} The mapping logic for `CMSTRTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTRTPT == 'BEFORE'.` The `hardcode_ct` function is used to map the CMSTRTPT as it involves hardcoding a specific value to an SDTM variable with controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_ct` function performs the mapping. @@ -267,7 +275,7 @@ dataset_oak_vignette( The `condition_add` function adds additional metadata to the records in the raw dataset that meets the condition. Refer to the function documentation for more details. `hardcode_ct` function uses the addtional metadata to find the records that meet the criteria and map them accordingly. -## hardcode_no_ct and condition_add +### hardcode_no_ct and condition_add {#hardcode_no_ct} The mapping logic for `CMSTTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTTPT == 'SCREENING'.` The `hardcode_no_ct` function is used to map the CMSTTPT as it involves hardcoding a specific value to an SDTM variable without controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_no_ct` function performs the mapping. @@ -292,7 +300,7 @@ dataset_oak_vignette( ) ``` -### condition_add involving target domain +### condition_add involving target domain {#condition_add_tar} In the mapping for `CMSTRTPT` and `CMSTTTPT`, the `condition_add` function is used in the raw dataset. In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. @@ -342,7 +350,7 @@ cm <- cm %>% ) ``` -### condition_add involving raw dataset and target domain +### condition_add involving raw dataset and target domain {#condition_add_raw_tar} In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. @@ -382,7 +390,7 @@ cm <- cm %>% ) ``` -### Map rest of the variables +Now, complete mapping the rest of the SDTM variables. ```{r eval=TRUE} cm <- cm %>% @@ -510,6 +518,10 @@ dataset_oak_vignette( ) ``` +## Repeat Map Topic and Map Rest {#repeatsteps} + +There is only one topic variable in this raw data source, and there are no additional topic variable mappings. Users can proceed to the next step. This is required only if there is more than one topic variable to map. + ## Create SDTM derived variables {#derivedvars} The SDTM derived variables or any SDTM mapping that is applicable to all the records in the `cm` dataset produced in the previous step cam be created now. In this example, we will create the `CMSEQ` variable. The mapping logic is `Create a sequence number for each record in the CM domain`. @@ -554,3 +566,7 @@ dataset_oak_vignette( ) ``` + +## Add Labels and Attributes {#attributes} + +Yet to be developed. From 0c4b00dbd94426520fefc9ba77cc9a2e25ee4599 Mon Sep 17 00:00:00 2001 From: Edgar Manukyan Date: Mon, 17 Jun 2024 14:34:52 -0400 Subject: [PATCH 20/23] just testing --- vignettes/articles/algorithms.Rmd | 221 ---------- vignettes/articles/cm_raw_data.csv | 15 - vignettes/articles/dm.csv | 6 - vignettes/articles/events_domain.Rmd | 572 ------------------------- vignettes/articles/findings_domain.Rmd | 564 ------------------------ vignettes/articles/iso_8601.Rmd | 254 ----------- vignettes/articles/just-dm.Rmd | 24 ++ vignettes/articles/sdtm_ct.csv | 75 ---- vignettes/articles/study_sdtm_spec.Rmd | 361 ---------------- vignettes/articles/vitals_raw_data.csv | 7 - 10 files changed, 24 insertions(+), 2075 deletions(-) delete mode 100644 vignettes/articles/algorithms.Rmd delete mode 100644 vignettes/articles/cm_raw_data.csv delete mode 100644 vignettes/articles/dm.csv delete mode 100644 vignettes/articles/events_domain.Rmd delete mode 100644 vignettes/articles/findings_domain.Rmd delete mode 100644 vignettes/articles/iso_8601.Rmd create mode 100644 vignettes/articles/just-dm.Rmd delete mode 100644 vignettes/articles/sdtm_ct.csv delete mode 100644 vignettes/articles/study_sdtm_spec.Rmd delete mode 100644 vignettes/articles/vitals_raw_data.csv diff --git a/vignettes/articles/algorithms.Rmd b/vignettes/articles/algorithms.Rmd deleted file mode 100644 index 3854287d..00000000 --- a/vignettes/articles/algorithms.Rmd +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: "Algorithms & Sub-Algorithms" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Algorithms & Sub-Algorithms} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} -editor_options: - markdown: - wrap: 72 ---- - -## Core Concept - -SDTM mappings are defined as algorithms that transform the collected -(eCRF, eDT) source data into the target SDTM data model. Mapping -algorithms are the backbone of the {sdtm.oak} - SDTM data transformation -engine. - -**Key Points:** - -- Algorithms can be re-used across multiple SDTM domains. - -- Algorithms are pre-specified for data collection standards in MDR - (if applicable) to facilitate automation. - -- Programming language agnostic - this concept does not rely on a - specific programming language for implementation. The {sdtm.oak} team - implemented them as R functions. - -Here is an example of reusing an algorithm across multiple domains, -variables, and also to a non-standard - -![](reusable_algorithms.jpg){width="600px"} - -## List of Algorithms - -This release of {sdtm.oak} supports the following algorithms: assign_no_ct, assign_ct, hardcode_no_ct, hardcode_ct, assign_datetime, condition_add. Rest of the algorithms will be developed in the subsequent releases. - -The following table provides a brief description of each algorithm. - -```{r echo = FALSE, results = "asis"} -library(knitr) -algorithms <- data.frame( - `Algorithm Name` = c( - "assign_no_ct", - "assign_ct", - "assign_datetime", - "hardcode_ct", - "hardcode_no_ct", - "condition_add", - "ae_aerel", - "dataset_level", - "not_submitted", - "relrec", - "multiple_responses", - "split_to_suppqual", - "remove_dup", - "group_by", - "merge_datasets" - ), - `Description` = c( - paste( - "One-to-one mapping between the raw source and a target", - "SDTM variable that has no controlled terminology restrictions.", - "Just a simple assignment", - "statement." - ), - paste( - "One-to-one mapping between the raw source and a target ", - "SDTM variable that is subject to controlled terminology restrictions.", - "A simple assign statement and applying controlled terminology.", - "This will be used only if the SDTM variable has an associated", - "controlled terminology." - ), - paste( - "One-to-one mapping between the raw source and a target that involves ", - "mapping a Date or time or datetime component. This mapping algorithm", - "also takes care of handling unknown dates and converting them into.", - "ISO8601 format." - ), - paste( - "Mapping a hardcoded value to a target SDTM variable that is subject to terminology restrictions.", - "This will be used only if the SDTM variable has an associated", - "controlled terminology." - ), - paste( - "Mapping a hardcoded value to a target SDTM variable that has no terminology restrictions." - ), - paste( - "Algorithm that is used to filter the source data and/or target domain", - "based on a condition. The mapping will be applied only if the condition is met.", - "The filter can be applied either at the source dataset or at target dataset or both.", - " This algorithm has to be used in conjunction with other algorithms, that is if the", - " condition is met perform the mapping using algorithms like assign_ct,", - "assign_no_ct, hardcode_ct, hardcode_no_ct, assign_datetime." - ), - paste( - "Algorithm that is currently unique to AE.AEREL,", - "particularly when more than one drug is used in the study.
If any collected study drug", - "causalities are 'Yes' then AE.AEREL is Y.
If all collected study", - "drug causalities are 'NA' then AE.AEREL is NA.
If no study drug", - "causalities are 'Yes' but there is at least one causality of 'No'", - "then AE.AEREL is N.
Individual study drug causality responses are", - "stored in AERELn in SUPPAE." - ), - paste( - "Indicates a dataset-level mapping. These mappings will", - "be applied to all SDTM records created from that source.", - "Also called an eCRF-level mappings in eCRF and dataset-level", - "mappings in eDT" - ), - paste( - "Instruction that `{sdtm.oak}` should not map the collected item to SDTM at all." - ), - paste( - "Associate two domains based on the variables in each domain and how those are related.", - "Specifies the name of two domains that are related via RELREC." - ), - paste( - "Consolidate the responses from more than one source variable into one target variable.", - "Used when multiple responses may be given for a single SDTM column.", - "`{sdtm.oak}` will populate all target variable(s) after determining the number of responses provided." - ), - paste( - "Consolidates the responses from more than one", - "source variable into more than one target variable", - "(always a suppqual/non-standard variable).", - "There is no 'parent' target variable that is populated with 'MULTIPLE'." - ), - paste( - "Sub-algorithm at the domain level that indicates some source records may", - "be removed during the `{sdtm.oak}` mapping process if determined to be duplicate records." - ), - paste( - "Sub-algorithm used at the domain level to group source records", - "before mapping to SDTM. This is used in the event we need to collapse data", - "collected across multiple rows into one row in SDTM but it is not a simple", - "un-duplication effort. For example, the way infusion study drug", - "administration data requires us to create 1 SDTM record in EC from 1 or more sources", - "records. When there is more than one source record,", - "we need to take the earliest collected infusion start date (for ECSTDTC) and", - "the latest collected infusion end date within an eCRF instance." - ), - paste( - "To indicate a join condition with a secondary source or multiple sources.", - "Merges are expressed at the domain level only", - "(not at data point or variable level).", - "This is a sub-algorithm and can only be used with algorithm DATASET_LEVEL." - ) - ), - `Example` = c( - paste( - "MH.MHTERM
", - "AE.AETERM" - ), - paste("VS.VSPOS
", "VS.VSLAT"), - paste("MH.MHSTDTC
", "AE.AEENDTC"), - paste( - "MH.MHPRESP = 'Y'
", - "
VS.VSTEST = 'Systolic Blood Pressure'
", - "
VS.VSORRESU = 'mmHg'
" - ), - paste( - "FA.FASCAT = 'COVID-19 PROBABLE CASE'
", - "
CM.CMTRT = 'FLUIDS'" - ), - paste( - "If If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE'.
", - "
VS.VSMETHOD when VSTESTCD = 'TEMP'
", - "
If collected value in raw variable DOS is numeric then CM.CMDOSE
", - "
If collected value in raw variable MOD is different to CMTRT then map to CM.CMMODIFY" - ), - paste("For AE.AEREL and AERELn in SUPPAE"), - paste( - "VS = 'Vital Signs'
", - "
MH.MHCAT = 'PROSTATE CANCER HISTORY'
" - ), - paste(""), - paste("BE record related to BS record via RELREC"), - paste( - "AE.AERELNST/ AERELNSn IN SUPPAE

", - "
DM.RACE, if only one value is selected.
", - "DM.RACE = MULTIPLE, if more than one value is selected.
", - "RACEn in SUPPDM where n = 1 to N selected values" - ), - paste( - "If both Filipino and Samoan are checked,", - "CRACE1 will be 'FILIPINO' and CRACE2 will be 'SAMOAN'.
", - "If only Chinese is checked, CRACE1 will be 'CHINESE'." - ), - paste("Remove duplicates on the Vital signs raw dataset based on subject number"), - paste("EC = 'Exposure as Collected'"), - paste( - "Merge AE raw dataset with SAE based on Subject number." - ) - ),stringsAsFactors = TRUE -) -knitr::kable(algorithms) -``` - -## Sub-algorithms - -{sdtm.oak} supports two levels for defining algorithms. For example, there -are some SDTM mappings where a certain action has to be taken only when -a condition is met. In such cases, the primary algorithm checks for the -condition, and the sub-algorithm executes the mappings when the -condition is met. - -Currently, sub-algorithms must be provided for this main algorithms. - -- condition_add -- dataset_level - -Some algorithms can be interchangeably used as algorithms and as -sub-algorithms as seen below (not an exhaustive list) - -![](algo_sub_algo_combo.jpg){width="650px"} - -The permutation & combination of algorithms & sub-algorithms creates -endless possibilities to accommodate different types of mappings. diff --git a/vignettes/articles/cm_raw_data.csv b/vignettes/articles/cm_raw_data.csv deleted file mode 100644 index 10390854..00000000 --- a/vignettes/articles/cm_raw_data.csv +++ /dev/null @@ -1,15 +0,0 @@ -PATNUM,SUBJSTAT,SITENM,INSTANCE,INSTRN,FOLDER,FOLDERL,FOLDERSQ,FORM,FORML,DATAPGID,PGREPNUM,RECORDDT,RECORDID,RECPOS,RECSTAT,MDNUM,MDNUM_RAW,MDREC,MDRAW,MDIND,MDBDR,MDBDTU,MDBTM,MDBTMU,MDPRIOR,MDEDR,MDEDT,MDETM,MDETMU,MDONG,DOS,DOSU,DOSUV,MDFORM,MDRTE,MDFRQ,MDPROPH,TERMID,SRCLN,RAVRFID,MODIFY,CMDRG,CMDRGCD,CMDECOD,CMPNCD,SPLIT,OMIT,ACTTYP,ACTTEXT,CMDICT,CMCLAS,CMCLASCD,CMATC4,CMATC4CD,CMATC3,CMATC3CD,CMATC2,CMATC2CD,CMATC1,CMATC1CD,CLASSNUM -375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111885785,1,N,1,1,No,BABY ASPIRIN,,,1,,1,1,,,,0,1,10,mg,MG,Tablet,PO (Oral),QD (Every Day),0,109576058,20,5652739,BABY ASPIRIN,BABY ASPIRIN,2701701,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 -375,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56379253,0,,111969387,2,N,2,2,No,CORTISPORIN,NAUSEA,15-Sep-20,0,,1,0,,,,0,1,50,g,G,Pill,PO (Oral),,0,105820348,28,5533807,CORTISPORIN (UNITED STATES),CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,90104001001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,S03C,OPHTHALMOLOGICAL AND OTOLOGICAL PREPARATIONS,S03,SENSORY ORGANS,S,1 -376,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56407664,0,,111939965,1,N,1,1,No,ASPIRIN,ANEMIA,17-Feb-21,0,8:00,0,0,17-Feb-21,2/17/21,,0,0,,,,,,,0,80619660,8,4297014,ASPIRIN,ASPIRIN [ACETYLSALICYLIC ACID],2701004,ACETYLSALICYLIC ACID,2701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,OTHER AGENTS FOR LOCAL ORAL TREATMENT,A01AD,STOMATOLOGICAL PREPARATIONS,A01A,STOMATOLOGICAL PREPARATIONS,A01,ALIMENTARY TRACT AND METABOLISM,A,1 -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,111942855,1,N,1,1,No,DIPHENHYDRAMINE HCL,NAUSEA,4-Oct-20,0,9:00,0,0,,,,0,1,50,mg,MG,Capsule,PO (Oral),BID (Twice a Day),0,79751919,3,4240092,DIPHENHYDRAMINE HCL,DIPHENHYDRAMINE HCL,402246,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972536,2,N,2,2,No,PARCETEMOL,PYREXIA,20-Jan-20,0,10:00,0,0,20-Jan-20,1/20/20,10:00,0,0,,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,129972536,2,,,,,,,,,,,,,,,,,,,,,, -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972541,3,N,3,3,No,VOMIKIND,VOMITINGS,UN UNK 2019,1,,1,0,UN UNK 2019,6/15/19,,1,0,,Tablet,TABLET,,PO (Oral),PRN (As Needed),1,129972541,3,,,,,,,,,,,,,,,,,,,,,, -377,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,56408736,0,,129972568,4,N,5,5,No,ZENFLOX OZ,DIARHHEA,20 UNK 2019,0,10:00,0,0,20 UNK 2019,6/15/19,,1,0,,mL,ML,Injection,IM (Intramuscular),PRN (As Needed),1,129972568,4,,,,,,,,,,,,,,,,,,,,,, -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472439,4,N,4,4,No,AMITRYPTYLINE,COLD,UN UNK 2020,0,,1,1,UN UNK 2020,6/15/20,,1,0,12,g,G,Inhalant,IA (Intra-arterial),QD (Every Day),0,81845879,6,4382628,AMITRIPTYLINE,AMITRIPTYLINE,2201001,AMITRIPTYLINE,2201001,,,SPELLING UPDATE,AMITRIPTYLINE,"WHODRUG GLOBAL B3 MARCH 1, 2021",DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,DRUGS FOR URINARY FREQUENCY AND INCONTINENCE,G04BD,UROLOGICALS,G04B,UROLOGICALS,G04,GENITO URINARY SYSTEM AND SEX HORMONES,G,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472436,1,N,1,1,No,BENADRYL,FEVER,26-Jan-20,0,9:00,0,0,26-Jan-20,1/26/20,7:00,0,0,100,mg,MG,Capsule,PO (Oral),BID (Twice a Day),1,95547017,4,5211852,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472437,2,N,2,2,Yes,DIPHENHYDRAMINE HYDROCHLORIDE,LEG PAIN,28-Jan-20,1,,1,1,1-Feb-20,2/1/20,,1,1,100,Capsule,CAPSULE,Capsule,Unknown,QD (Every Day),0,94095723,13,5084095,DIPHENHYDRAMINE HYDROCHLORIDE,DIPHENHYDRAMINE HYDROCHLORIDE,402001,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -378,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059916,0,,126472438,3,N,3,3,Yes,TETRACYCLINE,FEVER,12-Feb-20,0,12:12,0,1,18-Feb-20,2/18/20,,0,0,10,mg,MG,Capsule,DE (Transdermal),BID (Twice a Day),1,84246445,6,4537684,TETRACYCLINE,TETRACYCLINE,1701001,TETRACYCLINE,1701001,,,,,"WHODRUG GLOBAL B3 MARCH 1, 2021",ANTIBIOTICS,S01AA,ANTIBIOTICS,S01AA,ANTIINFECTIVES,S01A,OPHTHALMOLOGICALS,S01,SENSORY ORGANS,S,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472565,3,N,1,1,No,BENADRYL,COLD,10 UNK 2020,0,,0,0,20 UNK 2020,6/15/20,,0,0,12,IU,IU,Lotion,IJ (Intra-articular), , ,84734661,12,4567194,BENADRYL (UNITED STATES),BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE],402002,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472563,1,N,2,2,No,SOMINEX,COLD,,1,,1,0,,,,1,1,,mL,ML,Liquid,EP (Epidural),PRN (As Needed),0,82746644,5,4580551,SOMINEX (UNITED STATES),SOMINEX [DIPHENHYDRAMINE HYDROCHLORIDE],402060,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,COUNTRY,APPLY SITE COUNTRY TO TERM,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 -379,Randomized,TEST SITE,Concomitant Medications,0,MD,Concomitant Medications,15,MD1,Concomitant Medications,63059986,0,,126472564,2,N,3,3,No,ZQUILL,PAIN,,1,,1,0,17-Feb-20,2/17/20,,1,0,5,%,%,Aerosol,OP (Ophthalmic),Q2H (Every 2 Hours),0,99707553,22,5330876,ZZZQUIL,ZZZQUIL,402326,DIPHENHYDRAMINE HYDROCHLORIDE,402001,,,SPELLING UPDATE,ZZZQUIL,"WHODRUG GLOBAL B3 MARCH 1, 2021",AMINOALKYL ETHERS,R06AA,AMINOALKYL ETHERS,R06AA,ANTIHISTAMINES FOR SYSTEMIC USE,R06A,ANTIHISTAMINES FOR SYSTEMIC USE,R06,RESPIRATORY SYSTEM,R,1 diff --git a/vignettes/articles/dm.csv b/vignettes/articles/dm.csv deleted file mode 100644 index 5d58d228..00000000 --- a/vignettes/articles/dm.csv +++ /dev/null @@ -1,6 +0,0 @@ -"STUDYID","DOMAIN","USUBJID","SUBJID","RFSTDTC","RFENDTC","RFXSTDTC","RFXENDTC","RFICDTC","RFPENDTC","DTHDTC","DTHFL","SITEID","INVID","INVNAM","BRTHDTC","AGE","AGEU","SEX","RACE","ETHNIC","ARMCD","ARM","ACTARMCD","ACTARM","COUNTRY","DMDTC","DMDY","RACE1","RACE2","RACE3" -"test_study","DM","test_study-375","test_study-375","1999-04-14T08:36","2013-01-21","2023-04-14T08:36","2021-01-11T07:50","2007-01-15","2020-04-02","2020-04-02","Y","111111","90009","Dr doctor9",NA,NA,NA,"F","MULTIPLE",NA,NA,NA,NA,NA,"US",NA,NA,"NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER","WHITE",NA -"test_study","DM","test_study-376","test_study-376","2001-03-21","2007-05-21","2020-03-21","2017-09-14T18:49",NA,"2011-12-18","2011-12-18",NA,"111111","90009","Dr doctor9","1981-02-26T18:07",42,"YEARS","M","MULTIPLE","NOT HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,"BLACK OR AFRICAN AMERICAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" -"test_study","DM","test_study-377","test_study-377","1999-03-14","2021-05-05","2020-03-14","2013-08-23T12:37","2015-10-07","2021-05-05","2019-06-29",NA,"111111","90009","Dr doctor9","1968-03-19T04:36",56,"YEARS",NA,"MULTIPLE","NOT REPORTED",NA,NA,NA,NA,"US",NA,NA,"ASIAN","AMERICAN INDIAN OR ALASKA NATIVE","UNKNOWN" -"test_study","DM","test_study-378","test_study-378","2003-02-06T06:33","2021-04-24T09:06","2021-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11",NA,"111111","90009","Dr doctor9","1979-09-24",45,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA -"test_study","DM","test_study-379","test_study-379","2003-02-06T06:33","2021-04-24T09:06","2022-02-06T06:33","2021-04-24T09:06","2018-10-20","2017-04-11","2017-04-11","Y","111111","90009","Dr doctor9","1963-09-24",61,"YEARS","M","BLACK OR AFRICAN AMERICAN","HISPANIC OR LATINO",NA,NA,NA,NA,"US",NA,NA,NA,NA,NA diff --git a/vignettes/articles/events_domain.Rmd b/vignettes/articles/events_domain.Rmd deleted file mode 100644 index 9a9156db..00000000 --- a/vignettes/articles/events_domain.Rmd +++ /dev/null @@ -1,572 +0,0 @@ ---- -title: "Creating an Events SDTM domain" -output: - rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Creating an Events SDTM domain} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} ---- - -```{r setup, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) - -#library(sdtm.oak) -library(admiraldev) -library(rlang) -library(dplyr, warn.conflicts = FALSE) -``` - -```{r, include=FALSE} -devtools::load_all(".") -``` -# Introduction - -This article describes creating an Events SDTM domain using the `sdtm.oak` package. Examples are currently presented and tested in the context of the CM domain. - -# Raw data - -Raw datasets can be exported from the EDC systems in the format they are collected. The example used provides a raw dataset for Concomitant medications, where the collected data is represented as columns for each subject. For example, the Medication Name(MDRAW), Medication Start Date (MDBDR), Start Time (MDBTM), End Date (MDEDR), End time (MDETM), etc. are represented as columns.This format is commonly used in most EDC systems. - -The raw dataset is presented below: - -```{r eval=TRUE, echo=FALSE} -cm_raw <- as_tibble(read.csv("cm_raw_data.csv", stringsAsFactors = FALSE)) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm_raw, - display_vars = exprs( - PATNUM, FORML, MDNUM, MDRAW, MDIND, MDBDR, MDBTM, MDPRIOR, MDEDR, - MDETM, MDONG, DOS, DOSU, MDFORM, MDRTE, MDFRQ, MDPROPH - ) -) -``` - -# Programming workflow - -In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (example Concomitant medications (OID - cm_raw), Targeted Concomitant Medications (OID - cm_t_raw)) can be stacked together before processing. - -* [Read in data](#readdata) -* [Create oak_id_vars](#oakidvars) -* [Read in CT](#readct) -* [Map Topic Variable](#maptopic) -* [Map Rest of the Variables](#maprest) - * [assign_no_ct](#assign_no_ct) - * [assign_ct](#assign_ct) - * [assign_datetime](#assign_datetime) - * [hardcode_ct and condition_add](#hardcode_ct) - * [hardcode_no_ct and condition_add](#hardcode_no_ct) - * [condition_add involving target domain](#condition_add_tar) - * [condition_add involving raw dataset and target domain](#condition_add_raw_tar) -* [Repeat Map Topic and Map Rest](#repeatsteps) - -Repeat the above steps for different raw datasets before proceeding with the below steps. - -* [Create SDTM derived variables](#derivedvars) -* [Add Labels and Attributes](#attributes) - -## Read in data {#readdata} - -Read all the raw datasets into the environment. In this example, the raw dataset name is `cm_raw`. Users can read it from the package using the below code: - -```{r eval=FALSE} -cm_raw <- read.csv(system.file("cm_domain/cm_raw_data.csv", - package = "sdtm.oak")) - -dm <- read.csv(system.file("cm_domain/dm.csv", - package = "sdtm.oak")) -``` - -## Create oak_id_vars {#oakidvars} - -The `oak_id_vars` is a crucial link between the raw datasets and the mapped SDTM domain. As the user derives each SDTM variable, it is merged with the corresponding topic variable using `oak_id_vars`. In {sdtm.oak}, the variables oak_id, raw_source, and patient_number are considered as `oak_id_vars`. These three variables must be added to all raw datasets. They are used in multiple places in the programming. - -oak_id:- Type: numeric- Value: equal to the raw dataframe row number. - -raw_source:- Type: Character- Value: equal to the raw dataset (eCRF) name or eDT dataset name. - -patient_number:- Type: numeric- Value: equal to the subject number in CRF or NonCRF data source. - -```{r eval=TRUE} -cm_raw <- cm_raw %>% - generate_oak_id_vars(pat_var = "PATNUM", - raw_src = "cm_raw") -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm_raw, - display_vars = exprs( - oak_id, raw_source, patient_number, PATNUM, FORML, MDNUM, MDRAW - ) -) -``` - -Read in the DM domain - -```{r eval=TRUE} -dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) -``` - - -## Read in CT {#readct} - -Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `sdtm_ct.csv`. Users can read it from the package using the below code: - -```{r eval=FALSE} -study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", - package = "sdtm.oak")) -``` - -```{r eval=TRUE} -study_ct <- as_tibble(read.csv("sdtm_ct.csv", stringsAsFactors = FALSE)) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - study_ct, - display_vars = exprs( - codelist_code, term_code, term_value, collected_value, term_preferred_term, - term_synonyms - ) -) -``` - -## Map Topic Variable {#maptopic} - -The topic variable is mapped as a first step in the mapping process. It is the primary variable in the SDTM domain. The rest of the variables add further definition to the topic variable. In this example, the topic variable is `CMTRT`. It is mapped from the raw dataset column `MDRAW`. The mapping logic is `Map the collected value in the cm_raw dataset MDRAW variable to CM.CMTRT`. - -This mapping does not involve any controlled terminology. The `assign_no_ct` function is used for mapping. Once the topic variable is mapped, the Qualifier, Identifier, and Timing variables can be mapped. - -```{r eval=TRUE} -cm <- - # Map topic variable - assign_no_ct( - raw_dat = cm_raw, - raw_var = "MDRAW", - tgt_var = "CMTRT" - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT - ) -) -``` -## Map Rest of the Variables {#maprest} - -The Qualifiers, Identifiers, and Timing Variables can be mapped in any order. In this example, we will map each variable one by one to demonstrate different mapping algorithms. - -### assign_no_ct {#assign_no_ct} - -The mapping logic for `CMGRPID` is `Map the collected value in the cm_raw dataset MDNUM variable to CM.CMGRPID`. - - -```{r eval=TRUE} -cm <- cm %>% - # Map CMGRPID - assign_no_ct( - raw_dat = cm_raw, - raw_var = "MDNUM", - tgt_var = "CMGRPID", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID - ) -) -``` - -The CMGRPID is added to the corresponding CMTRT based on the 'oak_id_vars'. When calling the function, the parameter 'id_vars = oak_id_vars()' matches the raw dataset 'oak_id_vars' to the 'oak_id_vars' in the cm domain created in the previous step. It's important to note that the 'oak_id_vars' can be extended to include user-defined variables. But in most cases, the three variables should suffice. - -### assign_ct {#assign_ct} - -The mapping logic for `CMDOSU` is `Map the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU`. The controlled terminology is used to map the collected value to the standard value. `assign_ct` is the right algorithm to perform this mapping. - -```{r eval=TRUE} -cm <- cm %>% - # Map qualifier CMDOSU - assign_ct( - raw_dat = cm_raw, - raw_var = "DOSU", - tgt_var = "CMDOSU", - ct_spec = study_ct, - ct_clst = "C71620", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU - ) -) -``` - -### assign_datetime {#assign_datetime} - -The mapping logic for `CMSTDTC` is `Map the collected value in the cm_raw dataset MDBDR (start date) variable and MDBTM (start time) to CM.CMSTDTC`. The collected date value is in the format 'dd mmm yyyy'. The collected time value is in 'H"M' format. The `assign_datetime` function is used to map the collected value in ISO8601 format. - -```{r eval=TRUE} -cm <- cm %>% -# Map CMSTDTC. This function calls create_iso8601 - assign_datetime( - raw_dat = cm_raw, - raw_var = c("MDBDR", "MDBTM"), - tgt_var = "CMSTDTC", - raw_fmt = c(list(c("d-m-y", "dd mmm yyyy")), "H:M"), - raw_unk = c("UN", "UNK"), - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC - ) -) -``` - -### hardcode_ct and condition_add {#hardcode_ct} - -The mapping logic for `CMSTRTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTRTPT == 'BEFORE'.` The `hardcode_ct` function is used to map the CMSTRTPT as it involves hardcoding a specific value to an SDTM variable with controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_ct` function performs the mapping. - -When these two functions are used together, the `condition_add` function first filters the raw dataset based on the specified condition. Next, the filtered dataset is then passed to the `hardcode_ct` function to assign the appropriate value. This example illustrates how the `hardcode_ct` algorithm functions as a sub-algorithm to `condition_add`. - -```{r eval=TRUE} -cm <- cm %>% - # Map qualifier CMSTRTPT Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE' - hardcode_ct( - raw_dat = condition_add(cm_raw, MDPRIOR == "1"), - raw_var = "MDPRIOR", - tgt_var = "CMSTRTPT", - tgt_val = "BEFORE", - ct_spec = study_ct, - ct_clst = "C66728", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT - ) -) -``` - -The `condition_add` function adds additional metadata to the records in the raw dataset that meets the condition. Refer to the function documentation for more details. `hardcode_ct` function uses the addtional metadata to find the records that meet the criteria and map them accordingly. - -### hardcode_no_ct and condition_add {#hardcode_no_ct} - -The mapping logic for `CMSTTPT` is as follows: `If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTTPT == 'SCREENING'.` The `hardcode_no_ct` function is used to map the CMSTTPT as it involves hardcoding a specific value to an SDTM variable without controlled terminology. The `condition_add` function filters the raw dataset based on a particular condition, and the `hardcode_no_ct` function performs the mapping. - -```{r eval=TRUE} -cm <- cm %>% - # Map qualifier CMSTTPT Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING' - hardcode_no_ct( - raw_dat = condition_add(cm_raw, MDPRIOR == "1"), - raw_var = "MDPRIOR", - tgt_var = "CMSTTPT", - tgt_val = "SCREENING", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT - ) -) -``` - -### condition_add involving target domain {#condition_add_tar} - -In the mapping for `CMSTRTPT` and `CMSTTTPT`, the `condition_add` function is used in the raw dataset. In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. - -The mapping logic for `CMDOSFRQ` is `If CMTRT is not null, then map the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ.` This may or may not represent a valid SDTM mapping in an actual study, but it can be used as an example. - -In this mapping, the `condition_add` function filters the cm domain created in the previous step and adds metadata to the records where it meets the condition. The `assign_ct` function uses the additional metadata to find the records that meet the criteria and map them accordingly. - -```{r eval=TRUE} -cm <- cm %>% - # Map qualifier CMDOSFRQ Annotation text is If CMTRT is not null then map the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ - {assign_ct( - raw_dat = cm_raw, - raw_var = "MDFRQ", - tgt_dat = condition_add(. , !is.na(CMTRT)), - tgt_var = "CMDOSFRQ", - ct_spec = study_ct, - ct_clst = "C66728", - id_vars = oak_id_vars() - )} -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ - ) -) -``` - -Remember to use additional curly braces in the function call when using the `condition_add` function on the target dataset. This is necessary because the input target dataset is represented as a `.` and is passed on from the previous step using the {magrittr} pipe operator. Currently, there is a limitation when using a nested function call with `.` to reference one of the input parameters, and this [recommended approach](https://magrittr.tidyverse.org/reference/pipe.html#using-the-dot-for-secondary-purposes) will overcome that. - -The placeholder `.` is for use with {magrittr} pipe `%>%` operator. We encourage using `.` and {magrittr} pipe `%>%` operator when using {sdtm.oak} functions. - -Another way to achieve the same outcome is by moving the 'condition_by' call up one level, as illustrated below: it is not required to use the {magrittr} pipe `%>%` or curly braces in this case. - -```{r eval=FALSE} -cm <- cm %>% - condition_add(!is.na(CMTRT)) %>% - assign_ct( - raw_dat = cm_raw, - raw_var = "DOSU", - tgt_var = "CMDOSU", - ct_spec = study_ct, - ct_clst = "C71620", - id_vars = oak_id_vars() - ) -``` - -### condition_add involving raw dataset and target domain {#condition_add_raw_tar} - -In this mapping, we can explore how to use `condition_add` to add a filter condition based on the target SDTM variable. - -The mapping logic for `CMMODIFY` is `If collected value in MODIFY in cm_raw is different to CM.CMTRT then assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY)`. The `assign_no_ct` function is used to map the CMMODIFY as it involves mapping the collected value to the SDTM variable without controlled terminology. The `condition_add` function filters the raw dataset & target dataset based on a particular condition, and the `assign_no_ct` function performs the mapping. - -```{r eval=TRUE} -cm <- cm %>% - # Map CMMODIFY Annotation text If collected value in MODIFY in cm_raw is different to CM.CMTRT then assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY) - {assign_no_ct( - raw_dat = cm_raw, - raw_var = "MODIFY", - tgt_dat = condition_add(. , MODIFY != CMTRT, .dat2 = cm_raw), - tgt_var = "CMMODIFY", - id_vars = oak_id_vars() - )} -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY - ) -) -``` - -Another way to achieve the same outcome is by moving the 'condition_by' call up one level, as illustrated below: it is not required to use the {magrittr} pipe `%>%` or curly braces in this case. - -```{r eval=FALSE} -cm <- cm %>% - condition_add(MODIFY != CMTRT, .dat2 = cm_raw) %>% - assign_no_ct( - raw_dat = cm_raw, - raw_var = "MODIFY", - tgt_var = "CMMODIFY", - id_vars = oak_id_vars() - ) -``` - -Now, complete mapping the rest of the SDTM variables. - -```{r eval=TRUE} -cm <- cm %>% - # Map CMINDC as the collected value in MDIND to CM.CMINDC - assign_no_ct( - raw_dat = cm_raw, - raw_var = "MDIND", - tgt_var = "CMINDC", - id_vars = oak_id_vars() - ) %>% - # Map CMENDTC as the collected value in MDEDR and MDETM to CM.CMENDTC. - # This function calls create_iso8601 - assign_datetime( - raw_dat = cm_raw, - raw_var = c("MDEDR", "MDETM"), - tgt_var = "CMENDTC", - raw_fmt = c("d-m-y", "H:M"), - raw_unk = c("UN", "UNK") - ) %>% - # Map qualifier CMENRTPT as If MDONG == 1 then CM.CMENRTPT = 'ONGOING' - hardcode_ct( - raw_dat = condition_add(cm_raw, MDONG == "1"), - raw_var = "MDONG", - tgt_var = "CMENRTPT", - tgt_val = "ONGOING", - ct_spec = study_ct, - ct_clst = "C66728", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMENTPT as If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT' - hardcode_no_ct( - raw_dat = condition_add(cm_raw, MDONG == "1"), - raw_var = "MDONG", - tgt_var = "CMENTPT", - tgt_val = "DATE OF LAST ASSESSMENT", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMDOS as If collected value in raw_var DOS is numeric then CM.CMDOSE - assign_no_ct( - raw_dat = condition_add(cm_raw, is.numeric(DOS)), - raw_var = "DOS", - tgt_var = "CMDOS", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMDOS as If collected value in raw_var DOS is character then CM.CMDOSTXT - assign_no_ct( - raw_dat = condition_add(cm_raw, is.character(DOS)), - raw_var = "DOS", - tgt_var = "CMDOSTXT", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMDOSU as the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU - assign_ct( - raw_dat = cm_raw, - raw_var = "DOSU", - tgt_var = "CMDOSU", - ct_spec = study_ct, - ct_clst = "C71620", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMDOSFRM as the collected value in the cm_raw dataset MDFORM variable to CM.CMDOSFRM - assign_ct( - raw_dat = cm_raw, - raw_var = "MDFORM", - tgt_var = "CMDOSFRM", - ct_spec = study_ct, - ct_clst = "C66726", - id_vars = oak_id_vars() - ) %>% - # Map CMROUTE as the collected value in the cm_raw dataset MDRTE variable to CM.CMROUTE - assign_ct( - raw_dat = cm_raw, - raw_var = "MDRTE", - tgt_var = "CMROUTE", - ct_spec = study_ct, - ct_clst = "C66729", - id_vars = oak_id_vars() - ) %>% - # Map qualifier CMPROPH as If MDPROPH == 1 then CM.CMPROPH = 'Y' - hardcode_ct( - raw_dat = condition_add(cm_raw, MDPROPH == "1"), - raw_var = "MDPROPH", - tgt_var = "CMPROPH", - tgt_val = "Y", - ct_spec = study_ct, - ct_clst = "C66742", - id_vars = oak_id_vars() - ) %>% - # Map CMDRG as the collected value in the cm_raw dataset CMDRG variable to CM.CMDRG - assign_no_ct( - raw_dat = cm_raw, - raw_var = "CMDRG", - tgt_var = "CMDRG", - id_vars = oak_id_vars() - ) %>% - # Map CMDRGCD as the collected value in the cm_raw dataset CMDRGCD variable to CM.CMDRGCD - assign_no_ct( - raw_dat = cm_raw, - raw_var = "CMDRGCD", - tgt_var = "CMDRGCD", - id_vars = oak_id_vars() - ) %>% - # Map CMDECOD as the collected value in the cm_raw dataset CMDECOD variable to CM.CMDECOD - assign_no_ct( - raw_dat = cm_raw, - raw_var = "CMDECOD", - tgt_var = "CMDECOD", - id_vars = oak_id_vars() - ) %>% - # Map CMPNCD as the collected value in the cm_raw dataset CMPNCD variable to CM.CMPNCD - assign_no_ct( - raw_dat = cm_raw, - raw_var = "CMPNCD", - tgt_var = "CMPNCD", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, CMTRT, CMGRPID, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY, CMINDC, CMENDTC, CMENRTPT, CMENTPT, CMDOS, CMDOSTXT, CMDOSU, CMDOSFRM, CMROUTE, CMPROPH, CMDRG, CMDRGCD, CMDECOD, CMPNCD - ) -) -``` - -## Repeat Map Topic and Map Rest {#repeatsteps} - -There is only one topic variable in this raw data source, and there are no additional topic variable mappings. Users can proceed to the next step. This is required only if there is more than one topic variable to map. - -## Create SDTM derived variables {#derivedvars} - -The SDTM derived variables or any SDTM mapping that is applicable to all the records in the `cm` dataset produced in the previous step cam be created now. In this example, we will create the `CMSEQ` variable. The mapping logic is `Create a sequence number for each record in the CM domain`. - -```{r eval=TRUE} - cm <- cm %>% - # The below mappings are applicable to all the records in the cm domain, - # hence can be derived using mutate statement. - dplyr::mutate( - STUDYID = "test_study", - DOMAIN = "CM", - CMCAT = "GENERAL CONMED", - USUBJID = paste0("test_study", "-", cm_raw$PATNUM) - ) %>% - # derive sequence number - # derive_seq(tgt_var = "CMSEQ", - # rec_vars= c("USUBJID", "CMGRPID")) %>% - derive_study_day( - sdtm_in = ., - dm_domain = dm, - tgdt = "CMENDTC", - refdt = "RFXSTDTC", - study_day_var = "CMENDY" - ) %>% - derive_study_day( - sdtm_in = ., - dm_domain = dm, - tgdt = "CMSTDTC", - refdt = "RFXSTDTC", - study_day_var = "CMSTDY" - ) %>% - # Add code for derive Baseline flag. - dplyr::select("STUDYID", "DOMAIN" , "USUBJID", everything()) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - cm, - display_vars = exprs( - oak_id, raw_source, patient_number, STUDYID, DOMAIN, USUBJID, CMGRPID, CMTRT, CMDOSU, CMSTDTC, CMSTRTPT, CMSTTPT, CMDOSFRQ, CMMODIFY, CMINDC, CMENDTC, CMENRTPT, CMENTPT, CMDOS, CMDOSTXT, CMDOSU, CMDOSFRM, CMROUTE, CMPROPH, CMDRG, CMDRGCD, CMDECOD, CMPNCD, CMSTDY, CMENDY - ) -) -``` - - -## Add Labels and Attributes {#attributes} - -Yet to be developed. diff --git a/vignettes/articles/findings_domain.Rmd b/vignettes/articles/findings_domain.Rmd deleted file mode 100644 index bf9ed5ae..00000000 --- a/vignettes/articles/findings_domain.Rmd +++ /dev/null @@ -1,564 +0,0 @@ ---- -title: "Creating an Findings SDTM domain" -output: - rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Creating an Findings SDTM domain} - %\VignetteEncoding{UTF-8} - %\VignetteEngine{knitr::rmarkdown} ---- - -```{r setup, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) - -#library(sdtm.oak) -library(admiraldev) -library(rlang) -library(dplyr, warn.conflicts = FALSE) -``` - -```{r, include=FALSE} -devtools::load_all(".") -``` -# Introduction - -This article describes how to create a Findings SDTM domain using the {sdtm.oak} package. Examples are currently presented and tested in the context of the VS domain. - -Before reading this article, it is recommended that users review the "Creating an Events Domain" article, which provides a detailed explanation of various concepts in {sdtm.oak}, such as `oak_id_vars`, `condition_add`, etc. It also offers guidance on which mapping algorithms or functions to use for different mappings and provides a more detailed explanation of how these mapping algorithms or functions work. - -In this article, we will dive directly into programming and provide further explanation only where it is required. - -# Programming workflow - -In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (example Concomitant medications (OID - cm_raw), Targeted Concomitant Medications (OID - cm_t_raw)) can be stacked together before processing. - -* [Read in data](#readdata) -* [Create oak_id_vars](#oakidvars) -* [Read in CT](#readct) -* [Map Topic Variable](#maptopic) -* [Map Rest of the Variables](#maprest) -* [Repeat Map Topic and Map Rest](#repeatsteps) - -Repeat the above steps for different raw datasets before proceeding with the below steps. - -* [Create SDTM derived variables](#derivedvars) -* [Add Labels and Attributes](#attributes) - -## Read in data {#readdata} - -Read all the raw datasets into the environment. In this example, the raw dataset name is `cm_raw`. Users can read it from the package using the below code: - -```{r eval=FALSE} -vs_raw <- read.csv(system.file("cm_domain/vitals_raw_data.csv", - package = "sdtm.oak")) - -dm <- read.csv(system.file("cm_domain/dm.csv", - package = "sdtm.oak")) -``` - -```{r eval=TRUE, echo=FALSE} -vs_raw <- as_tibble(read.csv("vitals_raw_data.csv", stringsAsFactors = FALSE)) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs_raw, - display_vars = exprs( - PATNUM, FORML, ASMNTDN, TMPTC, VTLD, VTLTM, SUBPOS, SYS_BP, DIA_BP, - PULSE, RESPRT, TEMP, TEMPLOC, OXY_SAT, LAT, LOC - ) -) -``` - -## Create oak_id_vars {#oakidvars} - -```{r eval=TRUE} -vs_raw <- vs_raw %>% - generate_oak_id_vars(pat_var = "PATNUM", - raw_src = "vitals") -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs_raw, - display_vars = exprs( - oak_id, raw_source, patient_number, PATNUM, FORML, SYS_BP, DIA_BP - ) -) -``` - -Read in the DM domain - -```{r eval=TRUE, echo=FALSE} -dm <- as_tibble(read.csv("dm.csv", stringsAsFactors = FALSE)) -``` - - -## Read in CT {#readct} - -Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is `sdtm_ct.csv`. Users can read it from the package using the below code: - -```{r eval=FALSE} -study_ct <- read.csv(system.file("cm_domain/sdtm_ct.csv", - package = "sdtm.oak")) -``` - -```{r eval=TRUE, echo=FALSE} -study_ct <- as_tibble(read.csv("sdtm_ct.csv", stringsAsFactors = FALSE)) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - study_ct, - display_vars = exprs( - codelist_code, term_code, term_value, collected_value, term_preferred_term, - term_synonyms - ) -) -``` - -## Map Topic Variable {#maptopic} - -This raw dataset has multiple topic variables. Lets start with the first topic variable. Map topic variable SYSBP from the raw variable SYS_BP. - -```{r eval=TRUE} -# Map topic variable SYSBP and its qualifiers. -vs_sysbp <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "SYS_BP", - tgt_var = "VSTESTCD", - tgt_val = "SYSBP", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - # Filter for records where VSTESTCD is not empty. - # Only these records need qualifier mappings. - dplyr::filter(!is.na(.data$VSTESTCD)) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs_sysbp, - display_vars = exprs( - oak_id, raw_source, patient_number, VSTESTCD - ) -) -``` - -## Map Rest of the Variables {#maprest} - -Map rest of the variables applicable to the topic variable SYSBP. This can include qualifiers, identifier and timing variables. - -```{r eval=TRUE} -# Map topic variable SYSBP and its qualifiers. -vs_sysbp <- vs_sysbp %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "SYS_BP", - tgt_var = "VSTEST", - tgt_val = "Systolic Blood Pressure", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "SYS_BP", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "SYS_BP", - tgt_var = "VSORRESU", - tgt_val = "mmHg", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) %>% - # Map VSPOS using assign_ct algorithm - assign_ct( - raw_dat = vs_raw, - raw_var = "SUBPOS", - tgt_var = "VSPOS", - ct_spec = study_ct, - ct_clst = "C71148", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs_sysbp, - display_vars = exprs( - oak_id, raw_source, patient_number, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS - ) -) -``` - -## Repeat Map Topic and Map Rest {#repeatsteps} - -This raw data source has other topic variables DIABP, PULSE, RESP, TEMP, OXYSAT, VSALL and its corresponding qualifiers. Repeat mapping topic and qualifiers for each topic variable. - -```{r eval=TRUE} -# Map topic variable DIABP and its qualifiers. -vs_diabp <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "DIA_BP", - tgt_var = "VSTESTCD", - tgt_val = "DIABP", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "DIA_BP", - tgt_var = "VSTEST", - tgt_val = "Diastolic Blood Pressure", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "DIA_BP", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "DIA_BP", - tgt_var = "VSORRESU", - tgt_val = "mmHg", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) %>% - # Map VSPOS using assign_ct algorithm - assign_ct( - raw_dat = vs_raw, - raw_var = "SUBPOS", - tgt_var = "VSPOS", - ct_spec = study_ct, - ct_clst = "C71148", - id_vars = oak_id_vars() - ) - -# Map topic variable PULSE and its qualifiers. -vs_pulse <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "PULSE", - tgt_var = "VSTESTCD", - tgt_val = "PULSE", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "PULSE", - tgt_var = "VSTEST", - tgt_val = "Pulse Rate", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "PULSE", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "PULSE", - tgt_var = "VSORRESU", - tgt_val = "beats/min", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) - -# Map topic variable RESP from the raw variable RESPRT and its qualifiers. -vs_resp <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "RESPRT", - tgt_var = "VSTESTCD", - tgt_val = "RESP", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "RESPRT", - tgt_var = "VSTEST", - tgt_val = "Respiratory Rate", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "RESPRT", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "RESPRT", - tgt_var = "VSORRESU", - tgt_val = "breaths/min", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) - -# Map topic variable TEMP from raw variable TEMP and its qualifiers. -vs_temp <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "TEMP", - tgt_var = "VSTESTCD", - tgt_val = "TEMP", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "TEMP", - tgt_var = "VSTEST", - tgt_val = "Temperature", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "TEMP", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "TEMP", - tgt_var = "VSORRESU", - tgt_val = "C", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) %>% - # Map VSLOC from TEMPLOC using assign_ct - assign_ct( - raw_dat = vs_raw, - raw_var = "TEMPLOC", - tgt_var = "VSLOC", - ct_spec = study_ct, - ct_clst = "C74456", - id_vars = oak_id_vars() - ) - -# Map topic variable OXYSAT from raw variable OXY_SAT and its qualifiers. -vs_oxysat <- - hardcode_ct( - raw_dat = vs_raw, - raw_var = "OXY_SAT", - tgt_var = "VSTESTCD", - tgt_val = "OXYSAT", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "OXY_SAT", - tgt_var = "VSTEST", - tgt_val = "Oxygen Saturation", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) %>% - # Map VSORRES using assign_no_ct algorithm - assign_no_ct( - raw_dat = vs_raw, - raw_var = "OXY_SAT", - tgt_var = "VSORRES", - id_vars = oak_id_vars() - ) %>% - # Map VSORRESU using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "OXY_SAT", - tgt_var = "VSORRESU", - tgt_val = "%", - ct_spec = study_ct, - ct_clst = "C66770", - id_vars = oak_id_vars() - ) %>% - # Map VSLAT using assign_ct from raw variable LAT - assign_ct( - raw_dat = vs_raw, - raw_var = "LAT", - tgt_var = "VSLAT", - ct_spec = study_ct, - ct_clst = "C99073", - id_vars = oak_id_vars() - ) %>% - # Map VSLOC using assign_ct from raw variable LOC - assign_ct( - raw_dat = vs_raw, - raw_var = "LOC", - tgt_var = "VSLOC", - ct_spec = study_ct, - ct_clst = "C74456", - id_vars = oak_id_vars() - ) - -# Map topic variable VSALL from raw variable ASMNTDN with the logic if ASMNTDN == 1 then VSTESTCD = VSALL -vs_vsall <- - hardcode_ct( - raw_dat = condition_add(vs_raw, ASMNTDN == 1), - raw_var = "ASMNTDN", - tgt_var = "VSTESTCD", - tgt_val = "VSALL", - ct_spec = study_ct, - ct_clst = "C66741" - ) %>% - dplyr::filter(!is.na(.data$VSTESTCD)) %>% - # Map VSTEST using hardcode_ct algorithm - hardcode_ct( - raw_dat = vs_raw, - raw_var = "ASMNTDN", - tgt_var = "VSTEST", - tgt_val = "Vital Signs", - ct_spec = study_ct, - ct_clst = "C67153", - id_vars = oak_id_vars() - ) -``` - -Now that all the topic variable and its qualifier mappings are complete, combine all the datasets and proceed with mapping qualifiers, identifiers and timing variables appicable to all topic variables. - -```{r, eval=TRUE} -# Combine all the topic variables into a single data frame and map qualifiers -# applicable to all topic variables -vs <- dplyr::bind_rows(vs_vsall, vs_sysbp, vs_diabp, vs_pulse, vs_resp, - vs_temp, vs_oxysat) %>% - # Map qualifiers common to all topic variables - # Map VSDTC using assign_ct algorithm - assign_datetime( - raw_dat = vs_raw, - raw_var = c("VTLD", "VTLTM"), - tgt_var = "VSDTC", - raw_fmt = c(list(c("d-m-y", "dd-mmm-yyyy")), "H:M") - ) %>% - # Map VSTPT from TMPTC using assign_ct - assign_ct( - raw_dat = vs_raw, - raw_var = "TMPTC", - tgt_var = "VSTPT", - ct_spec = study_ct, - ct_clst = "TPT", - id_vars = oak_id_vars() - ) %>% - # Map VSTPTNUM from TMPTC using assign_ct - assign_ct( - raw_dat = vs_raw, - raw_var = "TMPTC", - tgt_var = "VSTPTNUM", - ct_spec = study_ct, - ct_clst = "TPTNUM", - id_vars = oak_id_vars() - ) %>% - # Map VISIT from INSTANCE using assign_ct - assign_ct( - raw_dat = vs_raw, - raw_var = "INSTANCE", - tgt_var = "VISIT", - ct_spec = study_ct, - ct_clst = "VISIT", - id_vars = oak_id_vars() - ) %>% - # Map VISITNUM from INSTANCE using assign_ct - assign_ct( - raw_dat = vs_raw, - raw_var = "INSTANCE", - tgt_var = "VISITNUM", - ct_spec = study_ct, - ct_clst = "VISITNUM", - id_vars = oak_id_vars() - ) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs, - display_vars = exprs( - oak_id, raw_source, patient_number, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS, - VSLAT, VSDTC, VSTPT, VSTPTNUM, VISIT, VISITNUM - ) -) -``` - -## Create SDTM derived variables {#derivedvars} - -Create derived variables applicable to all topic variables. - -```{r eval=TRUE} -vs <- vs %>% - dplyr::mutate( - STUDYID = "test_study", - DOMAIN = "VS", - VSCAT = "VITAL SIGNS", - USUBJID = paste0("test_study", "-", .data$patient_number) - ) %>% - # derive_seq(tgt_var = "VSSEQ", - # rec_vars= c("USUBJID", "CMTRT")) %>% - derive_study_day( - sdtm_in = ., - dm_domain = dm, - tgdt = "VSDTC", - refdt = "RFXSTDTC", - study_day_var = "VSDY" - ) %>% - dplyr::select("STUDYID", "DOMAIN", "USUBJID", everything()) -``` - -```{r, eval=TRUE, echo=FALSE} -dataset_oak_vignette( - vs, - display_vars = exprs( - STUDYID, DOMAIN, USUBJID, VSTESTCD, VSTEST, VSORRES, VSORRESU, VSPOS, - VSLAT, VSTPT, VSTPTNUM, VISIT, VISITNUM, VSDTC, VSDY - ) -) -``` - -## Add Labels and Attributes {#attributes} - -Yet to be devleoped. diff --git a/vignettes/articles/iso_8601.Rmd b/vignettes/articles/iso_8601.Rmd deleted file mode 100644 index 222e5d01..00000000 --- a/vignettes/articles/iso_8601.Rmd +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: "Converting dates, times or date-times to ISO 8601" ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -library(sdtm.oak) -``` - -An SDTM DTC variable may include data that is represented in [ISO -8601](https://en.wikipedia.org/wiki/ISO_8601) format as a complete date/time, a -partial date/time, or an incomplete date/time. `{sdtm.oak}` provides the -`create_iso8601()` function that allows flexible mapping of date and time -values in various formats to a single date-time ISO 8601 format. - -## Introduction - -To perform conversion to the ISO 8601 format you need to pass two key arguments: - -- At least one vector of dates, times, or date-times of `character` type; -- A date/time format via the `.format` parameter that instructs `create_iso8601()` on which date/time components to expect. - -```{r} -create_iso8601("2000 01 05", .format = "y m d") -create_iso8601("22:35:05", .format = "H:M:S") -``` - -By default the `.format` parameter understands a few reserved characters: - -- `"y"` for year -- `"m"` for month -- `"d"` for day -- `"H"` for hours -- `"M"` for minutes -- `"S"` for seconds - -Besides character vectors of dates and times, you may also pass a single vector -of date-times, provided you adjust the format: - -```{r} -create_iso8601("2000-01-05 22:35:05", .format = "y-m-d H:M:S") -``` - -## Multiple inputs - -If you have dates and times in separate vectors then you will need to pass -a format for each vector: - -```{r} -create_iso8601("2000-01-05", "22:35:05", .format = c("y-m-d", "H:M:S")) -``` - -In addition, like most R functions that take vectors as input, -`create_iso8601()` is vectorized: - -```{r} -date <- c("2000-01-05", "2001-12-25", "1980-06-18", "1979-09-07") -time <- c("00:12:21", "22:35:05", "03:00:15", "07:09:00") -create_iso8601(date, time, .format = c("y-m-d", "H:M:S")) -``` - -But the number of elements in each of the inputs has to match or you will get an -error: - -```{r} -date <- c("2000-01-05", "2001-12-25", "1980-06-18", "1979-09-07") -time <- "00:12:21" -try(create_iso8601(date, time, .format = c("y-m-d", "H:M:S"))) -``` - -You can combine individual date and time components coming -in as separate inputs; here is a contrived example of year, month and day -together, hour, and minute: - -```{r} -year <- c("99", "84", "00", "80", "79", "1944", "1953") -month_and_day <- c("jan 1", "apr 04", "mar 06", "jun 18", "sep 07", "sep 13", "sep 14") -hour <- c("12", "13", "05", "23", "16", "16", "19") -min <- c("0", "60", "59", "42", "44", "10", "13") -create_iso8601(year, month_and_day, hour, min, .format = c("y", "m d", "H", "M")) -``` - -The `.format` argument must be always named; otherwise, it will be treated as if -it were one of the inputs and interpreted as missing. - -```{r} -try(create_iso8601("2000-01-05", "y-m-d")) -``` - - -## Format variations - -The `.format` parameter can easily accommodate variations in the format of the -inputs: - -```{r} -create_iso8601("2000-01-05", .format = "y-m-d") -create_iso8601("2000 01 05", .format = "y m d") -create_iso8601("2000/01/05", .format = "y/m/d") -``` - -Individual components may come in a different order, so adjust the format -accordingly: - -```{r} -create_iso8601("2000 01 05", .format = "y m d") -create_iso8601("05 01 2000", .format = "d m y") -create_iso8601("01 05, 2000", .format = "m d, y") -``` - -All other individual characters given in the format are taken strictly, e.g. -the number of spaces matters: - -```{r} -date <- c("2000 01 05", "2000 01 05", "2000 01 05", "2000 01 05") -create_iso8601(date, .format = "y m d") -create_iso8601(date, .format = "y m d") -create_iso8601(date, .format = "y m d") -create_iso8601(date, .format = "y m d") -``` - -The format can include regular expressions though: - -```{r} -create_iso8601(date, .format = "y\\s+m\\s+d") -``` - -By default, a streak of the reserved characters is treated as if only one was -provided, so these formats are equivalent: - -```{r} -date <- c("2000-01-05", "2001-12-25", "1980-06-18", "1979-09-07") -time <- c("00:12:21", "22:35:05", "03:00:15", "07:09:00") -create_iso8601(date, time, .format = c("y-m-d", "H:M:S")) -create_iso8601(date, time, .format = c("yyyy-mm-dd", "HH:MM:SS")) -create_iso8601(date, time, .format = c("yyyyyyyy-m-dddddd", "H:MMMMM:SSSS")) -``` - -## Multiple alternative formats - -When an input vector contains values with varying formats, a single format may -not be adequate to encompass all variations. In such situations, it's advisable -to list multiple alternative formats. This approach ensures that each format is -tried sequentially until one matches the data in the vector. - -```{r} -date <- c("2000/01/01", "2000-01-02", "2000 01 03", "2000/01/04") -create_iso8601(date, .format = "y-m-d") -create_iso8601(date, .format = "y m d") -create_iso8601(date, .format = "y/m/d") -create_iso8601(date, .format = list(c("y-m-d", "y m d", "y/m/d"))) -``` - -Consider the order in which you supply the formats, as it can be significant. If -multiple formats could potentially match, the sequence determines which format -is applied first. - -```{r} -create_iso8601("07 04 2000", .format = list(c("d m y", "m d y"))) -create_iso8601("07 04 2000", .format = list(c("m d y", "d m y"))) -``` - -Note that if you are passing alternative formats, then the `.format` argument -must be a list whose length matches the number of inputs. - -## Parsing of date or time components - -By default, date or time components are parsed as follows: - -- year: either parsed from a two- or four-digit year; -- month: either as a numeric month (single or two-digit number) or as an English abbreviated month name (e.g. Jan, Jun or Dec) regardless of case; -- month day: are parsed from two-digit numbers; -- hour and minute: are parsed from single or two-digit numbers; -- second: is parsed from single or two-digit numbers with an optional fractional part. - -```{r} -# Years: two-digit or four-digit numbers. -years <- c("0", "1", "00", "01", "15", "30", "50", "68", "69", "80", "99") -create_iso8601(years, .format = "y") - -# Adjust the point where two-digits years are mapped to 2000's or 1900's. -create_iso8601(years, .format = "y", .cutoff_2000 = 20L) - -# Both numeric months (two-digit only) and abbreviated months work out of the box -months <- c("0", "00", "1", "01", "Jan", "jan") -create_iso8601(months, .format = "m") - -# Month days: single or two-digit numbers, anything else results in NA. -create_iso8601(c("1", "01", "001", "10", "20", "31"), .format = "d") - -# Hours -create_iso8601(c("1", "01", "001", "10", "20", "31"), .format = "H") - -# Minutes -create_iso8601(c("1", "01", "001", "10", "20", "60"), .format = "M") - -# Seconds -create_iso8601(c("1", "01", "23.04", "001", "10", "20", "60"), .format = "S") -``` - -## Allowing alternative date or time values - -If date or time component values include special values, e.g. values -encoding missing values, then you can indicate those values as possible -alternatives such that the parsing will tolerate them; use the `.na` argument: - -```{r} -create_iso8601("U DEC 2019 14:00", .format = "d m y H:M") -create_iso8601("U DEC 2019 14:00", .format = "d m y H:M", .na = "U") - -create_iso8601("U UNK 2019 14:00", .format = "d m y H:M") -create_iso8601("U UNK 2019 14:00", .format = "d m y H:M", .na = c("U", "UNK")) -``` - -In this case you could achieve the same result using regexps: - -```{r} -create_iso8601("U UNK 2019 14:00", .format = "(d|U) (m|UNK) y H:M") -``` - - -## Changing reserved format characters - -There might be cases when the reserved characters --- `"y"`, `"m"`, `"d"`, -`"H"`, `"M"`, `"S"` --- might get in the way of specifying an adequate format. -For example, you might be tempted to use format `"HHMM"` to try to parse a time -such as `"14H00M"`. You could assume that the first "H" codes for parsing the -hour, and the second "H" to be a literal "H" but, actually, `"HH"` will be taken -to mean parsing hours, and `"MM"` to parse minutes. You can use the function -`fmt_cmp()` to specify alternative format regexps for the format, replacing the -default characters. - -In the next example, we reassign new format strings for the hour and minute -components, thus freeing the `"H"` and `"M"` patterns from being interpreted as -hours and minutes, and to be taken literally: - -```{r} -create_iso8601("14H00M", .format = "HHMM") -create_iso8601("14H00M", .format = "xHwM", .fmt_c = fmt_cmp(hour = "x", min = "w")) -``` -Note that you need to make sure that the format component regexps are mutually -exclusive, i.e. they don't have overlapping matches; otherwise -`create_iso8601()` will fail with an error. In the next example both months and -minutes could be represented by an `"m"` in the format resulting in an ambiguous -format specification. - -```{r} -fmt_cmp(hour = "h", min = "m") -try(create_iso8601("14H00M", .format = "hHmM", .fmt_c = fmt_cmp(hour = "h", min = "m"))) -``` - diff --git a/vignettes/articles/just-dm.Rmd b/vignettes/articles/just-dm.Rmd new file mode 100644 index 00000000..9c57e6bf --- /dev/null +++ b/vignettes/articles/just-dm.Rmd @@ -0,0 +1,24 @@ +--- +title: "Just read csv" +output: + rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Just read csv} + %\VignetteEncoding{UTF-8} + %\VignetteEngine{knitr::rmarkdown} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) + +library(sdtm.oak) +``` + +```{r eval=TRUE, echo=FALSE} +dm <- system.file("cm_domain/dm.csv", package = "sdtm.oak") |> + read.csv() +nrow(dm) +``` diff --git a/vignettes/articles/sdtm_ct.csv b/vignettes/articles/sdtm_ct.csv deleted file mode 100644 index d078d6ed..00000000 --- a/vignettes/articles/sdtm_ct.csv +++ /dev/null @@ -1,75 +0,0 @@ -codelist_code,term_code,term_value,collected_value,term_preferred_term,term_synonyms -C66726,C25158,CAPSULE,Capsule,Capsule Dosage Form,cap -C66726,C25394,PILL,Pill,Pill Dosage Form, -C66726,C29167,LOTION,Lotion,Lotion Dosage Form, -C66726,C42887,AEROSOL,Aerosol,Aerosol Dosage Form,aer -C66726,C42944,INHALANT,Inhalant,Inhalant Dosage Form, -C66726,C42946,INJECTION,Injection,Injectable Dosage Form, -C66726,C42953,LIQUID,Liquid,Liquid Dosage Form, -C66726,C42998,TABLET,Tablet,Tablet Dosage Form,tab -C66728,C25629,BEFORE,Prior,Prior, -C66728,C53279,ONGOING,Continue,Continue,Continuous -C66729,C28161,INTRAMUSCULAR,IM (Intramuscular),Intramuscular Route of Administration, -C66729,C38210,EPIDURAL,EP (Epidural),Epidural Route of Administration, -C66729,C38222,INTRA-ARTERIAL,IA (Intra-arterial),Intraarterial Route of Administration, -C66729,C38223,INTRA-ARTICULAR,IJ (Intra-articular),Intraarticular Route of Administration, -C66729,C38287,OPHTHALMIC,OP (Ophthalmic),Ophthalmic Route of Administration, -C66729,C38288,ORAL,PO (Oral),Oral Route of Administration,Intraoral Route of Administration; PO -C66729,C38305,TRANSDERMAL,DE (Transdermal),Transdermal Route of Administration, -C66729,C38311,UNKNOWN,Unknown,Unknown Route of Administration, -C66734,C49568,CM,Concomitant Medication Domain,Concomitant Medication Domain,Concomitant/Prior Medications -C66741,C174446,TEMP,Body Temperature,Body Temperature,Body Temperature; Temperature -C66741,C25298,SYSBP,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure -C66741,C25299,DIABP,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure -C66741,C49676,PULSE,Pulse Rate,Pulse Rate,Pulse Rate -C66741,C49678,RESP,Respiratory Rate,Respiratory Rate,Respiratory Rate -C66741,C60832,OXYSAT,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation -C66741,V00224,VSALL,VS Domain ALL Tests,VS Domain ALL Tests, -C66742,C49488,Y,Yes,Yes,Yes -C66770,C25613,%,Percentage,Percentage,Percentage -C66770,C42559,C,Degree Celsius,Degree Celsius,Degree Celsius -C66770,C49670,mmHg,Millimeter of Mercury,Millimeter of Mercury,Millimeter of Mercury -C66770,C49673,beats/min,Beats per Minute,Beats per Minute,Beats per Minute; BPM; bpm -C66770,C49674,breaths/min,Breaths per Minute,Breaths per Minute,Breaths per Minute -C66789,C49484,NOT DONE,Not Done,Not Done, -C67153,C174446,Temperature,Body Temperature,Body Temperature,Body Temperature; Temperature -C67153,C25298,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure,Systolic Blood Pressure -C67153,C25299,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure,Diastolic Blood Pressure -C67153,C49676,Pulse Rate,Pulse Rate,Pulse Rate,Pulse Rate -C67153,C49678,Respiratory Rate,Respiratory Rate,Respiratory Rate,Respiratory Rate -C67153,C60832,Oxygen Saturation,Oxygen Saturation Measurement,Oxygen Saturation Measurement,Oxygen Saturation -C67153,V00224,Vital Signs,VS Domain ALL Tests,VS Domain ALL Tests, -C71113,C25473,QD,QD (Every Day),Daily,/day; Daily; Per Day -C71113,C64496,BID,BID (Twice a Day),Twice Daily,BD; Twice per day -C71113,C64499,PRN,PRN (As Needed),As Needed,As needed -C71113,C64516,Q2H,Q2H (Every 2 Hours),Every Two Hours,Every 2 hours -C71113,C64530,QID,QID (4 Times a Day),Four Times Daily,4 times per day -C71148,C111310,SEMI-RECUMBENT,Semi-Supine,Semi-Supine,Semi-Supine -C71148,C62122,SITTING,Sitting,Sitting,Sitting -C71148,C62165,PRONE,Prone,Prone,Prone -C71148,C62166,STANDING,Standing,Standing,Orthostatic; Standing -C71148,C62167,SUPINE,Supine,Supine,Supine -C71620,C25613,%,%,Percentage,Percentage -C71620,C28253,mg,mg,Milligram,Milligram -C71620,C28254,mL,mL,Milliliter,cm3; Milliliter -C71620,C48155,g,g,Gram,Gram -C71620,C48480,CAPSULE,Capsule,Capsule Dosing Unit,cap; Capsule Dosing Unit -C71620,C48542,TABLET,Tablet,Tablet Dosing Unit,tab; Tablet Dosing Unit -C71620,C48579,IU,IU,International Unit,IE; International Unit -C74456,C12390,RECTUM,Rectum,Rectum, -C74456,C12421,ORAL CAVITY,Oral Cavity,Oral Cavity,Buccal cavity; Mouth -C74456,C12470,SKIN,Skin,Skin,Integument; Skin -C74456,C12502,TYMPANIC MEMBRANE,Tympanic Membrane,Tympanic Membrane,Tympanic Membrane -C74456,C12674,AXILLA,Axilla,Axilla,Armpit; Axilla -C74456,C32608,FINGER,FINGER,FINGER,Finger -C74456,C89803,FOREHEAD,Forehead,Forehead,Forehead -C99073,C25228,RIGHT,Right,Right, -C99073,C25229,LEFT,Left,Left, -TPT,TPT,PREDOSE,Pre-dose,, -TPT,TPT,POSTDOSE,Post-dose,, -TPTNUM,TPTNUM,1,Pre-dose,, -TPTNUM,TPTNUM,2,Post-dose,, -VISITNUM,VISITNUM,1,Screening,, -VISITNUM,VISITNUM,2,Visit 1,, -VISIT,VISIT,SCREENING,Screening,, -VISIT,VISIT,VISIT 1,Visit 1,, \ No newline at end of file diff --git a/vignettes/articles/study_sdtm_spec.Rmd b/vignettes/articles/study_sdtm_spec.Rmd deleted file mode 100644 index 3f4715d2..00000000 --- a/vignettes/articles/study_sdtm_spec.Rmd +++ /dev/null @@ -1,361 +0,0 @@ ---- -title: "All about Metadata" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{All about Metadata} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- -```{css, echo = FALSE} -#pkgdown-sidebar{ - display:none; -} -.wide .table{ - font-size: 8px; - overflow: visible -} - -``` - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -options(rmarkdown.html_vignette.check_title = FALSE) -``` - -{sdtm.oak} is a metadata-driven solution that is designed to be Electronic Data -Capture (EDC) and standards agnostic. Throughout this article, the term "metadata" -is used several times. In this context, "metadata" refers to the specific -metadata used by {sdtm.oak}. This article aims to provide users with a more -detailed understanding of the {sdtm.oak} metadata. - -In general, metadata can be defined as "data about data." It does not include -any patient-level data. Instead, the metadata provides a blueprint of the data -that needs to be collected during a study. - -## Standards Metadata - -The standards metadata used in {sdtm.oak} is sourced from the CDISC Library or -sponsor MDR or any other form of documentation where standards are maintained. -This metadata provides information on the following: - -- The relationship between Data Collection Standards (eCRF & eDT), SDTM mapping, -and Controlled Terminology -- Machine-readable standard SDTM mappings -- Algorithms and associated metadata required for the SDTM automation of -standards in the study. - -In the upcoming releases of {sdtm.oak}, we will effectively utilize the -standards metadata and customize it to meet the study requirements. - -## Study Definition Metadata - -Study Definition Metadata is also referred to as Study Metadata. Study Definition -Metadata provides information about the eCRF and eDT data collected in the study. - -**eCRF Metadata** -The eCRF Design Metadata is fetched from the EDC system. This Metadata includes - -- Forms Metadata: Identifier, eCRF label, Repeating format and other properties of the eCRF. - -- Fields Metadata: Identifier, question label, datatype, and other -properties of data collection fields in the study. - -- Data Dictionaries: Identifier and the controlled terms collected at the -source. - -- Visits: Name of the visits as defined in the EDC. - -**eDT Metadata** - -eDT Metadata is the blueprint metadata that describes the data collected as part of that external data transfer (from clinical sites to the sponsor). This includes - -- Dataset name, label, repeating properties, etc. - -- Variable name, datatype, label and associated codelist, etc. - - -## Study SDTM Mappings Metadata (specifications) - -Study SDTM mappings metadata is the study SDTM specification. To develop the SDTM domains, {sdtm.oak} requires the user to prepare the Study SDTM mappings metadata. Unlike the conventional SDTM specification, which includes one tab per domain defining the target (SDTM domain, Variables) to source (raw dataset, raw variables) and SDTM mappings, the SDTM spec for {sdtm.oak} defines the source-to-target relationship. For each source, the SDTM mapping, algorithms, and associated metadata are defined. The table below presents the columns in the SDTM mapping specification and its explanation. - -

-```{r echo = FALSE, results = "asis"} -library(knitr) -definition <- data.frame( - Variable_Name = c( - "study_number", - "raw_source_model", - "raw_dataset", - "raw_dataset_ordinal", - "raw_dataset_label", - "raw_variable", - "raw_variable_label", - "raw_variable_ordinal", - "raw_variable_type", - "raw_data_format", - "raw_codelist", - "study_specific", - "annotation_ordinal", - "mapping_is_dataset", - "annotation_text", - "target_domain", - "target_sdtm_variable", - "target_sdtm_variable_role", - "target_sdtm_variable_codelist_code", - paste( - "target_sdtm_variable_", - "controlled_terms_or_format" - ), - "target_sdtm_variable_ordinal", - "origin", - "mapping_algorithm", - "sub_algorithm", - "target_hardcoded_value", - "target_term_value", - "target_term_code", - "condition_ordinal", - "condition_group_ordinal", - "condition_left_raw_dataset", - "condition_left_raw_variable", - "condition_left_sdtm_domain", - "condition_left_sdtm_variable", - "condition_operator", - "condition_right_text_value", - "condition_right_sdtm_domain", - "condition_right_sdtm_variable", - "condition_right_raw_dataset", - "condition_right_raw_variable", - "condition_next_logical_operator", - "merge_type", - "merge_left", - "merge_right", - "merge_condition", - "unduplicate_keys", - "groupby_keys", - "target_resource_dataset", - "target_resource_variable" - ), - `Description_of_the_variable` = c( - "Study Number", - "Data Collection model", - "Name of the raw or source dataset", - "Ordinal of the raw dataset as defined in EDC or eDT specification", - "Label of the raw or source dataset", - "Name of the raw variable", - "Label of the raw variable", - paste( - "Ordinal of the variable as defined in the eCRF or", - "eDT specification" - ), - "Type of the Raw Variable", - "Data format of the raw variable", - paste( - "Dictionary name which is assigned to the ", - "eCRF field or a eDT variable" - ), - paste( - "`TRUE` indicates that the source is study specific. ", - "`FALSE` indicates that the raw variable is part of data standards" - ), - "Ordinal of the SDTM mappings for the particular raw source", - paste( - "Indicates if the SDTM mapping is at the dataset level. ", - "`TRUE` indicates that it is dataset level mapping." - ), - "SDTM mapping text or annotation text", - "Name of the target domain.", - "Name of the target SDTM variable", - "CDISC Role for the SDTM target variable defined in the annotation.", - paste( - "NCI or sponsor code of the codelist assigned to the ", - "SDTM target variable defined in the annotation." - ), - paste( - "Controlled terms or format for the target variable ", - "defined in the annotation (as defined per CDISC).", - "`target_sdtm_variable_controlled_terms_or_format` is required ", - "for SDTM Define.xml" - ), - "Ordinal of the target SDTM variable", - "Origin of metadata source, values are subject to controlled terminology", - "Mapping Algorithm", - "The sub-algorithm (scenario) of the source-to-target mapping", - "Text (Hardcoded value) that applies to the target.", - paste( - "CDISC Submission value or sponsor value which represents a", - "hardcoded text" - ), - paste( - "NCI code or sponsor code of the hardcoded value" - ), - paste( - "Ordinal of a (sub)condition, increasing when there ", - "are more than one sub-conditions (e.g. X AND Y)" - ), - paste( - "Ordinal of a group of sub-conditions, used to ", - "disambiguate complex conditions such as (A AND B) OR C. ", - "The ordinal increases in each group and gives the final ", - "precedence of the logical operators." - ), - "Name of the raw dataset on the left part of the condition", - "Name of the raw variable on the left part of the condition", - "Name of the SDTM variable used in the left part of the condition.", - paste( - "Name of the SDTM domain of the variable that is used in ", - "the left part of the condition." - ), - "Operator between the left and right part of the condition", - paste( - "A text that applies to the right part of the condition as ", - "indicated per `condition_operator`." - ), - "Name of the SDTM variable used in the right part of the condition.", - paste( - "Name of the SDTM domain of the variable that is used ", - "in the right part of the condition." - ), - "Name of the raw dataset on the right part of the condition", - "Name of the raw variable on the right part of the condition", - paste( - "The logical operator that applies to the next ", - "sub-conditions, typically AND, OR" - ), - "Specifies the type of join", - "Specifies the left component of the merge", - "Specifies the right component of the merge", - paste( - "Specify the condition of the join (e.g. a specific ", - "variable that should match in the components of the merge)" - ), - paste( - "Raw variables that should be used to determine whether ", - "an observation in the source data is a duplicate record and ", - "subject to being removed" - ), - paste( - "Raw Variables or aggregation functions (i.e. earliest, ", - "latest) to group source data records before mapping to SDTM" - ), - paste( - "Raw dataset name of the raw variable. This will be used when ", - " values are assigned from a from a different source", - "other than the source the mapping is associated with" - ), - paste( - "Raw variable name. This will be used when ", - "values are assigned from a from a different source", - "other than the source the mapping is associated with" - ) - ), - Example_Values = c( - "test_study", - "e-CRF or eDT", - "VTLS1, DEM", - "1, 2, 3, etc", - "Vital Signs,
Demographics", - "SEX_001,
BRTHDD", - "Systolic Blood Pressure,
Birth Day", - "1, 2, 3, etc", - "Text Box,
Date control", - "$200,
dd MON YYYY", - "SEX, ETHNIC", - "TRUE, FALSE", - "1, 2, 3, etc", - "TRUE, FALSE", - "VS.VSORRES when VSTESTCD = 'SYSBP'", - "VS, MH", - "VSORRES, MHSTDTC", - "Topic Variable,
Grouping Qualifier,
Identifier Variable", - "C66742
C66790", - "(AGEU)
ISO 8601
(SEX)", - "1, 2, 3", - "Derived,
Assigned,
Collected,
Predecessor", - "DATASET_LEVEL
ASSIGN_CT
AE_AEREL
HARDCODE_CT", - "ASSIGN_NO_CT
HARCODE_CT", - "ALZHEIMER'S DISEASE HISTORY", - "Y,
beats/min,
INFORMED CONSENT OBTAINED", - "C49488", - "1, 2, 3", - "1, 2, 3", - "VTLS1", - "POSITION", - "AE", - "AEENRTPT", - paste( - "Checked
Not_checked
Is_null
Is_not_null", - "
Equals_to
Different_to
is_numeric
in", - "
not_in" - ), - "('Not Recovered/Not Resolved','Recovering/Resolving')
HOSPITALIZATION", - "AE", - "AETERM", - "SMKHX", - "SUNAM", - "and, or", - "left_join
right_join
full_join
visit_join
subject_join", - "VTLS1", - "VACREC", - "VTLS1.SUBJECT = VACREC.SUBJECT,
MD1.MDNUM = VACREC.MDNUM", - "VTLS1.SUBJECT,
VTLS1.DATAPAGEID", - "TXINF1.DATAPGID,
Earliest", - "AEDE", - "DATAPAGEID" - ), - Association_with_mapping_Algorithms = c( - "Generic Use", - "Generic Use", - "Required for all mapping algorithms", - "Generic Use", - "Generic Use", - "Generic Use", - "Generic Use", - "Generic Use", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Generic Use", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Generic Use", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Required for all mapping algorithms", - "Generic Use", - "Required for all mapping algorithms", - "Used for define.xml", - "Required for all mapping algorithms", - "Only when Mapping Algorithm is
IF_THEN_ELSE
DATASET_LEVEL", - "ASSIGN_NO_CT
HARDCODE_NO_CT", - "HARDCODE_CT", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "IF_THEN_ELSE", - "MERGE", - "MERGE", - "MERGE", - "MERGE", - "REMOVE_DUP", - "GROUP_BY", - "ASSIGN_NO_CT", - "ASSIGN_NO_CT" - ), - stringsAsFactors = TRUE -) -knitr::kable(definition) -``` diff --git a/vignettes/articles/vitals_raw_data.csv b/vignettes/articles/vitals_raw_data.csv deleted file mode 100644 index 8b164c22..00000000 --- a/vignettes/articles/vitals_raw_data.csv +++ /dev/null @@ -1,7 +0,0 @@ -STUDY,PATNUM,SUBJSTAT,SITENM,INSTANCE,FORM,FORML,DATAPGID,RECORDID,RECPOS,ASMNTDN,TMPTC,VTLD,VTLTM,SUBPOS,SYS_BP,DIA_BP,PULSE,RESPRT,TEMP,TEMPLOC,OXY_SAT,LAT,LOC,VSO2SRC,NEWS107 -Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1752329,5734754,0,0,Pre-dose,16-May-15,7:25,PRONE,158,92,63,17,40.48,SKIN,98,RIGHT,FINGER,MASK OXYGEN THERAPY,UNRESPONSIVE -Test Study,375,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,8153061,3712412,1,0,Post-dose,16-May-15,10:25,SEMI-RECUMBENT,94,78,76,20,36.75,TYMPANIC MEMBRANE,99,LEFT,FINGER,ROOM AIR,NEW CONFUSION -Test Study,375,Randomized,Test Study,Screening,VTLS1,Vital Signs,3463516,1229594,0,0,,6-May-18,2:01,PRONE,117,62,66,15,29.45,ORAL CAVITY,96,LEFT,FINGER,ROOM AIR,VERBAL RESPONSIVE -Test Study,376,Randomized,Test Study,Screening,VTLS1,Vital Signs,8423253,9767053,0,1,,,,,,,,,,,,,,, -Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,1211365,1567778,0,0,Pre-dose,23-Oct-08,1:19,PRONE,85,68,73,21,38.25,AXILLA,93,RIGHT,FINGER,ROOM AIR,ALERT -Test Study,376,Randomized,Test Study,VISIT1,VTLS1,Vital Signs,5880552,7060998,0,0,Post-dose,23-Oct-08,3:19,PRONE,126,81,56,18,38.08,TYMPANIC MEMBRANE,93,LEFT,FINGER,MASK OXYGEN THERAPY,PAIN RESPONSIVE \ No newline at end of file From 8a1ddfd3619d9a9b6c47d23366735e522dc617d3 Mon Sep 17 00:00:00 2001 From: Edgar Manukyan Date: Mon, 17 Jun 2024 14:35:04 -0400 Subject: [PATCH 21/23] testing --- _pkgdown.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index 13e86fbf..125d6a6c 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -33,3 +33,10 @@ reference: - title: Package global state contents: - clear_cache + - condition_add + - ctl_new_rowid_pillar.cnd_df + - dataset_oak_vignette + - mutate.cnd_df + - oak_id_vars + - rm_cnd_df + - tbl_sum.cnd_df From 6da571f0fbcf0c165eb192537eb5b00766625b75 Mon Sep 17 00:00:00 2001 From: edgar-manukyan Date: Mon, 17 Jun 2024 18:47:28 +0000 Subject: [PATCH 22/23] Automatic renv profile update. --- renv/profiles/4.2/renv.lock | 240 ++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/renv/profiles/4.2/renv.lock b/renv/profiles/4.2/renv.lock index a456139d..885895ef 100644 --- a/renv/profiles/4.2/renv.lock +++ b/renv/profiles/4.2/renv.lock @@ -17,7 +17,7 @@ "Package": "R.cache", "Version": "0.16.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -32,7 +32,7 @@ "Package": "R.methodsS3", "Version": "1.8.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -43,7 +43,7 @@ "Package": "R.oo", "Version": "1.26.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -56,7 +56,7 @@ "Package": "R.utils", "Version": "2.12.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -71,7 +71,7 @@ "Package": "R6", "Version": "2.5.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -81,7 +81,7 @@ "Package": "Rcpp", "Version": "1.0.10", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "methods", "utils" @@ -92,7 +92,7 @@ "Package": "askpass", "Version": "1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "sys" ], @@ -102,7 +102,7 @@ "Package": "assertthat", "Version": "0.2.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tools" ], @@ -112,7 +112,7 @@ "Package": "backports", "Version": "1.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -122,7 +122,7 @@ "Package": "base64enc", "Version": "0.1-3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -132,7 +132,7 @@ "Package": "bit", "Version": "4.0.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -142,7 +142,7 @@ "Package": "bit64", "Version": "4.0.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bit", @@ -156,21 +156,21 @@ "Package": "brew", "Version": "1.0-8", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "d69a786e85775b126bddbee185ae6084" }, "brio": { "Package": "brio", "Version": "1.1.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "976cf154dfb043c012d87cddd8bca363" }, "bslib": { "Package": "bslib", "Version": "0.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -190,7 +190,7 @@ "Package": "cachem", "Version": "1.0.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "fastmap", "rlang" @@ -201,7 +201,7 @@ "Package": "callr", "Version": "3.7.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -214,7 +214,7 @@ "Package": "checkmate", "Version": "2.1.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "backports", @@ -226,7 +226,7 @@ "Package": "cli", "Version": "3.6.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -237,7 +237,7 @@ "Package": "clipr", "Version": "0.8.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "utils" ], @@ -247,21 +247,21 @@ "Package": "commonmark", "Version": "1.8.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "b6e3e947d1d7ebf3d2bdcea1bde63fe7" }, "cpp11": { "Package": "cpp11", "Version": "0.4.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "ed588261931ee3be2c700d22e94a29ab" }, "crayon": { "Package": "crayon", "Version": "1.5.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "grDevices", "methods", @@ -273,7 +273,7 @@ "Package": "credentials", "Version": "1.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass", "curl", @@ -287,7 +287,7 @@ "Package": "curl", "Version": "5.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -297,7 +297,7 @@ "Package": "desc", "Version": "1.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -311,7 +311,7 @@ "Package": "devtools", "Version": "2.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -345,7 +345,7 @@ "Package": "diffobj", "Version": "0.3.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "crayon", @@ -360,7 +360,7 @@ "Package": "digest", "Version": "0.6.31", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -371,7 +371,7 @@ "Package": "downlit", "Version": "0.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "brio", @@ -391,7 +391,7 @@ "Package": "dplyr", "Version": "1.1.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -414,7 +414,7 @@ "Package": "ellipsis", "Version": "0.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "rlang" @@ -425,7 +425,7 @@ "Package": "evaluate", "Version": "0.20", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -436,7 +436,7 @@ "Package": "fansi", "Version": "1.0.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", @@ -448,14 +448,14 @@ "Package": "fastmap", "Version": "1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "f7736a18de97dea803bde0a2daaafb27" }, "fontawesome": { "Package": "fontawesome", "Version": "0.5.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "htmltools", @@ -467,7 +467,7 @@ "Package": "fs", "Version": "1.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -478,7 +478,7 @@ "Package": "generics", "Version": "0.1.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -489,7 +489,7 @@ "Package": "gert", "Version": "1.9.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass", "credentials", @@ -504,7 +504,7 @@ "Package": "gh", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -520,7 +520,7 @@ "Package": "git2r", "Version": "0.31.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "graphics", @@ -532,7 +532,7 @@ "Package": "gitcreds", "Version": "0.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -542,7 +542,7 @@ "Package": "glue", "Version": "1.6.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -553,7 +553,7 @@ "Package": "highr", "Version": "0.10", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "xfun" @@ -564,7 +564,7 @@ "Package": "hms", "Version": "1.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "ellipsis", "lifecycle", @@ -579,7 +579,7 @@ "Package": "htmltools", "Version": "0.5.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -596,7 +596,7 @@ "Package": "htmlwidgets", "Version": "1.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "grDevices", "htmltools", @@ -611,7 +611,7 @@ "Package": "httpuv", "Version": "1.6.9", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -626,7 +626,7 @@ "Package": "httr", "Version": "1.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -641,7 +641,7 @@ "Package": "httr2", "Version": "0.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -660,7 +660,7 @@ "Package": "hunspell", "Version": "3.0.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "Rcpp", @@ -672,14 +672,14 @@ "Package": "ini", "Version": "0.3.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "6154ec2223172bce8162d4153cda21f7" }, "jquerylib": { "Package": "jquerylib", "Version": "0.1.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "htmltools" ], @@ -689,7 +689,7 @@ "Package": "jsonlite", "Version": "1.8.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "methods" ], @@ -699,7 +699,7 @@ "Package": "knitr", "Version": "1.42", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "evaluate", @@ -715,7 +715,7 @@ "Package": "later", "Version": "1.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "Rcpp", "rlang" @@ -726,7 +726,7 @@ "Package": "lifecycle", "Version": "1.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -739,7 +739,7 @@ "Package": "lubridate", "Version": "1.9.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "generics", @@ -752,7 +752,7 @@ "Package": "magrittr", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -762,7 +762,7 @@ "Package": "memoise", "Version": "2.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cachem", "rlang" @@ -773,7 +773,7 @@ "Package": "mime", "Version": "0.12", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tools" ], @@ -783,7 +783,7 @@ "Package": "miniUI", "Version": "0.1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "htmltools", "shiny", @@ -795,7 +795,7 @@ "Package": "openssl", "Version": "2.0.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass" ], @@ -805,7 +805,7 @@ "Package": "pillar", "Version": "1.8.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cli", "fansi", @@ -822,7 +822,7 @@ "Package": "pkgbuild", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -841,7 +841,7 @@ "Package": "pkgconfig", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "utils" ], @@ -851,7 +851,7 @@ "Package": "pkgdown", "Version": "2.0.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -881,7 +881,7 @@ "Package": "pkgload", "Version": "1.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -901,21 +901,21 @@ "Package": "praise", "Version": "1.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "a555924add98c99d2f411e37e7d25e9f" }, "prettyunits": { "Package": "prettyunits", "Version": "1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "95ef9167b75dde9d2ccc3c7528393e7e" }, "processx": { "Package": "processx", "Version": "3.8.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -928,7 +928,7 @@ "Package": "profvis", "Version": "0.3.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "htmlwidgets", @@ -940,7 +940,7 @@ "Package": "progress", "Version": "1.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "crayon", @@ -953,7 +953,7 @@ "Package": "promises", "Version": "1.2.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "Rcpp", @@ -968,7 +968,7 @@ "Package": "ps", "Version": "1.7.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -979,7 +979,7 @@ "Package": "purrr", "Version": "1.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -994,7 +994,7 @@ "Package": "ragg", "Version": "1.2.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "systemfonts", "textshaping" @@ -1005,7 +1005,7 @@ "Package": "rappdirs", "Version": "0.3.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1015,7 +1015,7 @@ "Package": "rcmdcheck", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "callr", @@ -1037,7 +1037,7 @@ "Package": "readr", "Version": "2.1.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1060,7 +1060,7 @@ "Package": "rematch2", "Version": "2.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tibble" ], @@ -1070,7 +1070,7 @@ "Package": "remotes", "Version": "2.5.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "methods", @@ -1082,19 +1082,19 @@ }, "renv": { "Package": "renv", - "Version": "1.0.7", + "Version": "1.0.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "397b7b2a265bc5a7a06852524dabae20" + "Hash": "41b847654f567341725473431dd0d5ab" }, "rlang": { "Package": "rlang", "Version": "1.1.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -1105,7 +1105,7 @@ "Package": "rmarkdown", "Version": "2.20", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -1154,7 +1154,7 @@ "Package": "rprojroot", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1164,14 +1164,14 @@ "Package": "rstudioapi", "Version": "0.14", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "690bd2acc42a9166ce34845884459320" }, "rversions": { "Package": "rversions", "Version": "2.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "curl", "utils", @@ -1183,7 +1183,7 @@ "Package": "sass", "Version": "0.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "fs", @@ -1197,7 +1197,7 @@ "Package": "sessioninfo", "Version": "1.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1210,7 +1210,7 @@ "Package": "shiny", "Version": "1.7.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1244,7 +1244,7 @@ "Package": "sourcetools", "Version": "0.1.7-1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1254,7 +1254,7 @@ "Package": "spelling", "Version": "2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "commonmark", "hunspell", @@ -1300,7 +1300,7 @@ "Package": "stringi", "Version": "1.7.12", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "stats", @@ -1313,7 +1313,7 @@ "Package": "stringr", "Version": "1.5.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1349,14 +1349,14 @@ "Package": "sys", "Version": "3.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "34c16f1ef796057bfa06d3f4ff818a5d" }, "systemfonts": { "Package": "systemfonts", "Version": "1.0.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1367,7 +1367,7 @@ "Package": "testthat", "Version": "3.1.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1397,7 +1397,7 @@ "Package": "textshaping", "Version": "0.3.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11", @@ -1409,7 +1409,7 @@ "Package": "tibble", "Version": "3.2.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "fansi", @@ -1428,7 +1428,7 @@ "Package": "tidyr", "Version": "1.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1451,7 +1451,7 @@ "Package": "tidyselect", "Version": "1.2.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1467,7 +1467,7 @@ "Package": "timechange", "Version": "0.2.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1478,7 +1478,7 @@ "Package": "tinytex", "Version": "0.44", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "xfun" ], @@ -1488,7 +1488,7 @@ "Package": "tzdb", "Version": "0.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1499,7 +1499,7 @@ "Package": "urlchecker", "Version": "1.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1513,7 +1513,7 @@ "Package": "usethis", "Version": "2.1.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1544,7 +1544,7 @@ "Package": "utf8", "Version": "1.2.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1554,7 +1554,7 @@ "Package": "vctrs", "Version": "0.5.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1568,7 +1568,7 @@ "Package": "vroom", "Version": "1.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bit64", @@ -1594,7 +1594,7 @@ "Package": "waldo", "Version": "0.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cli", "diffobj", @@ -1611,14 +1611,14 @@ "Package": "whisker", "Version": "0.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "c6abfa47a46d281a7d5159d0a8891e88" }, "withr": { "Package": "withr", "Version": "2.5.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", @@ -1631,7 +1631,7 @@ "Package": "xfun", "Version": "0.37", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "stats", "tools" @@ -1642,7 +1642,7 @@ "Package": "xml2", "Version": "1.3.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -1653,7 +1653,7 @@ "Package": "xopen", "Version": "1.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "processx" @@ -1664,7 +1664,7 @@ "Package": "xtable", "Version": "1.8-4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "stats", @@ -1676,14 +1676,14 @@ "Package": "yaml", "Version": "2.3.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "0d0056cc5383fbc240ccd0cb584bf436" }, "zip": { "Package": "zip", "Version": "2.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "c42bfcec3fa6a0cce17ce1f8bc684f88" } } From 10a7f99022a844ee4545d851eb660a2a60033705 Mon Sep 17 00:00:00 2001 From: edgar-manukyan Date: Mon, 17 Jun 2024 18:51:13 +0000 Subject: [PATCH 23/23] Automatic renv profile update. --- renv/profiles/4.3/renv.lock | 240 ++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/renv/profiles/4.3/renv.lock b/renv/profiles/4.3/renv.lock index 30fb9575..ebc34e12 100644 --- a/renv/profiles/4.3/renv.lock +++ b/renv/profiles/4.3/renv.lock @@ -17,7 +17,7 @@ "Package": "R.cache", "Version": "0.16.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -32,7 +32,7 @@ "Package": "R.methodsS3", "Version": "1.8.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -43,7 +43,7 @@ "Package": "R.oo", "Version": "1.26.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -56,7 +56,7 @@ "Package": "R.utils", "Version": "2.12.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.methodsS3", @@ -71,7 +71,7 @@ "Package": "R6", "Version": "2.5.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -81,7 +81,7 @@ "Package": "Rcpp", "Version": "1.0.10", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "methods", "utils" @@ -92,7 +92,7 @@ "Package": "askpass", "Version": "1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "sys" ], @@ -102,7 +102,7 @@ "Package": "assertthat", "Version": "0.2.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tools" ], @@ -112,7 +112,7 @@ "Package": "backports", "Version": "1.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -122,7 +122,7 @@ "Package": "base64enc", "Version": "0.1-3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -132,7 +132,7 @@ "Package": "bit", "Version": "4.0.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -142,7 +142,7 @@ "Package": "bit64", "Version": "4.0.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bit", @@ -156,21 +156,21 @@ "Package": "brew", "Version": "1.0-8", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "d69a786e85775b126bddbee185ae6084" }, "brio": { "Package": "brio", "Version": "1.1.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "976cf154dfb043c012d87cddd8bca363" }, "bslib": { "Package": "bslib", "Version": "0.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -190,7 +190,7 @@ "Package": "cachem", "Version": "1.0.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "fastmap", "rlang" @@ -201,7 +201,7 @@ "Package": "callr", "Version": "3.7.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -214,7 +214,7 @@ "Package": "checkmate", "Version": "2.1.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "backports", @@ -226,7 +226,7 @@ "Package": "cli", "Version": "3.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -237,7 +237,7 @@ "Package": "clipr", "Version": "0.8.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "utils" ], @@ -247,21 +247,21 @@ "Package": "commonmark", "Version": "1.9.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "d691c61bff84bd63c383874d2d0c3307" }, "cpp11": { "Package": "cpp11", "Version": "0.4.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "ed588261931ee3be2c700d22e94a29ab" }, "crayon": { "Package": "crayon", "Version": "1.5.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "grDevices", "methods", @@ -273,7 +273,7 @@ "Package": "credentials", "Version": "1.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass", "curl", @@ -287,7 +287,7 @@ "Package": "curl", "Version": "5.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -297,7 +297,7 @@ "Package": "desc", "Version": "1.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -311,7 +311,7 @@ "Package": "devtools", "Version": "2.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -345,7 +345,7 @@ "Package": "diffobj", "Version": "0.3.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "crayon", @@ -360,7 +360,7 @@ "Package": "digest", "Version": "0.6.31", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -371,7 +371,7 @@ "Package": "downlit", "Version": "0.4.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "brio", @@ -391,7 +391,7 @@ "Package": "dplyr", "Version": "1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -414,7 +414,7 @@ "Package": "ellipsis", "Version": "0.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "rlang" @@ -425,7 +425,7 @@ "Package": "evaluate", "Version": "0.20", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -436,7 +436,7 @@ "Package": "fansi", "Version": "1.0.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", @@ -448,14 +448,14 @@ "Package": "fastmap", "Version": "1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "f7736a18de97dea803bde0a2daaafb27" }, "fontawesome": { "Package": "fontawesome", "Version": "0.5.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "htmltools", @@ -467,7 +467,7 @@ "Package": "fs", "Version": "1.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -478,7 +478,7 @@ "Package": "generics", "Version": "0.1.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -489,7 +489,7 @@ "Package": "gert", "Version": "1.9.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass", "credentials", @@ -504,7 +504,7 @@ "Package": "gh", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -520,7 +520,7 @@ "Package": "git2r", "Version": "0.32.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "graphics", @@ -532,7 +532,7 @@ "Package": "gitcreds", "Version": "0.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -542,7 +542,7 @@ "Package": "glue", "Version": "1.6.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -553,7 +553,7 @@ "Package": "highr", "Version": "0.10", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "xfun" @@ -564,7 +564,7 @@ "Package": "hms", "Version": "1.1.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "lifecycle", "methods", @@ -578,7 +578,7 @@ "Package": "htmltools", "Version": "0.5.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -595,7 +595,7 @@ "Package": "htmlwidgets", "Version": "1.6.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "grDevices", "htmltools", @@ -610,7 +610,7 @@ "Package": "httpuv", "Version": "1.6.9", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -625,7 +625,7 @@ "Package": "httr", "Version": "1.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -640,7 +640,7 @@ "Package": "httr2", "Version": "0.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -659,7 +659,7 @@ "Package": "hunspell", "Version": "3.0.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "Rcpp", @@ -671,14 +671,14 @@ "Package": "ini", "Version": "0.3.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "6154ec2223172bce8162d4153cda21f7" }, "jquerylib": { "Package": "jquerylib", "Version": "0.1.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "htmltools" ], @@ -688,7 +688,7 @@ "Package": "jsonlite", "Version": "1.8.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "methods" ], @@ -698,7 +698,7 @@ "Package": "knitr", "Version": "1.42", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "evaluate", @@ -714,7 +714,7 @@ "Package": "later", "Version": "1.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "Rcpp", "rlang" @@ -725,7 +725,7 @@ "Package": "lifecycle", "Version": "1.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -738,7 +738,7 @@ "Package": "lubridate", "Version": "1.9.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "generics", @@ -751,7 +751,7 @@ "Package": "magrittr", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -761,7 +761,7 @@ "Package": "memoise", "Version": "2.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cachem", "rlang" @@ -772,7 +772,7 @@ "Package": "mime", "Version": "0.12", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tools" ], @@ -782,7 +782,7 @@ "Package": "miniUI", "Version": "0.1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "htmltools", "shiny", @@ -794,7 +794,7 @@ "Package": "openssl", "Version": "2.0.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "askpass" ], @@ -804,7 +804,7 @@ "Package": "pillar", "Version": "1.9.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cli", "fansi", @@ -821,7 +821,7 @@ "Package": "pkgbuild", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -840,7 +840,7 @@ "Package": "pkgconfig", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "utils" ], @@ -850,7 +850,7 @@ "Package": "pkgdown", "Version": "2.0.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -880,7 +880,7 @@ "Package": "pkgload", "Version": "1.3.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -900,21 +900,21 @@ "Package": "praise", "Version": "1.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "a555924add98c99d2f411e37e7d25e9f" }, "prettyunits": { "Package": "prettyunits", "Version": "1.1.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "95ef9167b75dde9d2ccc3c7528393e7e" }, "processx": { "Package": "processx", "Version": "3.8.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -927,7 +927,7 @@ "Package": "profvis", "Version": "0.3.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "htmlwidgets", @@ -939,7 +939,7 @@ "Package": "progress", "Version": "1.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "crayon", @@ -952,7 +952,7 @@ "Package": "promises", "Version": "1.2.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "Rcpp", @@ -967,7 +967,7 @@ "Package": "ps", "Version": "1.7.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -978,7 +978,7 @@ "Package": "purrr", "Version": "1.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -993,7 +993,7 @@ "Package": "ragg", "Version": "1.2.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "systemfonts", "textshaping" @@ -1004,7 +1004,7 @@ "Package": "rappdirs", "Version": "0.3.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1014,7 +1014,7 @@ "Package": "rcmdcheck", "Version": "1.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "callr", @@ -1036,7 +1036,7 @@ "Package": "readr", "Version": "2.1.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1059,7 +1059,7 @@ "Package": "rematch2", "Version": "2.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "tibble" ], @@ -1069,7 +1069,7 @@ "Package": "remotes", "Version": "2.5.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "methods", @@ -1081,19 +1081,19 @@ }, "renv": { "Package": "renv", - "Version": "1.0.7", + "Version": "1.0.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "397b7b2a265bc5a7a06852524dabae20" + "Hash": "41b847654f567341725473431dd0d5ab" }, "rlang": { "Package": "rlang", "Version": "1.1.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -1104,7 +1104,7 @@ "Package": "rmarkdown", "Version": "2.21", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -1154,7 +1154,7 @@ "Package": "rprojroot", "Version": "2.0.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1164,14 +1164,14 @@ "Package": "rstudioapi", "Version": "0.14", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "690bd2acc42a9166ce34845884459320" }, "rversions": { "Package": "rversions", "Version": "2.1.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "curl", "utils", @@ -1183,7 +1183,7 @@ "Package": "sass", "Version": "0.4.5", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R6", "fs", @@ -1197,7 +1197,7 @@ "Package": "sessioninfo", "Version": "1.2.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1210,7 +1210,7 @@ "Package": "shiny", "Version": "1.7.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1244,7 +1244,7 @@ "Package": "sourcetools", "Version": "0.1.7-1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1254,7 +1254,7 @@ "Package": "spelling", "Version": "2.2.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "commonmark", "hunspell", @@ -1300,7 +1300,7 @@ "Package": "stringi", "Version": "1.7.12", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "stats", @@ -1313,7 +1313,7 @@ "Package": "stringr", "Version": "1.5.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1349,14 +1349,14 @@ "Package": "sys", "Version": "3.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "34c16f1ef796057bfa06d3f4ff818a5d" }, "systemfonts": { "Package": "systemfonts", "Version": "1.0.4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1367,7 +1367,7 @@ "Package": "testthat", "Version": "3.1.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1397,7 +1397,7 @@ "Package": "textshaping", "Version": "0.3.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11", @@ -1409,7 +1409,7 @@ "Package": "tibble", "Version": "3.2.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "fansi", @@ -1428,7 +1428,7 @@ "Package": "tidyr", "Version": "1.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1451,7 +1451,7 @@ "Package": "tidyselect", "Version": "1.2.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1467,7 +1467,7 @@ "Package": "timechange", "Version": "0.2.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1478,7 +1478,7 @@ "Package": "tinytex", "Version": "0.45", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "xfun" ], @@ -1488,7 +1488,7 @@ "Package": "tzdb", "Version": "0.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cpp11" @@ -1499,7 +1499,7 @@ "Package": "urlchecker", "Version": "1.0.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1513,7 +1513,7 @@ "Package": "usethis", "Version": "2.1.6", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1544,7 +1544,7 @@ "Package": "utf8", "Version": "1.2.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R" ], @@ -1554,7 +1554,7 @@ "Package": "vctrs", "Version": "0.6.2", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1568,7 +1568,7 @@ "Package": "vroom", "Version": "1.6.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "bit64", @@ -1594,7 +1594,7 @@ "Package": "waldo", "Version": "0.4.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "cli", "diffobj", @@ -1611,14 +1611,14 @@ "Package": "whisker", "Version": "0.4.1", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "c6abfa47a46d281a7d5159d0a8891e88" }, "withr": { "Package": "withr", "Version": "2.5.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", @@ -1631,7 +1631,7 @@ "Package": "xfun", "Version": "0.38", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "stats", "tools" @@ -1642,7 +1642,7 @@ "Package": "xml2", "Version": "1.3.3", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "methods" @@ -1653,7 +1653,7 @@ "Package": "xopen", "Version": "1.0.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "processx" @@ -1664,7 +1664,7 @@ "Package": "xtable", "Version": "1.8-4", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Requirements": [ "R", "stats", @@ -1676,14 +1676,14 @@ "Package": "yaml", "Version": "2.3.7", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "0d0056cc5383fbc240ccd0cb584bf436" }, "zip": { "Package": "zip", "Version": "2.3.0", "Source": "Repository", - "Repository": "repos", + "Repository": "RSPM", "Hash": "d98c94dacb7e0efcf83b0a133a705504" } }