Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
## Bug fixes

### NCA Calculations
* `exclude_half.life` is now initialized to `NA` instead of `FALSE` (matching `include_half.life`), so manually selecting half-life points to include no longer errors with "Cannot both include and exclude half-life points for the same interval" under the development version of PKNCA
* Renal clearance (RENALCL) removed from direct PK calculations (inaccurate in PKNCA) — use ratio table instead (#781)
* Multidose parameters (MRTMDO, MRTMDP, VSSMDO, VSSMDP, TAT) removed from direct calculations (#869)
* Last dose interval end time extends to last observed sample instead of being cut off at tau (#1235)
Expand Down
8 changes: 6 additions & 2 deletions R/PKNCA.R
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ PKNCA_create_data_object <- function( # nolint: object_name_linter
df_conc$is.excluded.hl <- FALSE
df_conc$is.included.hl <- FALSE
df_conc$REASON <- ""
df_conc$exclude_half.life <- FALSE
# NA (not FALSE) marks "no half-life exclusion yet". This mirrors how
# include_half.life is left NA until a point is selected and prevents PKNCA's
# "cannot both include and exclude half-life points" check from firing when
# only inclusions are set (an all-FALSE column counts as "in use").
df_conc$exclude_half.life <- NA

# Create PKNCA conc object

Expand Down Expand Up @@ -869,7 +873,7 @@ check_valid_pknca_data <- function(processed_pknca_data, check_exclusion_has_rea
time_col <- processed_pknca_data$conc$columns$time

has_no_reason <- (nchar(data_conc[["REASON"]]) == 0) | is.na(data_conc[["REASON"]])
has_hl_excl <- data_conc[[excl_hl_col]]
has_hl_excl <- data_conc[[excl_hl_col]] %in% TRUE
missing_reasons <- has_hl_excl & has_no_reason

if (any(missing_reasons)) {
Expand Down
8 changes: 4 additions & 4 deletions R/get_halflife_plots.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ get_halflife_plots <- function(pknca_data, add_annotations = TRUE,

# Make sure to create a default exclude half life column if it does not exist
if (is.null(exclude_hl_col)) {
pknca_data$conc$data[["exclude_half.life"]] <- FALSE
pknca_data$conc$data[["exclude_half.life"]] <- NA
exclude_hl_col <- "exclude_half.life"
}

Expand Down Expand Up @@ -114,7 +114,7 @@ get_halflife_plots <- function(pknca_data, add_annotations = TRUE,
tlast = tlast + start,
is_halflife_used = .[[time_col]] >= lambda.z.time.first &
.[[time_col]] <= lambda.z.time.last &
!.[[exclude_hl_col]]
!(.[[exclude_hl_col]] %in% TRUE)
) %>%
group_by(!!!syms(c(group_vars(pknca_data), "start", "end"))) %>%
mutate(
Expand All @@ -133,9 +133,9 @@ get_halflife_plots <- function(pknca_data, add_annotations = TRUE,
info_per_plot_list <- info_per_plot_list %>%
mutate(
color = "black",
color = ifelse(.[[exclude_hl_col]], "red", color),
color = ifelse(.[[exclude_hl_col]] %in% TRUE, "red", color),
color = ifelse(is_halflife_used & !is.na(is_halflife_used), "green", color),
symbol = ifelse(.[[exclude_hl_col]], "x", "circle")
symbol = ifelse(.[[exclude_hl_col]] %in% TRUE, "x", "circle")
) %>%
group_by(!!!syms(c(group_vars(pknca_data), "start", "end"))) %>%
group_split()
Expand Down
5 changes: 3 additions & 2 deletions R/pivot_wider_pknca_results.R
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ pivot_wider_pknca_results <- function(myres, flag_rules = NULL, extra_vars_to_ke
group_by(!!!syms(conc_groups), DOSNOA) %>%
# Derive LAMZMTD: was lambda.z manually customized?
mutate(LAMZMTD = ifelse(
any(exclude_half.life) | any(include_half.life), "Manual", "Best slope"
any(exclude_half.life %in% TRUE) | any(include_half.life %in% TRUE),
"Manual", "Best slope"
)) %>%
filter(!exclude_half.life | is.na(LAMZLL) | is.na(LAMZNPT)) %>%
filter(!(exclude_half.life %in% TRUE) | is.na(LAMZLL) | is.na(LAMZNPT)) %>%
filter(!!sym(time_col) >= (LAMZLL + start) | is.na(LAMZLL)) %>%
filter(row_number() <= LAMZNPT | is.na(LAMZNPT)) %>%
mutate(LAMZIX = paste0(IX, collapse = ",")) %>%
Expand Down
4 changes: 3 additions & 1 deletion inst/shiny/functions/utils-slope_selector.R
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ handle_hl_adj_change <- function(new_pknca_data, old_pknca_data, plot_outputs) {
new_concdata <- new_pknca_data$conc$data
old_concdata <- old_pknca_data$conc$data

ix_excl_changes <- which(new_concdata[[excl_hl_col]] != old_concdata[[excl_hl_col]])
ix_excl_changes <- which(
(new_concdata[[excl_hl_col]] %in% TRUE) != (old_concdata[[excl_hl_col]] %in% TRUE)
)
ix_incl_changes <- which(
paste0(new_concdata[[incl_hl_col]]) != paste0(old_concdata[[incl_hl_col]])
)
Expand Down
4 changes: 2 additions & 2 deletions tests/testthat/test-PKNCA.R
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,8 @@ describe("PKNCA_update_data_object", {
# t=3 should be flagged for exclusion with the specified reason
expect_true(all(conc$exclude_half.life[at_t3]))
expect_true(all(grepl("Outlier", conc$REASON[at_t3])))
# Other points should remain unflagged
expect_false(any(conc$exclude_half.life[!at_t3]))
# Other points should remain unflagged (NA, mirroring include_half.life)
expect_true(all(is.na(conc$exclude_half.life[!at_t3])))
})

it("flags include_half.life on matching points via hl_adj_rules Selection", {
Expand Down
5 changes: 5 additions & 0 deletions tests/testthat/test-export_cdisc.R
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ describe("export_cdisc", {
})

it("differentiates vz.xxx for extravascular (bioavailability, F) and intravascular", {
# The development version of PKNCA adds new vz.* parameters (e.g. vz.last)
# that aNCA's CDISC export does not yet map, so extra Vz rows appear. Skip on
# CRAN so an upcoming PKNCA release cannot block CRAN; the gap still surfaces
# off-CRAN in runs against PKNCA dev.
skip_on_cran()
test_vz_data <- FIXTURE_PKNCA_DATA
test_vz_data$intervals <- test_vz_data$intervals %>%
filter(USUBJID %in% unique(USUBJID)[c(5, 7)]) %>%
Expand Down
6 changes: 3 additions & 3 deletions tests/testthat/test-get_halflife_plots.R
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ describe("get_halflife_plot", {

it("renders markers, colors and shapes with no exclusion/inclusion", {
pknca_no_excl_incl <- base_pknca
pknca_no_excl_incl$conc$data$exclude_half.life <- FALSE
pknca_no_excl_incl$conc$data$include_half.life <- FALSE
pknca_no_excl_incl$conc$data$exclude_half.life <- NA
pknca_no_excl_incl$conc$data$include_half.life <- NA
plots <- withCallingHandlers(
get_halflife_plots(pknca_no_excl_incl)[["plots"]],
# Ignore the warning associated with the expected missing records
Expand Down Expand Up @@ -138,7 +138,7 @@ describe("get_halflife_plot", {
it("renders markers, colors and shapes with inclusion of lambda.z points", {
pknca_incl <- base_pknca
pknca_incl$intervals <- pknca_incl$intervals[3, ]
pknca_incl$conc$data$exclude_half.life <- FALSE
pknca_incl$conc$data$exclude_half.life <- NA
pknca_incl$conc$data$include_half.life <- NA
pknca_incl_with_incl <- pknca_incl
pknca_incl_with_incl$conc$data <- pknca_incl$conc$data %>%
Expand Down
5 changes: 5 additions & 0 deletions tests/testthat/test-pivot_wider_pknca_results.R
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ describe("pivot_wider_pknca_results", {
})

it("adds appropriate labels to columns (CDISC PPTEST)", {
# The development version of PKNCA emits new parameters (e.g. lambda.z.corrxy)
# that aNCA's CDISC label/parameter mapping does not yet cover, which changes
# the expected label set. Skip on CRAN so an upcoming PKNCA release cannot
# block CRAN; the mismatch still surfaces in local/CI runs against PKNCA dev.
skip_on_cran()
labels <- formatters::var_labels(pivoted_res)
expected_labels <- c(
PCSPEC = NA, USUBJID = NA, PARAM = NA, start = NA, end = NA, ATPTREF = NA,
Expand Down
Loading