88# ' @param obs_compartment the observation compartment number
99# ' @param covariates a vector of covariate names that are to be extracted
1010# ' and added to the modeling dataset.
11+ # ' @param na what to set NA values to. E.g. ".", (default) or NA (keep NA),
12+ # ' or NULL (do nothing).
13+ # ' @param repeat_doses Optional list for repeated dosing (MAD studies). Must
14+ # ' contain `interval` (dosing interval in TIME units). Optionally contains `n`
15+ # ' (total number of doses). If `n` is omitted, it is inferred per subject/group
16+ # ' as `ceiling(max(observation_time) / interval)`. Only applies to column-wise
17+ # ' dose data. Default `NULL` preserves existing behavior (no ADDL/II columns).
18+ # ' Examples: `list(interval = 12)` or `list(n = 5, interval = 12)`.
1119# '
1220# ' @returns data.frame with population PK input data in NONMEM-style
1321# ' format.
14- # '
22+ # '
1523# ' @export
1624reformat_data_nca_to_modeling <- function (
17- data ,
25+ data ,
1826 dictionary = list (
1927 subject_id = " ID" ,
2028 group = " GROUP" ,
@@ -24,7 +32,9 @@ reformat_data_nca_to_modeling <- function(
2432 ),
2533 dose_compartment = 1 ,
2634 obs_compartment = 1 ,
27- covariates = NULL
35+ covariates = NULL ,
36+ repeat_doses = NULL ,
37+ na = " ."
2838) {
2939
3040 groups <- c(dictionary $ subject_id , dictionary $ group )
@@ -56,12 +66,40 @@ reformat_data_nca_to_modeling <- function(
5666 dplyr :: filter(! is.na(AMT )) | >
5767 dplyr :: mutate(EVID = 1 , MDV = 1 , DV = 0 , CMT = dose_compartment ) | >
5868 dplyr :: left_join(ids , by = dplyr :: join_by(" ORIGID" ))
69+
5970 if (nrow(doses ) == nrow(data )) { # Dose is given as a column, and not row-wise using EVID
6071 doses <- doses | >
6172 dplyr :: group_by(.data $ ORIGID , .data $ GROUP ) | >
6273 dplyr :: slice(1 ) | >
6374 dplyr :: mutate(TIME = 0 ) | >
6475 dplyr :: ungroup()
76+
77+ if (! is.null(repeat_doses )) {
78+ if (is.null(repeat_doses $ interval )) {
79+ stop(" `repeat_doses` must contain an `interval` element." )
80+ }
81+ interval <- repeat_doses $ interval
82+ if (! is.null(repeat_doses $ n )) {
83+ doses <- doses | >
84+ dplyr :: mutate(ADDL = as.numeric(repeat_doses $ n ) - 1 , II = interval )
85+ } else {
86+ max_obs_times <- data | >
87+ dplyr :: select(
88+ ORIGID = !! dictionary $ subject_id ,
89+ GROUP = !! dictionary $ group ,
90+ TIME = !! dictionary $ time
91+ ) | >
92+ dplyr :: group_by(.data $ ORIGID , .data $ GROUP ) | >
93+ dplyr :: summarise(max_obs_time = max(.data $ TIME , na.rm = TRUE ), .groups = " drop" )
94+ doses <- doses | >
95+ dplyr :: left_join(max_obs_times , by = c(" ORIGID" , " GROUP" )) | >
96+ dplyr :: mutate(
97+ ADDL = pmax(0 , ceiling(.data $ max_obs_time / interval ) - 1 ),
98+ II = interval
99+ ) | >
100+ dplyr :: select(- " max_obs_time" )
101+ }
102+ }
65103 }
66104
67105 # # Observations
@@ -78,15 +116,19 @@ reformat_data_nca_to_modeling <- function(
78116 stringr :: str_detect(tolower(.data $ DV ), " [<a-z]" ), - 99 , .data $ DV
79117 ))) | >
80118 dplyr :: left_join(ids , by = dplyr :: join_by(" ORIGID" ))
81-
119+
120+ if (! is.null(repeat_doses )) {
121+ samples <- samples | > dplyr :: mutate(ADDL = 0 , II = 0 )
122+ }
123+
82124 # # Combine
83125 comb <- dplyr :: bind_rows(
84126 doses ,
85127 samples
86128 ) | >
87129 dplyr :: mutate(ifelse(is.null(.data $ GROUP ), 1 , .data $ GROUP )) | >
88130 dplyr :: arrange(!! dictionary $ subject_id , !! dictionary $ group , !! dictionary $ time , .data $ EVID ) | >
89- dplyr :: select(" ID" , " TIME" , " CMT" , " EVID" , " MDV" , " DV" , " AMT" , " GROUP" , " ORIGID" , !! covariates ) | >
131+ dplyr :: select(" ID" , " TIME" , " CMT" , " EVID" , " MDV" , " DV" , " AMT" , dplyr :: any_of(c( " ADDL " , " II " )), " GROUP" , " ORIGID" , !! covariates ) | >
90132 dplyr :: arrange(.data $ GROUP , .data $ ID , .data $ TIME , - .data $ EVID )
91133
92134 # # Convert all character columns to categorical (but numeric)
@@ -99,7 +141,14 @@ reformat_data_nca_to_modeling <- function(
99141 }
100142
101143 # # Remove any observations with DV = -99
102- comb <- dplyr :: filter(comb , .data $ DV != - 99 )
144+ comb <- comb | >
145+ dplyr :: filter(.data $ DV != - 99 )
146+
147+ # # Convert NA's to dots or something else
148+ if (! is.null(na )) {
149+ comb <- comb | >
150+ dplyr :: mutate(dplyr :: across(dplyr :: everything(), ~ ifelse(is.na(. ) | . == " NA" , na , . )))
151+ }
103152
104153 # # Return
105154 comb
0 commit comments