make_adpc.RdOne record per subject, analyte and timepoint, carrying nominal and actual time from first dose, actual time since the most recent dose, the dose in force, subject-level covariates, and an explicit, documented policy for values below the limit of quantification.
make_adpc(
pc,
adsl,
ex = NULL,
blq = c("half", "zero", "drop", "keep"),
lloq = NULL,
keep = NULL
)Concentration data: one record per subject, analyte and timepoint.
Must contain USUBJID, PARAMCD, the concentration column AVAL and the
actual time column AFRLT. NFRLT, PARAM, AVISIT, AVALU and LLOQ
are carried when present.
Subject-level dataset with USUBJID. Columns named in keep
are merged onto every record.
Optional dosing data with USUBJID, EXDOSE and a dose time in
AFRLT (and NFRLT for the nominal dose time). When supplied, ARRLT,
NRRLT and EXDOSE are derived from it. When NULL, time since dose is
taken to be time since first dose, which is only correct for a single-dose
profile — the function says so with a warning.
BLQ policy: "half", "zero", "drop" or "keep".
Limit of quantification to use when pc has no LLOQ column.
A single number, applied to every record.
Character vector of adsl columns to carry onto the analysis
dataset. NULL (default) carries every column of adsl except USUBJID
and any name already present in pc.
An eradam_adpc object: a tibble::tibble with one record per
subject, analyte and timepoint.
A record is treated as BLQ when its concentration is missing (the usual way
a <LLOQ result arrives once PCSTRESN has been left empty) or when it is
strictly below the limit of quantification in force. BLQFL records that
judgement on every record, whatever the policy, so the count is always
recoverable from the delivered dataset.
The policy is an argument because no standard picks one for you. Regulatory guidance is silent and the pharmacometrics literature treats the choice as part of the analysis (Beal, "Ways to fit a PK model with some data below the quantification limit", J Pharmacokinet Pharmacodyn 2001, describes the M1–M7 family; dropping BLQ is M1, imputing is M5/M6).
"half" (default) — AVAL is set to LLOQ / 2 and DTYPE to "LOQ".
"zero" — AVAL is set to 0 and DTYPE to "LOQ".
"drop" — the record is removed from the dataset entirely.
"keep" — AVAL is left missing and ANL01FL is not set.
DTYPE = "LOQ" is the ADaM controlled-terminology value for a record whose
analysis value was imputed from the limit of quantification, so an imputed
record is always distinguishable from an observed one.
Variable names follow the CDISC ADaM Implementation Guide for
Non-compartmental Analysis Input Data (ADNCA v1.0): NFRLT, AFRLT,
NRRLT, ARRLT for nominal and actual time from first and from most recent
dose, with ARRLT negative on pre-dose records. DTYPE, AVAL, AVALC,
AVALU, PARAMCD, PARAM and ANL01FL are standard ADaM BDS variables.
BLQFL and LLOQ are not CDISC-standard names; this package uses them
because a delivered PK dataset is unusable without them being somewhere.
This function replaces the SAS idiom of a PROC SORT + DATA step over
PC/EX with a retained "last dose time" variable and an if PCSTRESC = '<LLOQ' then ... block.
| Variable | Meaning | Source |
STUDYID | Study identifier | pc |
USUBJID | Unique subject identifier | pc |
PARAMCD | Analyte code | pc |
PARAM | Analyte description | pc |
AVISIT | Analysis visit | pc (kept when present) |
NFRLT | Nominal time from first dose (h) | pc |
AFRLT | Actual time from first dose (h) | pc |
NRRLT | Nominal time from most recent dose (h) | Derived from ex nominal dose times |
ARRLT | Actual time from most recent dose (h); negative before the first dose | Derived from ex actual dose times |
AVAL | Analysis concentration after the BLQ policy has been applied | pc / derived |
AVALC | Character analysis value; the reported result, or "<lloq" (e.g. "<0.5") for BLQ records | Derived |
AVALU | Concentration unit | pc (kept when present) |
LLOQ | Lower limit of quantification in force for the record | pc column LLOQ or argument lloq |
BLQFL | "Y" when the original result was below the limit of quantification | Derived |
DTYPE | "LOQ" when AVAL was imputed from the limit of quantification, otherwise NA | Derived (ADaM DTYPE codelist) |
EXDOSE | Dose amount in effect at the sample time | ex |
ANL01FL | "Y" when AVAL is non-missing and the record is usable for analysis | Derived |
<covariates> | Subject-level variables carried from ADSL | adsl (argument keep) |
pc <- eradam_example("pc")
ex <- eradam_example("ex")
adsl <- eradam_example("adsl")
adpc <- make_adpc(pc, adsl, ex)
adpc
#>
#> ── eradam ADPC ─────────────────────────────────────────────────────────────────
#> ℹ 576 record(s) | 24 subject(s) | 2 analyte(s)
#> ℹ BLQ policy: half | 48 BLQ record(s) in output
#> # A tibble: 576 × 24
#> STUDYID USUBJID PARAMCD PARAM AVISIT NFRLT AFRLT NRRLT ARRLT AVAL AVALC
#> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
#> 1 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 0 0 0 0 0.25 <0.5
#> 2 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 0.5 0.58 0.5 0.58 230. 229.…
#> 3 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 1 1.01 1 1.01 348. 347.…
#> 4 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 2 2.03 2 2.03 378. 378.…
#> 5 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 4 4.03 4 4.03 355. 355.…
#> 6 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 8 7.99 8 7.99 139. 139.…
#> 7 ERADAM01 ERADAM01-… DRUGX DRUG… Day 1 12 12.0 12 12.0 83.1 83.0…
#> 8 ERADAM01 ERADAM01-… DRUGX DRUG… Day 2 24 23.9 0 23.9 14.8 14.7…
#> 9 ERADAM01 ERADAM01-… DRUGX DRUG… Day 2 25 25.0 1 1.03 343. 343.…
#> 10 ERADAM01 ERADAM01-… DRUGX DRUG… Day 2 28 28.0 4 3.98 298. 297.…
#> # ℹ 566 more rows
#> # ℹ 13 more variables: AVALU <chr>, LLOQ <dbl>, BLQFL <chr>, DTYPE <chr>,
#> # EXDOSE <dbl>, ANL01FL <chr>, ARM <chr>, TRT01P <chr>, AGE <int>, SEX <chr>,
#> # RACE <chr>, WTBL <dbl>, CRCL <dbl>
# the BLQ policy is an argument, never a hardcoded rule
table(make_adpc(pc, adsl, ex, blq = "zero")$AVAL == 0)
#>
#> FALSE TRUE
#> 528 48
nrow(make_adpc(pc, adsl, ex, blq = "drop"))
#> [1] 528