Skip to content

Refactoring with checkmate and rlang#548

Open
PavanLomati wants to merge 4 commits into
humanpred:mainfrom
PavanLomati:checkmate-rlang-refactor
Open

Refactoring with checkmate and rlang#548
PavanLomati wants to merge 4 commits into
humanpred:mainfrom
PavanLomati:checkmate-rlang-refactor

Conversation

@PavanLomati

Copy link
Copy Markdown
Contributor

No description provided.

@PavanLomati PavanLomati requested a review from billdenney May 27, 2026 04:18
@billdenney

Copy link
Copy Markdown
Member

This looks like it will make all of the code more consistent. Thank you!. Please merge in the current origin/main branch and resolve the conflicts.

Also, for many of the checkmate calls, you've added .var.name = "name" or similar where name is the parameter name used. Please omit those as they are not necessary since they are the default that checkmate will provide.

…ng-refactor

# Conflicts:
#	R/001-add.interval.col.R
#	R/PKNCA.options.R
#	R/assertions.R
#	R/auc.R
#	R/aucint.R
#	R/class-PKNCAdata.R
#	R/class-PKNCAdose.R
#	R/class-general.R
#	R/class-summary_PKNCAresults.R
#	R/exclude.R
#	R/interpolate.conc.R
#	R/pk.calc.all.R
#	R/pk.calc.c0.R
#	R/superposition.R
#	R/tss.R
#	R/tss.monoexponential.R
#	R/tss.stepwise.linear.R
#	tests/testthat/test-PKNCA.options.R
Comment thread R/assertions.R
end,
interval[2]
),
class = "pknca_error_interval_mismatch"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that all class values differ. This is the same as the one a few lines above, and part of the goal of setting the classes is to be able to differentiate errors by class for programmatic capturing by other tools (e.g. ANCA or ruminate).

