Skip to contents

Prepares longitudinal Markov trajectory data for proportional odds regression by removing absorbing states and converting variables to appropriate types. Works with both VGAM::vglm and rms::orm models.

Usage

prepare_markov_data(
  data,
  absorbing_state = 6,
  ordered_response = TRUE,
  factor_previous = TRUE
)

Arguments

data

A data frame containing Markov trajectory data with columns y (current state) and yprev (previous state).

absorbing_state

Integer or integer vector. The absorbing state(s) to filter out (default: 6 for death). Observations where yprev equals any of these values are removed. Can be a single value (e.g., 6) or a vector of multiple absorbing states (e.g., c(1, 6) for both home discharge and death).

ordered_response

Logical. Should y be converted to ordered factor? (default: TRUE). Required for vglm, not required for orm.

factor_previous

Logical. Should yprev be converted to factor? Defaults to TRUE for backward compatibility and categorical previous-state effects. Set to FALSE when modeling the previous state linearly or with nonlinear numeric terms such as rms::rcs(yprev, 6).

Value

A data frame with modified y and yprev columns and absorbing states removed.

Details

This is a convenience function that performs standard data preparation for proportional odds models on Markov data:

  • Removes rows where patients were in an absorbing state at the previous time

  • Converts current state to ordered factor (for cumulative models)

  • Converts previous state to factor by default (for categorical transition effects)

  • Can preserve previous state as numeric for linear or spline transition effects

Package compatibility: This function prepares data for:

  • VGAM::vglm: Use cumulative(parallel = TRUE, reverse = TRUE) default datasets.

  • rms::orm: Automatically treats integers as ordered factors.

Multiple absorbing states: When modeling scenarios with multiple absorbing states (e.g., discharge home and death), specify them as a vector. For example, absorbing_state = c(1, 6) will remove all transitions from either state 1 (home) or state 6 (death).

Examples

if (FALSE) { # \dontrun{
# Prepare data with single absorbing state (death only)
model_data <- prepare_markov_data(trajectories, absorbing_state = 6)

# Prepare data with multiple absorbing states (home and death)
model_data <- prepare_markov_data(trajectories, absorbing_state = c(1, 6))

# Fit with VGAM (no robust SEs; use bootstrap for inference)
library(VGAM)
fit <- vglm(y ~ tx + rcs(time, 4) + yprev,
            family = cumulative(parallel = TRUE, reverse = TRUE),
            data = model_data)

# Keep yprev numeric to use one linear or nonlinear previous-state effect
model_data <- prepare_markov_data(
  trajectories,
  absorbing_state = 6,
  factor_previous = FALSE
)
fit <- vglm_markov(
  ordered(y) ~ tx + rcs(time, 4) + rcs(yprev, 6),
  family = cumulative(parallel = TRUE, reverse = TRUE),
  data = model_data
)

# Fit with rms (supports robust SEs via robcov)
library(rms)
dd <- datadist(model_data)
options(datadist = "dd")
fit <- orm(y ~ tx + rcs(time, 4) + yprev, data = model_data, x = TRUE, y = TRUE)
fit_robust <- robcov(fit, cluster = model_data$id)

} # }