Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if_then_else support via "conditioned" data frames #55

Merged
merged 13 commits into from
Jun 18, 2024
5 changes: 4 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ Imports:
tibble,
vctrs,
readr,
glue
glue,
pillar
Suggests:
knitr,
lifecycle,
magrittr,
rmarkdown,
spelling,
testthat (>= 3.1.7)
Expand Down
9 changes: 9 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# 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("%.>%")
export(assign_ct)
export(assign_datetime)
export(assign_no_ct)
export(clear_cache)
export(condition_add)
export(create_iso8601)
export(ct_map)
export(ct_spec_example)
Expand All @@ -13,9 +18,13 @@ 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)
importFrom(dplyr,mutate)
importFrom(pillar,ctl_new_rowid_pillar)
importFrom(pillar,tbl_sum)
importFrom(rlang,"%||%")
importFrom(rlang,":=")
importFrom(rlang,.data)
Expand Down
16 changes: 16 additions & 0 deletions R/assertions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Surprisingly, admiraldev doesn't provide `assert_logical_vector`.
ramiromagno marked this conversation as resolved.
Show resolved Hide resolved
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)
}
71 changes: 32 additions & 39 deletions R/assign.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -53,29 +54,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)) |>
dplyr::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)

# Recode the raw variable following terminology.
tgt_val <- ct_map(join_dat[[raw_var]], ct_spec = ct_spec, ct_clst = ct_clst)

# 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)) {
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
Expand Down Expand Up @@ -127,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 <-
Expand Down Expand Up @@ -175,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
Expand All @@ -189,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)
Expand All @@ -204,24 +196,25 @@ 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
)
}

#' @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)
Expand All @@ -232,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
Expand Down
54 changes: 24 additions & 30 deletions R/assign_datetime.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -170,27 +171,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(c(id_vars, raw_var)) |>
dplyr::mutate("{tgt_var}" := tgt_val) |> # nolint object_name_linter()
dplyr::select(-raw_var)
dplyr::select(dplyr::all_of(c(id_vars, raw_var))) |>
sdtm_join(tgt_dat = tgt_dat, id_vars = id_vars)

der_dat <-
if (!is.null(tgt_dat)) {
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())
}
Loading