Allow non-unique units columns (PKNCAconc & PKNCAdose)#435
Allow non-unique units columns (PKNCAconc & PKNCAdose)#435Gero1999 wants to merge 31 commits intohumanpred:mainfrom
Conversation
…ero1999/pknca into 416-custom_units_for_PKNCAdata
|
hey @billdenney I adapted some things we did on aNCA to include it as default behaviour in PKNCAdata. This should flexibilize the reading of unit columns in PKNCAconc (and PKNCAdose) related to #416. I added also tests to make sure this is translated into the results, but let me know if I miss something! I also added some #TODO comments of the main changes I needed to do to adapt the function to PKNCA |
|
Instead of creating a new |
…ero1999/pknca into 416-custom_units_for_PKNCAdata
| all_unit_cols <- c(concu_col, amountu_col, timeu_col, doseu_col) | ||
|
|
||
| # Join dose units with concentration group columns and units | ||
| d_concu <- o_conc$data %>% |
There was a problem hiding this comment.
Please use base R for readability:
unit_cols <- c(group_conc_cols, concu_col, amountu_col, timeu_col)
d_concu <- as.data.frame(o_conc)
d_concu <- unique(d_concu[, intersect(names(d_concu), unit_cols)])
unit_cols <- c(group_conc_cols, doseu_col)
d_doseu <- as.data.frame(o_dose)
d_doseu <- unique(d_doseu[, intersect(names(d_doseu), unit_cols)])
R/unit-support.R
Outdated
| groups_units_tbl <- merge(d_concu, d_doseu, all.x = TRUE) %>% | ||
| dplyr::mutate(dplyr::across(dplyr::everything(), ~ as.character(.))) %>% | ||
| dplyr::group_by(!!!rlang::syms(group_conc_cols)) %>% | ||
| tidyr::fill(!!!rlang::syms(all_unit_cols), .direction = "downup") %>% |
There was a problem hiding this comment.
Why is fill necessary here? It seems like it could go against the user's intent as they don't have units in their source data.
There was a problem hiding this comment.
It is to ignore so if there are NA values assume they are the same as the units in the group as indicated in the test:
test_that("PKNCAdata units (#336)", {
# Typical use
d_conc <- data.frame(conc = 1, time = 0, concu_x = "A", timeu_x = "B", amountu_x = "C")
d_dose <- data.frame(dose = 1, time = 0, doseu_x = "D")
o_conc <- PKNCAconc(data = d_conc, conc~time, concu = "concu_x", timeu = "timeu_x")
o_dose <- PKNCAdose(data = d_dose, dose~time, doseu = "doseu_x")
o_data <- PKNCAdata(o_conc, o_dose)
expect_equal(
o_data$units,
pknca_units_table(concu = "A", doseu = "D", timeu = "B")
)
suppressWarnings(o_nca <- pk.nca(o_data))
expect_true("Cmax (A)" %in% names(summary(o_nca)))
# NA unit values are ignored
d_conc <- data.frame(conc = 1, time = 0:1, concu_x = c("A", NA), timeu_x = "B", amountu_x = "C")
d_dose <- data.frame(dose = 1, time = 0, doseu_x = "D")
o_conc <- PKNCAconc(data = d_conc, conc~time, concu = "concu_x", timeu = "timeu_x")
o_dose <- PKNCAdose(data = d_dose, dose~time, doseu = "doseu_x")
o_data <- PKNCAdata(o_conc, o_dose)
expect_equal(
o_data$units,
pknca_units_table(concu = "A", doseu = "D", timeu = "B")
)
But I think you are right, should be the user who fixes this when the situation occurs. I will remove this test and the fill action.
R/unit-support.R
Outdated
|
|
||
| groups_units_tbl <- merge(d_concu, d_doseu, all.x = TRUE) %>% | ||
| dplyr::mutate(dplyr::across(dplyr::everything(), ~ as.character(.))) %>% | ||
| dplyr::group_by(!!!rlang::syms(group_conc_cols)) %>% |
There was a problem hiding this comment.
Please use dplyr::grouped_df() instead of indirection via rlang::syms().
| unique() | ||
|
|
||
| groups_units_tbl <- merge(d_concu, d_doseu, all.x = TRUE) %>% | ||
| dplyr::mutate(dplyr::across(dplyr::everything(), ~ as.character(.))) %>% |
There was a problem hiding this comment.
Why do we need to convert everything to character? I think that it should all be character from the original input. If it is not (perhaps it's a factor), then we should likely handle factor conversion elsewhere. This seems like it is possibly hiding a data problem from the user (possibly causing a hard-to-trace bug in the future) and should be corrected in source data rather than here.
There was a problem hiding this comment.
This is more to prevent NA values from creating conflicts during the group_by or the select_minimal_grouping_cols actions. It is only intended to ensure the units table is created, but it won't affect or change per ce the PKNCAdata input contents
R/unit-support.R
Outdated
| stop( | ||
| "Units should be uniform at least across concentration groups. ", | ||
| "Review the units for the next group(s):\n", | ||
| paste(utils::capture.output(print(mismatching_units_groups)), collapse = "\n") |
There was a problem hiding this comment.
Rather than capture.output, please directly generate the desired string like:
do.call(paste, lapply(X = names(d), FUN = function(x) paste(x, d[[x]], sep = "=")))
R/unit-support.R
Outdated
| units.are.all.na <- all(is.na(groups_units_tbl[,all_unit_cols])) | ||
| if (units.are.all.na) return(NULL) | ||
|
|
||
| groups_units_tbl %>% |
There was a problem hiding this comment.
Please convert this to a loop for readability (it will only likely be called a few times, so it should not be a performance issue).
| #' 2. If a column does not exist, it creates the column and assigns default values. | ||
| #' 3. If not default values are provided, it assigns NA to the new column. | ||
| #' @keywords Internal | ||
| ensure_column_unit_exists <- function(pknca_obj, unit_name) { |
There was a problem hiding this comment.
I think that this is already handled as part of the pknca_set_units() function. Can this function be eliminated, and if not, can you please explain why not?
There was a problem hiding this comment.
the problem I see is that pknca_set_units() does not guarantee the physical unit column to be made if not present. This helper/wrapper function does this by introducing NA values if not there
R/unit-support.R
Outdated
| } | ||
|
|
||
| # Add globalVariables for NSE/dplyr/rlang/tidyr usage | ||
| utils::globalVariables(c( |
There was a problem hiding this comment.
Please use double colon notation or rlang::.data rather than globalVariables()
|
Please also merge the current main branch upon making the above changes. |
…PKNCAdata (conflicts with no real issue in unit-support.R & NAMESPACE)
…espacing instead f globalVariables
…make sure no additional warnings for row.names appear
Makes
PKNCAdata$unitstable able to include any group variable stratifying the units in PKNCAconc / PKNCAdose .Implementation Summary:
Added
pknca_units_table_from_pknca. Creates a default units table based on a PKNCAconc object (and optionally PKNCAdose as well).Introduced helper functions
ensure_column_unit_existsandselect_minimal_grouping_colsto support unit column validation and minimal grouping column selection.Updated PKNCAdata.default to replace manual unit table construction with the new
pknca_units_table_from_pkncafunction.Added tests for pknca_units_table_from_pknca to verify its behavior with various scenarios, including:
Added new imports (dplyr, rlang, tidyr, utils) and exported pknca_units_table_from_pknca to make the new functionality accessible.