PKNCA (Perform Pharmacokinetic Non-Compartmental Analysis) is an R package that computes standard NCA parameters for pharmacokinetic analyses and summarizes them. It has been cross-validated with Phoenix WinNonlin and Pumas. Licensed under AGPL-3.
devtools::load_all() # Load package for interactive testing
devtools::test() # Run full testthat suite
devtools::test_active_file("tests/testthat/test-auc.R") # Run a single test file
devtools::check() # Full R CMD check
devtools::document() # Regenerate roxygen2 docs + NAMESPACE
pkgdown::build_site() # Build documentation website
spelling::spell_check_package() # Spell check (wordlist: inst/WORDLIST)R/ # Source code (47 files)
man/ # Auto-generated roxygen2 documentation (do not edit by hand)
tests/testthat/ # testthat test files (43 tests + helper)
vignettes/ # Rmd vignettes (19 files)
data-raw/ # Scripts that generate package datasets
inst/ # Installed files (CITATION, WORDLIST)
courses/ # Training materials and presentations
.github/workflows/ # CI: R-CMD-check, test-coverage, pkgdown
A typical PKNCA analysis follows this pipeline:
# 1. Wrap concentration-time data
my.conc <- PKNCAconc(d.conc, conc~time|subject)
# 2. Wrap dosing data
my.dose <- PKNCAdose(d.dose, dose~time|subject)
# 3. Combine into a data object (intervals auto-generated from dose times)
my.data <- PKNCAdata(my.conc, my.dose)
# 4. Run NCA calculations
my.results <- pk.nca(my.data)
# 5. View results
summary(my.results)
as.data.frame(my.results)PKNCAconc(data, formula, ...) wraps concentration-time data.
- Formula:
conc~time|groups(e.g.,conc~time|Study+Subject/Analyte) - The last group variable (or the one before
/) defaults as thesubjectcolumn - Sparse PK: set
sparse = TRUEfor sparse sampling designs - Optional args:
volume,duration(for urine/feces),time.nominal,exclude,exclude_half.life/include_half.life - Unit args:
concu,amountu,timeuaccept scalar values (e.g.,"ng/mL") or column names in the data;concu_pref,amountu_pref,timeu_prefset preferred reporting units
PKNCAdose(data, formula, ...) wraps dosing data.
- Formula:
dose~time|groups; supports one-sided formulas (omit dose or time with.) - Route:
routeparameter --"extravascular"(default) or"intravascular"(column name or scalar) - IV dosing: specify
rateorduration(not both); bolus assumed if neither given - Unit args:
doseu(scalar or column name);doseu_preffor preferred reporting units
PKNCAdata(data.conc, data.dose, ...) combines concentration + dose + intervals.
- Accepts
PKNCAconc/PKNCAdoseobjects or raw data.frames (withformula.conc/formula.dose) - Intervals: auto-generated from dose times if omitted; pass a data.frame for manual specification
- Units: auto-built via
pknca_units_table()from unit columns on PKNCAconc/PKNCAdose if omitted; or supply a manual table - Imputation:
imputeparameter for data imputation methods (seevignette("v08-data-imputation")) - Options:
optionslist forPKNCA.options()overrides
Units flow from PKNCAconc (concu, amountu, timeu) and PKNCAdose (doseu) through to derived NCA parameter units:
- Scalar or column-based: unit args accept a string (e.g.,
"ng/mL") applied to all rows, or a column name for per-row stratification pknca_units_table()builds the full mapping from base units to derived units (AUC =time*conc, clearance =dose/(time*conc), etc.)- Preferred units:
*_prefargs enable automatic conversion (requires theunitspackage) - Auto-build:
PKNCAdata()callspknca_units_table()automatically when nounitsargument is supplied
Example with units:
my.conc <- PKNCAconc(d.conc, conc~time|subject,
concu = "ng/mL", timeu = "hr", amountu = "mg")
my.dose <- PKNCAdose(d.dose, dose~time|subject, doseu = "mg/kg")
my.data <- PKNCAdata(my.conc, my.dose) # units table auto-generatedAll classes use S3 dispatch (not S4 or R6):
| Class | Purpose | Defined in |
|---|---|---|
PKNCAconc |
Concentration-time data | class-PKNCAconc.R |
PKNCAdose |
Dosing data | class-PKNCAdose.R |
PKNCAdata |
Combined data + intervals + units + options | class-PKNCAdata.R |
PKNCAresults |
NCA calculation results | class-PKNCAresults.R |
summary_PKNCAresults |
Summary statistics | class-summary_PKNCAresults.R |
dplyr verbs are supported on these classes: filter, mutate, group_by, inner_join, full_join (see R/dplyr.R).
- Functions: dot notation --
pk.calc.cmax(),pk.calc.auc(),clean.conc.blq(),business.geomean() - Validation:
assert_*with underscores --assert_conc(),assert_conc_time()(exception to dot convention) - Class constructors: PascalCase --
PKNCAconc(),PKNCAdose(),PKNCAdata() - File naming:
class-*.Rfor class definitions- Some legacy files use numbered prefixes (
001-add.interval.col.R) orzzz-prefixes for load order -- do not create new files with these prefixes - New files should use descriptive names (e.g.,
half.life.R,interpolate.conc.R) - Test files mirror source:
R/auc.R->tests/testthat/test-auc.R
- Style guide: tidyverse (package is slowly migrating from older dot-style; don't restyle unrelated code)
- Documentation: roxygen2 with Markdown syntax (
Roxygen: list(markdown = TRUE)in DESCRIPTION)- Use
@inheritParamsand@rdnameto avoid duplication - Use
@family PKNCA objectsto group related class documentation - Use
@keywords Internalfor non-exported helper functions
- Use
- Validation:
checkmatepackage for input validation;rlang::warn()with custom error classes (e.g.,"pknca_conc_none") - Deprecation:
lifecyclepackage for managing deprecated functions (seeR/defunct.R) - Global options: managed through
PKNCA.options()/PKNCA.choose.option()inR/PKNCA.options.R
- Framework: testthat Edition 3 (
Config/testthat/edition: 3in DESCRIPTION) - No snapshot tests -- use explicit expected-value comparisons
- Numerical tolerance: use
tolerance=inexpect_equal()for floating-point PK calculations - Test data generators:
generate.conc(nsub, ntreat, time.points)andgenerate.dose(concdata)intests/testthat/helper-generate_data.R - Global state: save and restore
PKNCA.options()when modifying options in tests - Validation tests: use
expect_error(..., regexp=)andexpect_warning(..., regexp=)for input validation - Spelling: checked via
spelling::spell_check_package()with custom wordlist atinst/WORDLIST
Three GitHub Actions workflows in .github/workflows/:
| Workflow | Trigger | What it does |
|---|---|---|
R-CMD-check.yaml |
push to main, PRs | R CMD check on macOS (release), Windows (release), Ubuntu (devel, release, oldrel-1) |
test-coverage.yaml |
push to main, PRs | Code coverage via covr, uploads to Codecov |
pkgdown.yaml |
push to main, PRs, releases | Builds and deploys documentation site to GitHub Pages |
Build args: --no-manual --compact-vignettes=gs+qpdf
- Update
NEWS.mdfor user-facing changes (bullet under current dev version header, with GitHub username and issue/PR links) - Include testthat tests with contributions
- Don't restyle code outside your change scope
- Run
devtools::document()after changing any roxygen2 comments -- always verify thatman/files andNAMESPACEare up to date - Run
devtools::check()before submitting -- must pass cleanly - Add new words to
inst/WORDLISTif spell check flags domain-specific terms