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

# 16 calculate_study_day #20

Merged
merged 75 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
47e08c8
draft
Nov 6, 2023
05a14d2
add reference df so that DM can be joined on the fly
Dec 6, 2023
ef235ac
add roxygen doc
Dec 6, 2023
d3814cb
doc update
Dec 6, 2023
1333ca9
rename ds_in as sdtm_in
Jan 16, 2024
10c2233
replace ds_dm with dm_domain
Jan 17, 2024
2881071
add default value for refdt
Jan 17, 2024
4eb2926
add matching check
Jan 17, 2024
512e254
Merge branch 'main' into 16_calculate_study_day@devel
Jan 20, 2024
1caeb91
refdt and tgdt have to be ISO format, otherwise NA and warning
Jan 21, 2024
4cdf814
utils::hasName
Jan 21, 2024
e62d5dc
modify assert message
Jan 21, 2024
1c267e1
update message for refdt and tgdt convertion error
Jan 22, 2024
aecf81d
set .call to FALSE for warning
Jan 22, 2024
222c4b7
add unit test
Jan 22, 2024
b936cf1
update document
Jan 22, 2024
3cca05a
style update
Jan 22, 2024
5e41b4b
add asserthat in DESCRIPTION
Jan 22, 2024
a4fc269
Automatic renv profile update.
yli110-stat697 Jan 22, 2024
2e04f13
Automatic renv profile update.
yli110-stat697 Jan 22, 2024
72641d1
use data frame instead of data.frame
yli110-stat697 Feb 2, 2024
8036644
capitalize param per reference
yli110-stat697 Feb 2, 2024
d05a147
data frame instead of data.frame
yli110-stat697 Feb 2, 2024
c495170
capitalize param per reference
yli110-stat697 Feb 2, 2024
fa6667a
capitalize param per reference
yli110-stat697 Feb 2, 2024
6d19981
update wording for test
yli110-stat697 Feb 2, 2024
a0c6522
update wording for test
yli110-stat697 Feb 2, 2024
a90210f
use base pipe
yli110-stat697 Feb 2, 2024
79799db
use base pipe
yli110-stat697 Feb 2, 2024
381de67
use base pipe
yli110-stat697 Feb 2, 2024
2e63aef
Merge branch 'main' into 16_calculate_study_day@devel
yli110-stat697 Feb 2, 2024
0d7a179
Merge branch 'main' into 16_calculate_study_day@devel
yli110-stat697 Feb 9, 2024
c3ec9ce
update man file
Feb 11, 2024
01c3fc5
update df name for lint compliance
Feb 11, 2024
7f4a8bb
integer with L
Feb 11, 2024
a47e827
L for test integers
Feb 11, 2024
f6d467b
replace nested ifelse with case when per lintr suggestion
Feb 11, 2024
9ad8daf
Revert "replace nested ifelse with case when per lintr suggestion"
Feb 12, 2024
a1af5be
capitalize param per reference
yli110-stat697 Feb 12, 2024
0c78685
update typo in roxygen header
Feb 12, 2024
fd8e46c
resolve conflict
Feb 12, 2024
f20ed8b
capitalize param per reference
yli110-stat697 Feb 12, 2024
9c26b03
capitalize param per reference
yli110-stat697 Feb 12, 2024
8a977b2
remove don't run
Feb 12, 2024
44aef03
Merge branch '16_calculate_study_day@devel' of github.com:pharmaverse…
Feb 12, 2024
06532bd
capitalize param per reference
yli110-stat697 Feb 12, 2024
0be0d8b
use mapply to replace nested if else
Feb 12, 2024
4b79383
Merge branch '16_calculate_study_day@devel' of github.com:pharmaverse…
Feb 12, 2024
c3d812f
style
Feb 12, 2024
99cc8d2
roxygen update
Feb 12, 2024
9243268
fixed to be TRUE
Feb 12, 2024
df4a7ed
fix lintr
Feb 12, 2024
4e7c392
fix lintr in test file
Feb 12, 2024
026f5a3
remove @md tag
Feb 15, 2024
7e92d53
Update `calculate_study_day()`
ramiromagno Feb 17, 2024
d651028
move defaults to the end of argument positions
Feb 19, 2024
81d5804
merge from ramio
Feb 19, 2024
ae903e9
add equal sign
Feb 19, 2024
64dcdb1
default to "DM"
Feb 19, 2024
7c91722
update unit test per the arg position change
Feb 19, 2024
fa26e73
man file update
Feb 19, 2024
958453e
remove dm_domain default
Feb 21, 2024
b95a82a
Update common.yml
galachad Feb 27, 2024
9f739b7
simplify by statement
Mar 4, 2024
aadbae5
Merge branch '16_calculate_study_day@devel' of github.com:pharmaverse…
Mar 4, 2024
f424a58
Automatic renv profile update.
yli110-stat697 Mar 4, 2024
d57ad5a
add unit test for same input and reference df
Mar 4, 2024
b86965d
Merge branch '16_calculate_study_day@devel' of github.com:pharmaverse…
Mar 4, 2024
091e506
rename function
Mar 4, 2024
4379011
rename files
Mar 4, 2024
e6d8758
study day changed to integer
Mar 4, 2024
2037ba1
update style
Mar 4, 2024
48ba06d
update man file
Mar 4, 2024
2074b16
update doc
yli110-stat697 Mar 11, 2024
fcdcb0c
update man file
Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
if: >
github.event_name != 'release'
with:
r-version: "4.3"
r-version: "release"
# Whether to skip code coverage badge creation
# Setting to 'false' will require you to create
# an orphan branch called 'badges' in your repository
Expand Down
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Depends: R (>= 4.2)
Imports:
admiraldev,
dplyr (>= 1.0.0),
assertthat,
purrr (>= 0.3.3),
rlang (>= 0.4.4),
stringr (>= 1.4.0),
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Generated by roxygen2: do not edit by hand

