Skip to content

statspai.longitudinal

longitudinal

Longitudinal causal inference (sp.longitudinal).

Unified entry for What If Layer-4 methods (time-varying treatments with time-varying confounders). Wraps MSM / g-formula ICE / IPW under a single dispatcher with a dynamic-regime DSL.

import statspai as sp r = sp.longitudinal.analyze( ... data=panel, ... id="pid", ... time="visit", ... treatment="drug", ... outcome="cd4", ... time_varying=["cd4_lag", "viral_load_lag"], ... baseline=["age", "sex"], ... regime="if cd4_lag < 200 then 1 else 0", ... ) r.summary()

diff = sp.longitudinal.contrast( ... data=panel, id="pid", time="visit", ... treatment="drug", outcome="cd4", ... regime_a="always_treat", ... regime_b="never_treat", ... time_varying=["cd4_lag"], ... )

Regime dataclass

A dynamic treatment regime.

Attributes:

Name Type Description
kind {'static', 'dynamic'}
name str
rule Union[list, Callable]

Static regimes store a list/sequence; dynamic regimes store a callable (history_dict, t) -> treatment_value.

treatment

treatment(history: dict, t: int = 0, K: int = 1)

Evaluate the regime at time t given history.

apply

apply(history_df: DataFrame) -> Series

Vectorized: apply the regime to each row of a history dataframe.

LongitudinalResult dataclass

Result of a unified longitudinal analysis.

Attributes:

Name Type Description
method str

Which estimator was used ("msm", "g-formula", "ipw", "ltmle").

regime_name str

Name of the regime being evaluated.

estimate float

E[Y(regime)] under the chosen estimator.

se float
ci tuple[float, float]
n int

Panel sample size.

n_periods int
diagnostics dict

Weight quantiles, positivity flags, etc.

underlying_result Any

Raw result object from the underlying estimator.

always_treat

always_treat(K: int = 1) -> Regime

Convenience: the always-treat regime over K periods.

never_treat

never_treat(K: int = 1) -> Regime

Convenience: the never-treat regime over K periods.

contrast

contrast(data: DataFrame, id: str, time: str, treatment: str, outcome: str, regime_a: Union[str, Sequence, Regime], regime_b: Union[str, Sequence, Regime], **kwargs) -> dict

Estimate E[Y(regime_a)] - E[Y(regime_b)] using :func:analyze.

Returns:

Type Description
dict

With keys regime_a, regime_b, contrast, a_result, b_result. The contrast value is the plug-in difference a.estimate - b.estimate; its SE uses the delta-method approximation sqrt(se_a^2 + se_b^2).