Comment thread R/assertions.R
# stricter.
stop(unit_col, call. = FALSE)
rlang::abort(
message = conditionMessage(attr(unit_col, "condition")),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditionMessage() here seems like it is not required. Please remove it or let me know why it is necessary.

Comment thread R/auc.R
if ("auc.type" %in% names(list(...)))
stop("auc.type cannot be changed when calling pk.calc.auc.inf, please use pk.calc.auc")
rlang::abort(
message = paste(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use paste() as that can make finding the error message harder to diagnose problems.

Comment thread R/auc.R
if ("auc.type" %in% names(list(...)))
stop("auc.type cannot be changed when calling pk.calc.auc.all, please use pk.calc.auc")
rlang::abort(
message = paste(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about not using paste. Please apply that throughout.

Comment thread R/auc.R
"auc.type cannot be changed when calling pk.calc.aumc.all,",
"please use pk.calc.aumc"
),
class = "pknca_error_aumc_type_override"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make the class unique here, too.

Comment thread R/aucint.R
#' quantification; this is used for AUCinf calculations. If provided as
#' `clast.obs` (observed clast value, default), AUCinf is AUCinf,obs. If
#' provided as `clast.pred`, AUCinf is AUCinf,pred.
#' provided as `clast.pred`, AUCinf is AUCinf,pred.#'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extraneous #' was added to the end of this line. Please remove it.


test_that("add.interval.col", {
# Invalid inputs fail
expect_error(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reinstate all of the tests where they are using the new regexp, if applicable. (You can remove the "info" part.)

@billdenney

Copy link
Copy Markdown
Member

@PavanLomati

Here are the comprehensive findings:

Additional review findings

These supplement the 6 inline comments already on the diff (non-unique classes, conditionMessage(), paste() in messages, stray #'). They're organized by class, highest-leverage first. All behavioral claims were verified against the base branch.

Severity token missing from some preexisting condition classes — breaks class-based capture

Three internal "report a bug" errors are raised with a pknca_internal_* class instead of pknca_error_*:

  • pknca_internal_pk_tss_ret_non_naR/tss.R
  • pknca_internal_dose_scalingR/superposition.R
  • pknca_internal_unknown_nca_unitsR/unit-support.R

Their siblings correctly use pknca_error_internal_* (pknca_error_internal_tlast in R/auc.R, pknca_error_internal_clast_na in R/aucint.R). A handler filtering on pknca_error_* will silently miss the three pknca_internal_* ones. Please standardize on pknca_error_internal_*.

Negative-path tests deleted instead of migrated — coverage regression

Please restore the tests to match the previous intent.

Across ~10 test files, the expect_error(..., regexp=) cases that exercised the exact validation being refactored were removed rather than updated to the new message/class:

  • test-001-add.interval.col.R — entire ~20-case input-validation block (name/FUN/pretty_name/datatype/desc/depends/formalsmap) deleted
  • test-PKNCA.options.R — ~18 scalar/factor/NA/"must be a number" checks across nine options, plus PKNCA.set.summary point/spread/description checks
  • test-superpostion.Radditional.times non-numeric/negative/>tau and steady.state.tol checks
  • test-set_and_assert_intervals.R — 3 whole test_that blocks
  • Same pattern in test-time.above.R, test-pk.calc.c0.R, test-class-PKNCAconc.R, test-class-PKNCAdata.R, test-class-PKNCAdose.R, test-exclude.R, test-assertions.R, test-time.to.steady.state.R

The new behavior is now less tested than the old. Please convert these to expect_error(..., class="pknca_error_...") instead of deleting them.

checkmate semantics quietly differ from the manual checks they replaced

Please add tests for where these tests are stricter:

CI can't catch these because the negative tests (finding 2) were deleted. All verified against base:

  • finite=TRUE added where the old code accepted Inf: pk.calc.aucabove now uses assert_number(conc_above, na.ok=TRUE, finite=TRUE); old stopifnot(is.numeric, length==1) allowed Inf. conc_above=Inf now errors.
  • all-NA acceptance: assert_character/assert_numeric accept an all-NA logical vector by default, where is.character()/is.numeric() rejected it. In R/exclude.R the old else if (!is.character(reason)) became an unconditional assert_character(reason), so reason=NA now passes the type gate. (add.interval.col intentionally relies on this for FUN=NA, but the relaxation is silent elsewhere.)
  • Newly stricter, not in the original: add.interval.col adds min.chars=1 to name (rejects "") and unique=TRUE on formalsmap names; R/impute.R assert_scalar(impute) rejects a length-1 list that length(impute)==1 accepted.

None look dangerous, but they're undocumented behavior changes with no test pinning them.

Please find remaining stop and warning calls

"Replaced all stop() and warning() calls" — but genuine sites remain at the PR head:

  • stop() in R/auc_integrate.R (the idx_tlast "must occur exactly once" check — not nocov), R/prepare_data.R:165, R/time.above.R:86
  • warning() in R/pk.calc.all.R:143 (re-raises a captured condition)

.Rbuildignore references a file not in the repo

The PR adds ^coverage_check\.R$ and strips the trailing newline, but coverage_check.R is not part of the PR or repo — a leftover local-scratch reference. Please drop the line and restore the trailing newline.

Whitespace / formatting issues

Pervasive enough to be a class:

  • ) } — closing brace fused onto an abort()/warn() close paren: ~11 sites (e.g. R/auc.R, R/class-PKNCAdata.R, R/superposition.R, R/tss.monoexponential.R, R/exclude.R, R/class-general.R, R/001-add.interval.col.R)
  • Zero/under-indentation: R/pk.calc.c0.R (assert_number + if at column 0), R/PKNCA.options.R (if (default && check)), R/class-summary_PKNCAresults.R (} else if)
  • Comments displaced onto code lines: R/PKNCA.options.R (assert_number(...) # Must be between 0 and 1), R/aucint.R (} else if (...) { # If using clast.pred…)
  • Inconsistent ){ (no space), stray trailing whitespace, and two new "No newline at end of file" (R/pk.calc.simple.R, .Rbuildignore)

A styler/lintr pass clears all of these.

Commented-out dead code left behind (8 sites)

Beyond the #stop(unit_col, …) already noted: #c("interval", …) (R/001-add.interval.col.R), #checkmate::assert_number(… max.missing) (R/PKNCA.options.R), #checkmate::assertNumeric(x$start …) (R/check.intervals.R), #stopifnot(inherits(… o_conc/o_dose)) ×2 and # stopifnot(…cols…) ×2 (R/prepare_data.R), and the trailing assert_number(tlast)#, finite = TRUE) (R/auc_integrate.R).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants