% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tcoarsen.R
\name{tcoarsen}
\alias{tcoarsen}
\title{Time coarsening and follow-up augmentation for start-stop survival data}
\usage{
tcoarsen(data, id, start, stop, event, covs = NULL, bin_width,
  dir_coarsen = c("floor", "ceiling"), origin = NULL, absorb_vars = NULL,
  keep_terminal_time = TRUE, gap_action = c("stop", "warn", "ignore"),
  add_visit = TRUE, visit_name = "visit", diagnostics = TRUE,
  verbose = TRUE)
}
\arguments{
\item{data}{A \code{data.frame} in start-stop long format, with one or more rows
per subject.}

\item{id}{A character string for the subject identifier variable name.}

\item{start}{A character string naming the interval start-time
variable.}

\item{stop}{A character string for the interval stop-time variable name.}

\item{event}{A character string for the terminal event indicator.
The event variable must be coded \code{0}/\code{1}, with at most one event per
subject.}

\item{covs}{Optional character vector of treatment or covariate variables
to document as carried-forward predictors. Both baseline-only and
time-varying variables are allowed. The function retains all original data
columns, but \code{covs} is checked for existence and stored in the returned
object's attributes for reproducibility. In practice, all \strong{time-varying}
covariates are encouraged to be included here.}

\item{bin_width}{A positive numeric value giving the grid width in the
same time units as \code{start} and \code{stop}, for example \code{30} for a 30-day grid.}

\item{dir_coarsen}{Coarsening direction, either \code{"floor"} or \code{"ceiling"}.
Floor coarsening moves updates backward to the start of the containing bin;
ceiling coarsening moves updates forward to the end of the containing bin.}

\item{origin}{Optional numeric grid origin. If \code{NULL}, the minimum observed
start time is used. In trial applications this is often \code{0}.}

\item{absorb_vars}{Optional character vector of variables to convert to
absorbing status using within-subject cumulative maxima after sorting by
time. These variables must be coded \code{0}/\code{1}. For multi-way switching data,
this will often be \code{c("cross", "subseq")}.}

\item{keep_terminal_time}{Logical. If \code{TRUE} (default), each subject's exact
event/censoring exit time is preserved as the final stop time. If \code{FALSE},
the exit time is also snapped to the selected grid. The default is strongly
recommended for survival analyses.}

\item{gap_action}{How to handle gaps between adjacent within-subject
start-stop intervals before coarsening. One of \code{"stop"}, \code{"warn"}, or
\code{"ignore"}. Overlapping intervals always stop with an error.}

\item{add_visit}{Logical. If \code{TRUE} (default), add a discrete grid index to
the output.}

\item{visit_name}{A single character string giving the name of the visit-index
variable to add when \code{add_visit = TRUE}. Defaults to \code{"visit"}.}

\item{diagnostics}{Logical. If \code{TRUE} (default), attach preprocessing metadata
and a by-visit row/event summary in \code{diagnostics} object of output.}

\item{verbose}{Logical. If \code{TRUE}, print a short preprocessing message.}
}
\value{
A \code{tcoarsen} object with two components. The first component is a \code{data.frame}
called \code{dat_coarsen} the time-coarsened input data with updated interval times
and time-varying covariates under coarsened time grid; the second component is
\code{diagnostics} for diagnostics settings and basic diagnostics.
}
\description{
\code{tcoarsen()} harmonizes irregular longitudinal survival data in start-stop
form onto a user-specified discrete time grid. It maps observed update times
to grid landmarks using either floor or ceiling coarsening, rebuilds start-stop
intervals, and augments each individual's follow-up record by carrying the
last known covariate and treatment values forward to empty grid intervals.

The function is intended as a transparent preprocessing utility for real-world
clinical trial datasets with sparse or irregular follow-up times.The grid width
and coarsening direction are substantive analysis choices and should usually be
prespecified and examined in sensitivity analysis.

For use before \code{\link[=multimsm]{multimsm()}}, include the triplet variables such as \code{rand},
\code{cross}, and \code{subseq} in \code{covs}, and set \code{absorb_vars = c("cross", "subseq")}
when crossover and subsequent therapy indicators should be interpreted as
absorbing current-status variables. The output remains an ordinary data frame
that can be passed directly to downstream modeling functions.
}
\details{
Suppose an individual has observed rows indexed by \code{j}, representing intervals
\verb{[start_ij, stop_ij)} over which the row values are assumed to apply. Given
grid origin \code{origin} and bin width \code{bin_width}, an observed update time \code{s} is
mapped to
\itemize{
\item \code{origin + floor((s - origin) / bin_width) * bin_width} when
\code{dir_coarsen = "floor"};
\item \code{origin + ceiling((s - origin) / bin_width) * bin_width} when
\code{dir_coarsen = "ceiling"}.
}

After snapping update times, \code{tcoarsen()} inserts one row for each missing grid
interval during which the subject remains under observation. Values of all
carried variables are filled by last-known-value-carried-forward (LKCF).
Terminal event/censoring times are preserved exactly by default, so an event
at day 173 can remain \code{stop = 173} even if the coarsening grid is monthly.

If multiple observed rows map to the same coarsened update time, the last
observed row within that coarsened bin is kept. This rule is simple and
reproducible, but it necessarily discards within-bin ordering information.
}
\examples{
if (requireNamespace("survival", quietly = TRUE)) {
  data("heart", package = "survival")

  heart_30 <- tcoarsen(
    data = heart,
    id = "id",
    start = "start",
    stop = "stop",
    event = "event",
    covs = c("transplant", "age", "surgery"),
    bin_width = 30,
    dir_coarsen = "floor",
    origin = 0,
    absorb_vars = "transplant",
    verbose = FALSE
  )

  utils::head(heart_30$dat_coarsen, 10)
}

}
\references{
Guerra SF, Schnitzer ME, Forget A, Blais L. Impact of discretization of the
timeline for longitudinal causal inference methods. \emph{Statistics in
Medicine}. 2020 Sept;39(27):0277-6715.
}
\seealso{
\code{\link[=multimsm]{multimsm()}}
}
