Creates the response object used on the left hand side of a pcdreg()
formula, in the same spirit as survival::Surv().
Arguments
- id
Subject identifier. May be numeric, character or a factor; rows sharing an identifier are treated as one subject.
- time
Examination time in the three argument form, or the start of the interval in the four argument form.
- time2
The end of the interval in the four argument form; the event count in the three argument form.
- count
Number of events observed since the previous examination. Use
NAon rows that only record a change in a covariate rather than an examination. Omitted in the three argument form.
Value
An object of class "pcd": a numeric matrix with columns
id, tstart, tstop, count and exam, carrying the original
identifier labels in the "labels" attribute. Missing counts are stored as
count = 0 with exam = 0, so that the response contains no NA and
na.action handling applies to the covariates alone.
Details
There are two forms, distinguished by the number of arguments. Which one you need depends on a single question: does any covariate change value during follow-up?
pcd(id, time, count) is for data with one row per examination, which
is all that time-invariant covariates need. Interval starts are filled in as
the previous examination time of the same subject, with the first interval
starting at zero.
pcd(id, tstart, tstop, count) is the counting process form, needed as
soon as a covariate moves. Each row gives an interval (tstart, tstop] over
which the covariates in that row are constant, exactly as for a time-varying
survival::coxph() fit. The count column distinguishes the two kinds of
row:
a number means the row ends at an examination, and that many events occurred since the previous examination;
NAmeans the row ends at a covariate change rather than an examination.
There is no separate event indicator; the presence or absence of a count is the indicator.
Counts are increments, not totals
count must be the number of events since the previous examination,
\(\Delta N_{ij}\), not the running total \(N_i(T_{ij})\). Data recorded
cumulatively must be differenced within subject first. This is not something
the package can detect for you, and getting it wrong inflates the event count
and biases the coefficients rather than raising an error. A quick check after
fitting is that fit$nevent matches the number of events you believe you
have. See vignette("data-preparation") for the conversion.
What the data must satisfy
Checked before any arithmetic, naming the offending subject when a check fails:
follow-up starts at time zero, since the models integrate from there;
intervals within a subject are contiguous, with no gaps or overlaps;
no subject has two rows ending at the same time;
every subject has at least one examination;
counts are non-negative whole numbers.
Row order is irrelevant: the data are sorted internally. Identifiers may be numeric, character or factor, and need not be consecutive.
A subject's follow-up ends at their last examination, because the likelihood runs only over \(j = 1, \ldots, J_i\). Rows lying entirely beyond it carry no information and are dropped, with a message saying how many. A censoring row appended after the final visit is the usual reason for seeing it.
See also
pcdreg() and
vignette("data-preparation") for converting data into this shape.
Examples
# One row per examination: subject 1 seen at 0.5 and 1.2 with 2 then 0
# events, subject 2 seen once at 0.8 with 3.
pcd(c(1, 1, 2), c(0.5, 1.2, 0.8), c(2, 0, 3))
#> [1] 1: (0.0, 0.5] 2 1: (0.5, 1.2] 0 2: (0.0, 0.8] 3
# Counting process form. Subject 1's covariates change at t = 0.9, part way
# through the examination interval (0.5, 1.2], so that interval needs two
# rows: the first ends at the change and carries NA, the second ends at the
# examination and carries its count.
pcd(
id = c(1, 1, 1, 2),
time = c(0.0, 0.5, 0.9, 0.0),
time2 = c(0.5, 0.9, 1.2, 0.8),
count = c(2, NA, 0, 3)
)
#> [1] 1: (0.0, 0.5] 2 1: (0.5, 0.9] - 1: (0.9, 1.2] 0 2: (0.0, 0.8] 3
# Used on the left hand side of a formula, which is how you will normally
# meet it.
set.seed(1)
d <- sim_pcd(40)
fit <- pcdreg(pcd(id, tstart, tstop, count) ~ x1 + x2, data = d)
c(subjects = fit$n, examinations = fit$nexam, events = fit$nevent)
#> subjects examinations events
#> 40 159 272