Auditable multistate life-course editing and longitudinal policy simulation in R
lcedit 0.5.0 represents, describes, edits, and models longitudinal
multistate processes while keeping completed-path transformations, forward
policies, and causal estimators conceptually separate.
library(lcedit)
space <- lc_state_space(
c("stable", "adverse", "recovered"),
reference = "stable",
focal = "adverse",
labels = c("Stable", "Adverse", "Recovered")
)
x <- lc_seq(
rbind(
A = c("stable", "adverse", "adverse", "recovered"),
B = c("stable", "stable", "adverse", "recovered")
),
times = 1:4,
state_space = space
)
edited <- apply_edit(
x,
edit_transition(
from = "adverse",
to = "recovered",
shift = -1
)
)
lc_state_features(x)
lc_transition_features(x)
lc_audit(edited)
lc_table(edited, "audit_steps")
plot(x, type = "transition")
plot(edited, type = "flow")The state-space contract fixes state order, labels, colors, legal transitions,
absorbing states, and missing/void markers. Explicit from and to arguments
allow timing, duration, cessation, recurrence, and general transition edits to
preserve every third state.
The 0/1 interface remains available without changing its legacy semantics:
binary <- lc_seq(
rbind(A = c(0, 1, 1, 0), B = c(0, 0, 1, 0)),
times = 1:4,
exposed = 1,
reference = 0
)
binary_edit <- apply_edit(binary, edit_duration(shorten = 1))
lc_features(binary_edit$original)
lc_audit(binary_edit)For binary data, a transition from 1 to 0 is cessation, not proof of
substantive recovery. edit_recovery() and the recovery_* feature names are
retained as exact compatibility aliases.
| Layer | Main interfaces | Interpretation |
|---|---|---|
| State and sequence | lc_state_space(), lc_seq(), as_lc_seq(), as_traminer() |
Declared multistate data contract |
| Description | lc_state_features(), lc_transition_features(), lc_table(), plot() |
Weighted state/transition summaries and graphics |
| Retrospective editing | edit_transition(), edit_timing(), edit_duration(), apply_edit() |
Audited transformation of completed paths |
| Forward policy | policy_redirect(), policy_prevent(), policy_stochastic(), bind_policy() |
Online MTP or direct stochastic intervention |
| Observed-path model | fit_lcee() |
Model-based standardization of completed observed paths |
| Sequential causal model | lc_panel(), fit_lc_gformula() |
Multinomial parametric g-formula under explicit assumptions |
| Diagnostics/inference | diagnose_support(), tidy(), vcov(), confint(), plot() |
Calibration, positivity, Monte Carlo error, and bootstrap covariance |
Sequence descriptions and retrospective edits remain useful even when a causal interpretation is not warranted. An audit records eligibility, no-op reasons, changed cells, state pairs, graph decisions, and ordered compound-edit steps.
Modified treatment policies transform a natural proposal:
no_adverse <- policy_redirect("adverse", "recovered")
short_adverse <- policy_shorten_episode(
state = "adverse",
max_duration = 2,
redirect_to = "recovered"
)Direct stochastic interventions declare the assigned-state distribution:
mix <- policy_stochastic(
c(stable = 0.35, adverse = 0.15, recovered = 0.50)
)Policies are validated against the panel's state space and legal transition graph when they are bound. Illegal structural assignments fail explicitly rather than being silently renormalized.
panel <- simulate_multistate_lc_panel(
n = 300,
state_effects = c(stable = 0, adverse = -1, recovered = 0.4),
seed = 2026
)
fit <- fit_lc_gformula(
panel,
policies = list(
no_adverse = policy_redirect("adverse", "recovered"),
mix = policy_stochastic(
c(stable = 0.35, adverse = 0.15, recovered = 0.50)
)
),
exposure_formula =
.state ~ factor(.time_index) + .lag_state + L + W,
covariate_formulas = list(
L = .next_L ~ factor(.time_index) + L + .state + W
),
outcome_formula =
.Y ~ .cum_state__adverse + .cum_state__recovered + L + W,
nsim = 500,
bootstrap = 100,
bootstrap_min_success = 80,
seed = 2027
)
tidy(fit)
vcov(fit)
diagnose_support(fit)
plot(fit, type = "calibration")
plot(fit, type = "support")A causal interpretation of these policy-minus-identity contrasts requires consistency, sequential conditional exchangeability, positivity for every legal state receiving positive policy mass, no interference, and correct temporal ordering. Correct nuisance specification, or another consistent nuisance-learning strategy, is additionally required by this parametric estimator. Software diagnostics do not establish those substantive assumptions.
Multiple policies share a fitted identity arm and paired common random
numbers. The person bootstrap resamples complete trajectories and returns a
joint covariance matrix. Sampling standard error, point-simulation
mc.error, and replicate-level bootstrap.mc.rms are reported separately.
Stable in 0.5.0:
- deterministic native multistate sequence edits;
- deterministic MTPs and direct stochastic policies;
- legal-choice multinomial sequential g-computation;
- model-based observed-path standardization;
- person-level bootstrap inference with multi-policy covariance; and
- multistate calibration and policy-support diagnostics.
User-supplied assignment engines are experimental. The optional lmtp bridge
remains binary-only and restricted to its documented threshold policy.
lcedit does not claim a stable multistate LMTP or a general multistate doubly
robust estimator.
The causal engine requires complete balanced follow-up through the endpoint. Descriptive sequences may retain their documented missing/void behavior, but that does not relax the causal-panel gate.
Install the development release from GitHub:
if (!requireNamespace("remotes", quietly = TRUE)) {
install.packages("remotes")
}
remotes::install_github("williamlorder/lcedit")For a local checkout:
pkgload::load_all(".")TraMineR, ggplot2, and nnet are core dependencies. WeightedCluster,
seqHMM, and lmtp are optional ecosystem extensions.
The source tree includes four PDFs rebuilt from executable R Markdown:
- Introduction to Multistate Life-Course Editing
- Technical Details: Estimands, Policies, and Multinomial G-Computation
- Biofam: Editing Family-Formation Trajectories
- MVAD: Editing School-to-Work Transitions
Biofam and MVAD retain their native eight- and six-state processes as the primary analyses. Binary projections appear only as explicit compatibility comparisons. Neither empirical vignette claims an identified causal effect.
roxygen2::roxygenise(".")
testthat::test_local(".", reporter = "summary", stop_on_failure = TRUE)Multistate validation is recorded in inst/VALIDATION.md, with generated
artifacts in inst/validation/. The 500-replication-by-four-scenario full
design completed and passed on 2026-07-27 at commit b8180fa: absolute bias
at most 0.0037, RMSE at most 0.0437, and scheduled interval coverage of 0.940
to 0.990 against a declared floor of 0.850. Every scenario returned all 500
point estimates and all 100 bootstrap intervals with no fit, absent-state, or
support failures.