S3method(print,iso8601)
export(calculate_study_day)
export(create_iso8601)
export(fmt_cmp)
export(problems)
Expand Down
132 changes: 132 additions & 0 deletions R/calculate_study_day.R
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#' `calculate_study_day` performs study day calculation
#' @description
#' This function takes the an input data frame and a reference data frame (which
#' is DM domain in most cases), and calculate the study day from reference date
#' and target date. In case of unexpected conditions like reference date is not
#' unique for each patient, or reference and input dates are not actual dates,
#' NA will be returned for those records.
#'
#' @param sdtm_in Input data frame that contains the target date.
#' @param dm_domain Reference date frame that contains the reference date.
#' @param tgdt Target date from `sdtm_in` that will be used to calculate the study
#' day.
#' @param refdt Reference date from `dm_domain` that will be used as reference to
#' calculate the study day.
#' @param study_day_var New study day variable name in the output. For
#' example, AESTDY for AE domain and CMSTDY for CM domain.
#' @param merge_key Character to represents the merging key between `sdtm_in` and
#' `dm_domain`.
#'
#' @return Data frame that takes all columns from `sdtm_in` and a new variable
#' to represent the calculated study day.
#'
#' @export
#'
#' @examples
#' ae <- data.frame(
#' USUBJID = c("study123-123", "study123-124", "study123-125"),
#' AESTDTC = c("2012-01-01", "2012-04-14", "2012-04-14")
#' )
#' dm <- data.frame(
#' USUBJID = c("study123-123", "study123-124", "study123-125"),
#' RFSTDTC = c("2012-02-01", "2012-04-14", NA)
#' )
#' ae$AESTDTC <- as.Date(ae$AESTDTC)
#' dm$RFSTDTC <- as.Date(dm$RFSTDTC)
#' calculate_study_day(ae, dm, "AESTDTC", "RFSTDTC", "AESTDY")
#'
calculate_study_day <- function(sdtm_in,
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
dm_domain,
tgdt,
refdt,
study_day_var,
merge_key = "USUBJID") {
assertthat::assert_that(is.data.frame(sdtm_in))
assertthat::assert_that(is.data.frame(dm_domain))
assertthat::assert_that(
utils::hasName(dm_domain, refdt),
msg = "dm_domain needs to have the variable of refdt."
)
assertthat::assert_that(
utils::hasName(sdtm_in, tgdt),
msg = "sdtm_in needs to have the variable of tgdt."
)
assertthat::assert_that(
utils::hasName(dm_domain, merge_key),
msg = "dm_domain needs to have the variable of merge_key."
)
assertthat::assert_that(
utils::hasName(sdtm_in, merge_key),
msg = "sdtm_in needs to have the variable of merge_key."
)
assertthat::assert_that(is.character(study_day_var))
# check tgdt and study_day_var matching, for example, CMSTDTC matches CMSTDY
if (gsub("DTC", "", tgdt, fixed = TRUE) != gsub("DY", "", study_day_var, fixed = TRUE)) {
warning(
"Target date and the returned study day doesn't match. ",
"Expecting matching date and study day, for example, CMENDTC and CMENDY"
)
}

original_variables <- names(sdtm_in)

if (!identical(sdtm_in, dm_domain)) {
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
dm_domain <- unique(dm_domain[c(merge_key, refdt)])

check_refdt_uniqueness <- dm_domain |>
dplyr::group_by(dplyr::pick({{ merge_key }})) |>
dplyr::filter(dplyr::n() > 1L)
if (nrow(check_refdt_uniqueness) > 0L) {
warning(
"Reference date is not unique for each patient! ",
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
"Patient without unique reference date will be ingored. ",
"NA will be returned for such records."
)
dm_domain <- dm_domain[
!dm_domain[[merge_key]] %in% check_refdt_uniqueness[[merge_key]],
]
}

sdtm_in <- sdtm_in |>
dplyr::left_join(
dm_domain,
by = structure(names = merge_key, .Data = merge_key)
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
)
}

# refdt/tgdt should be in ISO format, otherwise throw warning
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
sdtm_in[[refdt]] <- tryCatch(
as.Date(sdtm_in[[refdt]], "%Y-%m-%d"),
error = function(e) {
warning(
"Encountered errors when converting refdt to dates. ",
"The warning message is ",
e$message,
call. = FALSE
)
NA
}
)
sdtm_in[[tgdt]] <- tryCatch(
as.Date(sdtm_in[[tgdt]], "%Y-%m-%d"),
error = function(e) {
warning(
"Encountered errors when converting tgdt to dates. ",
"The warning message is ",
e$message,
call. = FALSE
)
NA
}
)

ref <- sdtm_in[[refdt]]
tgt <- sdtm_in[[tgdt]]

# SDTMIG 4.4.4 Use of the Study Day Variables
res <- ifelse(tgt >= ref, tgt - ref + 1L, tgt - ref)
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved

sdtm_in <- sdtm_in[original_variables]
sdtm_in[study_day_var] <- res
yli110-stat697 marked this conversation as resolved.
Show resolved Hide resolved
return(sdtm_in)
}
57 changes: 57 additions & 0 deletions man/calculate_study_day.Rd

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

10 changes: 10 additions & 0 deletions renv.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@
],
"Hash": "e8a22846fff485f0be3770c2da758713"
},
"assertthat": {
"Package": "assertthat",
"Version": "0.2.1",
"Source": "Repository",
"Repository": "RSPM",
"Requirements": [
"tools"
],
"Hash": "50c838a310445e954bc13f26f26a6ecf"
},
"backports": {
"Package": "backports",
"Version": "1.4.1",
Expand Down
10 changes: 10 additions & 0 deletions renv/profiles/4.2/renv.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@
],
"Hash": "e8a22846fff485f0be3770c2da758713"
},
"assertthat": {
"Package": "assertthat",
"Version": "0.2.1",
"Source": "Repository",
"Repository": "RSPM",
"Requirements": [
"tools"
],
"Hash": "50c838a310445e954bc13f26f26a6ecf"
},
"backports": {
"Package": "backports",
"Version": "1.4.1",
Expand Down
10 changes: 10 additions & 0 deletions renv/profiles/4.3/renv.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@
],
"Hash": "e8a22846fff485f0be3770c2da758713"
},
"assertthat": {
"Package": "assertthat",
"Version": "0.2.1",
"Source": "Repository",
"Repository": "RSPM",
"Requirements": [
"tools"
],
"Hash": "50c838a310445e954bc13f26f26a6ecf"
},
"backports": {
"Package": "backports",
"Version": "1.4.1",
Expand Down
67 changes: 67 additions & 0 deletions tests/testthat/test-calculate_study_day.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
ae <- data.frame(
USUBJID = c("study123-123", "study123-124", "study123-125"),
AESTDTC = c("2012-01-01", "2012-04-14", "2012-04-14"),
stringsAsFactors = FALSE
)
dm <- data.frame(
USUBJID = c("study123-123", "study123-124", "study123-125"),
RFSTDTC = c("2012-02-01", "2012-04-14", NA_character_),
stringsAsFactors = FALSE
)

test_that("`calculate_study_day()` works as expected for invalid input", {
expect_error(
calculate_study_day("a", "b", "C", "D", "E"),
"sdtm_in is not a data frame"
)
expect_error(
calculate_study_day(iris, "b", "C", "D", "E"),
"dm_domain is not a data frame"
)
expect_error(
calculate_study_day(iris, iris, "d", "e", "b"),
"dm_domain needs to have the variable of refdt"
)
expect_error(
calculate_study_day(iris, iris, "d", "Species"),
"sdtm_in needs to have the variable of tgdt"
)
expect_error(
calculate_study_day(iris, iris, "Petal.Length", "Species", "e"),
"needs to have the variable of merge_key"
)
expect_error(
calculate_study_day(iris, iris, "Petal.Length", "Species", 123L, "Species"),
"study_day_var is not a character vector"
)
expect_warning(
calculate_study_day(ae, dm, "AESTDTC", "RFSTDTC", "AENDY"),
"Target date and the returned study day doesn't match."
)

dm1 <- data.frame(
USUBJID = c("study123-123", "study123-123", "study123-125"),
RFSTDTC = c("2012-02-01", "2012-04-14", "2012-04-14"),
stringsAsFactors = FALSE
)
expect_warning(
calculate_study_day(ae, dm1, "AESTDTC", "RFSTDTC", "AESTDY"),
"Reference date is not unique for each patient!"
)

dm2 <- data.frame(
USUBJID = c("study123-123", "study123-124", "study123-125"),
RFSTDTC = c(123L, 456L, 789L),
stringsAsFactors = FALSE
)
expect_warning(
calculate_study_day(ae, dm2, "AESTDTC", "RFSTDTC", "AESTDY"),
"Encountered errors when converting refdt to dates."
)
})

test_that("`calculate_study_day()` works as expected for valid input", {
res <- calculate_study_day(ae, dm, "AESTDTC", "RFSTDTC", "AESTDY")
expected <- c(-31L, 1L, NA)
expect_equal(res$AESTDY, expected, tolerance = "1.5e-08")
})
Loading