Turns sequence data into the discrete-time expanded form a logistic or
probit model needs: one row per individual per time point at risk, a
binary indicator of whether the target event (a transition from one
state to another) occurred there, dummy variables for each time period
(so period effects can be estimated freely, the way factor(t)
would in a regular model), and any covariates carried along. Fit the
result with tda_qreg (model = "logit" or
"probit") or tda_glm(family = binomial) on the
event column against the period dummies and covariates –
TDA's manual (chapter 6.18) calls this approach out explicitly as
the discrete-time counterpart to tda_rate.
Usage
tda_seqmd(
sequences,
event,
data = NULL,
covariates = NULL,
event_covariates = NULL,
select = NULL,
tp = NULL,
summary = FALSE,
options = list(),
dir = tempfile("tda"),
...
)
tda_seqev(
sequences,
data = NULL,
sn = 1L,
select = NULL,
options = list(),
dir = tempfile("tda"),
...
)
tda_seqevd(
sequences,
data = NULL,
sn = 1L,
select = NULL,
options = list(),
dir = tempfile("tda"),
...
)Arguments
- sequences
a data frame or matrix, one row per case, one column per time point, in order – the same shape
tda_seqmtakes – or, givendatatoo, a character vector naming those columns within it directly, rather than requiring a separately pre-subsetted data frame: real sequence data typically carries an ID column and covariates alongside the states in the same data frame (TDA'sexamples/exam/seq.d4, e.g.), not only the states on their own. Fortda_seqev/tda_seqevd, also a list of several such specs, to define several independent sequence data structures at once – TDA'sseqdef(sn=1),seqdef(sn=2), ... – the pattern TDA's own manual uses to build a second sequence structure fromseq.d4'sS0..S5columns, entirely separate from the first (Y0..Y5), not a covariate of it. Usesn=to say which one a given call analyzes.- event
for
tda_seqmd, the target transition, asc(from, to)– the two states such that going from the first to the second at timetcounts as the event.- data
optional data frame
sequences(and, fortda_seqmd,covariates) name columns within, instead ofsequences/covariatesbeing the actual data already.- covariates
optional further time-independent covariates, carried into the output unchanged – a data frame or matrix, one row per case in the same order as
sequences, or (withdatagiven) a character vector naming columns within it.- event_covariates
optional time-varying covariates – TDA's
xe=, different fromcovariates/v=: a separate value for each time point, rather than one fixed value per case. A named list, needsdata: each element the per-time-point column names for one such covariate, in the same order assequencesitself, named by what the result's column should be called –list(price = paste0("Price", 0:5)), say, for a covariate stored one column per time point the same way the states themselves are. Exactly how TDA derives the value it puts in the output is not documented – it is not simply the value at the event's time point; check against your data before relying on a particular reading of this column.- select
optional expression (
sel=) restricting which sequences are used – written with R's comparison operators (Y0 == 1, orY0 = 1) or TDA's function form (eq(Y0,1)) interchangeably;&/|combine several conditions the same way in both.- tp
optional restriction of the time axis, as a vector of time points or a single TDA range expression such as
"0(1)10".- summary
instead of the full per-case, per-period data, just a
time/riskset/eventstable – TDA'sseqmd(ev=...)called with no output file at all, a separate mode in which TDA prints this table to the console instead of writing any records.covariates/event_covariatesare not accepted together with this, since TDA's console summary carries no covariate columns to show.- options
a named list of further TDA options, passed through.
- dir
working directory.
- ...
passed to
tda_run.- sn
for
tda_seqev/tda_seqevd, which sequence data structure to use whensequencesdefines more than one (see above) – TDA'ssn=, 1 by default, the same as when only one structure was ever defined.
Value
tda_seqmd returns a data frame: id, time,
event (the binary indicator), one period dummy column
per distinct time point, and any covariates – or, with
summary = TRUE, time, riskset, events
instead. tda_seqev
returns a data frame, one row per transition that occurs
in the data: from, to, count.
tda_seqevd returns a data frame: time, cases,
one match-count column per event type found, and total.
Details
tda_seqev and tda_seqevd are the exploratory step before
committing to a target event: tda_seqev counts how often each
state-to-state transition actually occurs in the data, and
tda_seqevd tabulates event counts over time.
A note on names: the manual documents this command as
seqnd, but TDA 6.4 itself calls it seqmd;
tda_seqmd() uses the name that works.
This wrapper always defines exactly one sequence data structure per
call (a fresh seqdef, every time), so TDA's sn= –
selecting among several already-defined structures – has nothing to
select among here: sn = 1 is always correct, and there is no
way to reach any other value through this interface. Not exposed as
an argument for that reason, rather than included as a parameter
that could never meaningfully differ from its default.
tda_seqev ignores TDA's dtda= (no description file
is written even when asked for one); its output shape
(from/to/count) needs no further description to
read reliably. tda_seqmd's dtda= is used
internally to read TDA's real column structure back, since
event_covariates, in particular, can change how many columns
come back and where.
See also
Other sequence analysis:
tda_evalfi(),
tda_fml(),
tda_frml(),
tda_seq_info(),
tda_seqgc(),
tda_seqm(),
tda_seqpe(),
tda_seqpm()
Examples
# three individuals, six time points (0-5), states 1-3; the target
# event is a 1 -> 2 transition, with two time-independent covariates
s <- data.frame(Y0 = c(1, 1, 2), Y1 = c(1, 2, 1), Y2 = c(2, 1, 1),
Y3 = c(1, 1, 2), Y4 = c(1, 1, 2), Y5 = c(3, 3, 3))
cov <- data.frame(v1 = c(1, 2, 2), v2 = c(-10, -15, -20))
tda_seqev(s) # which transitions actually occur, and how often
#> from to count
#> 1 1 2 3
#> 2 1 3 2
#> 3 2 1 3
#> 4 2 3 1
tda_seqevd(s) # event counts over time
#> time cases ev1_2 ev1_3 ev2_1 ev2_3 total
#> 1 1 3 1 0 1 0 2
#> 2 2 3 1 0 1 0 2
#> 3 3 3 1 0 1 0 2
#> 4 4 3 0 0 0 0 0
#> 5 5 3 0 2 0 1 3
d <- tda_seqmd(s, event = c(1, 2), covariates = cov)
d
#> id time event period1 period2 period3 period4 period5 v1 v2
#> 1 1 1 0 1 0 0 0 0 1 -10
#> 2 1 2 1 0 1 0 0 0 1 -10
#> 3 1 4 0 0 0 0 1 0 1 -10
#> 4 1 5 0 0 0 0 0 1 1 -10
#> 5 2 1 1 1 0 0 0 0 2 -15
#> 6 2 3 0 0 0 1 0 0 2 -15
#> 7 2 4 0 0 0 0 1 0 2 -15
#> 8 2 5 0 0 0 0 0 1 2 -15
#> 9 3 2 0 0 1 0 0 0 2 -20
#> 10 3 3 1 0 0 1 0 0 2 -20
# fit it: a period dummy for every distinct time point, the way
# factor(time) would in an ordinary logistic regression
pd <- grep("^period", names(d), value = TRUE)
tda_qreg(stats::as.formula(paste("event ~", paste(c(pd, "v1", "v2"),
collapse = "+"))),
d, model = "logit", intercept = FALSE)
#> Call: tda_qreg(formula = stats::as.formula(paste("event ~", paste(c(pd,
#> "v1", "v2"), collapse = "+"))), data = d, model = "logit",
#> intercept = FALSE)
#>
#> Cases: 10
#> Model: logit (TDA 1)
#> logLik (starting values): -6.931472
#> logLik: -4.158883
#> Converged in 18 iterations
#>
#> Idx Cat Term Variable Coeff Error C/Error Signif
#> 1 1.0000 X period1 -0.0000 3.3665 -0.0000 0.0000
#> 2 1.0000 X period2 -0.0000 3.7417 -0.0000 0.0000
#> 3 1.0000 X period3 -0.0000 4.3970 -0.0000 0.0000
#> 4 1.0000 X period4 -18.2029 6341.5209 -0.0029 0.0023
#> 5 1.0000 X period5 -18.2029 6341.5209 -0.0029 0.0023
#> 6 1.0000 X v1 -0.0000 4.0000 -0.0000 0.0000
#> 7 1.0000 X v2 -0.0000 0.4619 -0.0000 0.0000
# the same data, but with an ID column and the states/covariates all
# together in one data frame, the more realistic shape -- sequences=
# and covariates= just name columns in data= directly
full <- cbind(id = 1:3, s, cov)
tda_seqmd(paste0("Y", 0:5), event = c(1, 2), data = full,
covariates = c("v1", "v2"))
#> id time event period1 period2 period3 period4 period5 v1 v2
#> 1 1 1 0 1 0 0 0 0 1 -10
#> 2 1 2 1 0 1 0 0 0 1 -10
#> 3 1 4 0 0 0 0 1 0 1 -10
#> 4 1 5 0 0 0 0 0 1 1 -10
#> 5 2 1 1 1 0 0 0 0 2 -15
#> 6 2 3 0 0 0 1 0 0 2 -15
#> 7 2 4 0 0 0 0 1 0 2 -15
#> 8 2 5 0 0 0 0 0 1 2 -15
#> 9 3 2 0 0 1 0 0 0 2 -20
#> 10 3 3 1 0 0 1 0 0 2 -20