| Type: | Package |
| Title: | Surrogate Evaluation for Jointly Longitudinal Outcome and Surrogate |
| Version: | 0.0.3 |
| Description: | Tools for surrogate evaluation in longitudinal studies using state-space models. The package estimates treatment effects over time with and without adjustment for surrogate information, summarizes the proportion of treatment effect explained by a longitudinal surrogate, quantifies uncertainty via bootstrap resampling, and provides plotting and summary utilities for fitted models. |
| License: | GPL (≥ 3) |
| Encoding: | UTF-8 |
| Imports: | kDGLM (≥ 1.2.14), dplyr, ggplot2, tidyr, rlang, Rfast, stats, latex2exp, Rdpack |
| Suggests: | knitr, rmarkdown |
| RdMacros: | Rdpack |
| RoxygenNote: | 7.3.3 |
| VignetteBuilder: | knitr |
| URL: | https://silvaneojunior.github.io/OnlineSurr/ |
| Repository: | CRAN |
| BugReports: | https://github.com/silvaneojunior/OnlineSurr/issues |
| Depends: | R (≥ 4.1.0) |
| NeedsCompilation: | no |
| Packaged: | 2026-04-15 07:34:08 UTC; Silvaneo |
| Author: | Silvaneo dos Santos Jr. [aut, cre], Layla Parast [aut] |
| Maintainer: | Silvaneo dos Santos Jr. <silvaneojunior@utexas.edu> |
| Date/Publication: | 2026-04-21 18:02:37 UTC |
Check if a dlm block has the treatment as covariate
Description
Check if a dlm block has the treatment as covariate
Usage
check_has_G(formula, name.G, inside_dlm = FALSE)
Arguments
formula |
A formula describing the model passed to the fit.surr function. |
name.G |
The name of the surrogate |
Check if a formula term is a dlm block
Description
Check if a formula term is a dlm block
Usage
check_is_dlm_block(term)
Arguments
term |
A string. |
Fit marginal and conditional state-space models for longitudinal surrogate evaluation
Description
Fits two Gaussian state-space models (Dynamic Linear Models) to jointly longitudinal outcome data: (i) a marginal model for the outcome trajectory given treatment and time, and (ii) a conditional model that additionally adjusts for a user-specified surrogate structure. The function returns per-time treatment-effect estimates from both models and subject-level bootstrap draws obtained via subject-level resampling.
Usage
fit.surr(
formula,
id,
surrogate,
treat,
data = NULL,
time = NULL,
N.boots = 2000,
verbose = 1,
D.local = 0.8
)
Arguments
formula |
An object of class |
id |
A variable (unquoted) identifying subjects. Each subject must have at most one measurement per |
surrogate |
A formula describing the surrogate structure to be included in the conditional model. May be provided either as a |
treat |
A variable (unquoted) indicating treatment assignment. Must encode exactly two treatment levels after coercion to a factor. |
data |
A |
time |
Optional variable (unquoted) giving the measurement time index. Must be numeric and equally spaced across observed time points. If |
N.boots |
Integer number of subject-level bootstrap replicates. Each replicate resamples subjects with replacement and recombines subject-specific sufficient quantities to form bootstrap draws of the fixed effects. |
verbose |
Logical scalar indicating whether to print progress information during model fitting. If |
D.local |
Numeric, a number between 0 and 1 indicating the discount factor to be used for the random effect block. This factor controls how smooth the random effect evolve over time. A discount factor of 1 means that the random effects do not change over time, so that each individual has its own local level, but that level is the same for all times. A discount factor of 0 is not acceptable (the kDGLM package will replace it by 1), but values closer to 0 imply in a more flexible dynamic. See (West and Harrison 1997) or the appendix in (dos Santos Jr. and Parast 2026) for instructions on how to specify the discount factor. |
Details
The implementation follows a two-model decomposition used for estimating longitudinal treatment effects and surrogate-adjusted (residual) treatment effects in a state-space framework.
See (dos Santos Jr. and Parast 2026) for details on the methodology.
See (West and Harrison 1997) for best practices on model specification in the state-space model setting.
Data requirements. The data must have at most one row per subject-time pair; time must be numeric and equally spaced (or omitted, in which case an index is created). Treatment and subject identifiers are coerced to factors with sorted levels.
Model structure. The marginal model includes treatment-by-time fixed effects and a subject-specific random-walk component to capture within-subject correlation. The conditional model adds the user-specified surrogate structure to the design, and checks that treatment is not a linear combination of the surrogate design (rank check).
Bootstrap. Subjects are resampled with replacement. Subject-specific filtered quantities are computed once and recombined in each bootstrap iteration to reduce computational cost, consistent with a subject-level nonparametric bootstrap strategy for replicated time series.
Value
An object of class "fitted_onlinesurr": a named list with elements $Marginal and $Conditional. Each of these contains:
-
point: the point estimate vector of the fixed effects (excluding subject-specific random-walk states) at the final time point. -
smp: a matrix of bootstrap draws for those fixed effects, with one column per bootstrap replicate.
The object also includes:
-
T: number of unique time points. -
N: number of subjects. -
n.fixed: number of fixed-effect coefficients implied byformulafor a single subject prior to stacking across subjects.
Examples
## Not run:
# data columns: y (outcome), id (subject id), trt (0/1 or two-level factor),
# time (numeric equally spaced), s1 and s2 (surrogates)
fit <- fit.surr(
formula = y ~ 1, # baseline fixed effects; function adds trt*time terms
id = id,
surrogate = ~ s1 + s2,
treat = trt,
data = dat,
time = time,
N.boots = 500
)
# Access point estimates and bootstrap samples
fit$Marginal$point
fit$Conditional$smp[, 1:10]
## End(Not run)
formula.to.structure
Description
formula.to.structure
Usage
## S3 method for class 'to.structure'
formula(formula, data, label = "mu")
Arguments
formula |
an object of class "formula" (or one that can be coerced to that class): a symbolic description of the model to be fitted. |
data |
an optional data frame, list or environment (or object coercible by as.data.frame to a data frame) containing the variables in the model. If not found in data, the variables are taken from environment(formula), typically the environment from which glm is called. |
label |
An optional character naming the linear predictor. |
Compute a spline configuration
Description
Derive the configuration needed to evaluate s() for a given input vector. This helper resolves boundary limits, chooses or validates knot locations, augments the knot vector with repeated boundary knots, and returns the arguments in a form that can be used to rebuild or update spline calls.
Usage
get.config.s(
x,
P = 3,
K = min(7, max(3, floor(log2(length(unique(x)))))),
limits = c(NA, NA),
knots = "eq"
)
Arguments
x |
A numeric vector of predictor values. |
P |
A non-negative integer giving the spline degree. |
K |
An integer giving the number of basis functions implied by the spline specification. |
limits |
A numeric vector of length 2 giving the lower and upper boundary limits for the spline basis. Missing values are replaced by |
knots |
Either a numeric vector of knot locations, or one of |
Details
This function is intended for programmatic use, for example when rewriting model formulas that contain calls to s(...).
Value
A named list containing:
- x
The unevaluated expression supplied as
x, returned viasubstitute(x).- knots
The full augmented knot vector, including repeated boundary knots.
- limits
The resolved lower and upper boundary limits.
- P
The spline degree.
- K
The number of basis functions.
ginv
Description
This function receives a covariance matrix S and calculates the generalized inverse of S.
Usage
ginv(S)
Arguments
S |
A covariance matrix |
Test whether an expression contains a function call
Description
Recursively checks whether expr contains a call to fun.
Usage
has_call(expr, fun = "s")
Arguments
expr |
An R language object. |
fun |
A character string giving the function name to look for. |
Value
TRUE if expr contains a call to fun, otherwise FALSE.
Compute lagged values of a vector
Description
Returns a lagged version of x by shifting its values forward by k positions and padding the first k entries with zeros.
Usage
lagged(x, k = 1)
Arguments
x |
A vector to be lagged. |
k |
A non-negative integer giving the lag order. |
Details
This function is intended for use in model formulas when delayed effects of a predictor should be included explicitly.
Value
A vector of the same length as x, with the first k values set to 0 and the remaining values taken from x shifted by k positions.
Examples
x <- 1:5
lagged(x)
lagged(x, k = 2)
Plot time-varying PTE measures and treatment effects from a "fitted_onlinesurr" object
Description
Produces a ggplot2 figure showing, over time, either the Local PTE (LPTE), the Cumulative PTE (CPTE), or the marginal and residual treatment effects \Delta(t) and \Delta_R(t) (labeled \Delta and \Delta_R in the plot). Point estimates are taken from object$Marginal$point and object$Conditional$point, with uncertainty bands computed from the stored bootstrap draws.
Usage
## S3 method for class 'fitted_onlinesurr'
plot(x, type = "LPTE", conf.level = 0.95, one.sided = TRUE, ...)
Arguments
x |
A |
type |
Character string specifying what to plot. One of |
conf.level |
Numeric in |
one.sided |
Logical; if |
... |
Additional arguments (currently unused) included for S3 method compatibility. |
Details
The function extracts time-indexed treatment-effect estimates \Delta(t) (marginal) and \Delta_R(t) (residual/conditional) from the fitted object, along with bootstrap draws for each. It then constructs:
-
LPTE:
\mathrm{LPTE}(t) = 1 - \Delta_R(t)/\Delta(t). -
CPTE:
\mathrm{CPTE}(t) = 1 - \sum_{u\le t}\Delta_R(u)/\sum_{u\le t}\Delta(u). -
Delta: plots
\Delta(t)and\Delta_R(t)directly.
Point estimates are plotted as points; intervals are empirical quantile intervals computed from the bootstrap sample matrices stored in object.
Value
A ggplot object.
Examples
## Not run:
fit <- fit.surr(y ~ 1,
id = id, surrogate = ~ s1 + s2, treat = trt,
data = dat, time = time, N.boots = 2000
)
plot(fit, type = "LPTE")
plot(fit, type = "CPTE", conf.level = 0.90, one.sided = FALSE)
plot(fit, type = "Delta")
## End(Not run)
print.fitted_onlinesurr
Description
This method is wrapper for the summary.fitted_onlinesurr method.
Usage
## S3 method for class 'fitted_onlinesurr'
print(x, ...)
Arguments
x |
A fitted_onlinesurr object. |
... |
Arguments passed to summary.fitted_onlinesurr |
Value
No return value, called to print a summary of the fitted kDGLM model.
Rewrite function calls in an expression
Description
Recursively traverses expr and replaces calls to fun using the configuration returned by config_fun.
Usage
rewrite_calls(
expr,
fun = "s",
config_fun = get.config.s,
eval_env = parent.frame()
)
Arguments
expr |
An R language object. |
fun |
A character string giving the function name to rewrite. |
config_fun |
A function returning the replacement argument list for each matched call. |
eval_env |
An environment used to evaluate arguments passed to |
Value
A modified language object with matching calls rewritten.
rmvnorm
Description
Obtains a sample from a multivariate normal distribution.
Usage
rmvnorm(n, mu, Sigma, norm.x = matrnorm(k, n, seed = round(runif(1) * 1e+15)))
Arguments
n |
integer: The sample size. |
mu |
numeric: The mean vector |
Sigma |
matrix: The Covariance matrix. |
Construct a B-spline basis matrix
Description
Build a B-spline basis for a numeric vector using a Cox-de Boor style recursion. By default, the function constructs a cubic spline basis (P = 3) and chooses the number of basis functions from the number of unique values in x.
Usage
s(
x,
P = 3,
K = min(7, max(3, floor(log2(length(unique(x)))))),
limits = c(NA, NA),
knots = "eq"
)
Arguments
x |
A numeric vector of predictor values. |
P |
A non-negative integer giving the spline degree. |
K |
An integer giving the number of basis functions to return. The default increases slowly with the number of unique values in |
limits |
A numeric vector of length 2 giving the lower and upper boundary limits for the spline basis. Missing values are replaced by |
knots |
Either a numeric vector of knot locations, or one of |
Details
Boundary limits are taken from x unless supplied explicitly. Knot locations may be given directly as a numeric vector, or generated either at equally spaced locations ("eq") or at empirical quantiles ("quantile").
The returned basis has length(x) rows and k columns.
When knots is generated internally, the function first creates K - P + 1 knot locations and then augments them with repeated boundary knots so the recursion can be evaluated.
Value
A numeric matrix with one row per element of x and one column per spline basis function.
Examples
x <- seq(0, 1, length.out = 10)
# Default cubic basis
B <- s(x)
dim(B)
# Equally spaced knots with custom basis size
B2 <- s(x, K = 5, knots = "eq")
# Quantile-based knots
B3 <- s(x, knots = "quantile")
Summarize a "fitted_onlinesurr" object
Description
Prints a human-readable report for an object of class "fitted_onlinesurr" returned by fit.surr. The report includes marginal and conditional treatment-effect estimates at a selected time point (or cumulatively up to that time), an estimate of the LPTE/CPTE, and a time-homogeneity test of the LPTE.
Usage
## S3 method for class 'fitted_onlinesurr'
summary(object, t = object$T, cumulative = T, signif.level = 0.05, ...)
Arguments
object |
A |
t |
Integer time index at which to evaluate treatment effects and the PTE. If |
cumulative |
Logical; if |
signif.level |
Numeric in |
... |
Additional arguments passed to downstream summary/print utilities (if any). |
Details
The "fitted_onlinesurr" object stores point estimates and bootstrap samples for marginal and surrogate-adjusted (conditional) models in object$Marginal and object$Conditional.
Value
No return value. Called for its side effect of printing a summary report.
Examples
## Not run:
fit <- fit.surr(y ~ 1,
id = id, surrogate = ~ s1 + s2, treat = trt,
data = dat, time = time, N.boots = 2000
)
# Cumulative up to time 5
summary(fit, t = 5, cumulative = TRUE, signif.level = 0.05)
# Time-specific at time 5
summary(fit, t = 5, cumulative = FALSE)
## End(Not run)
Extract formula terms containing a function call
Description
Returns the term labels from a formula whose parsed expressions contain a call to fun.
Usage
terms_with_call(formula, fun = "s")
Arguments
formula |
A model formula. |
fun |
A character string giving the function name to look for. |
Value
A character vector of term labels containing a call to fun.
Test time-homogeneity of the PTE
Description
Tests the null hypothesis that the LPTE is constant over time. The test is based on the difference between the conditional and marginal treatment-effect trajectories implied by a fitted "fitted_onlinesurr" object, standardized by an estimated covariance, and uses a max-type statistic to control the family wise error across time points.
Usage
time_homo_test(model, signif.level = 0.05, N.boots = 50000)
Arguments
model |
A fitted object of class |
signif.level |
Numeric in (0,1) giving the test significance level used to form the critical value from the bootstrap distribution. Default is |
N.boots |
Integer number of Monte Carlo draws used to approximate the null distribution of the max standardized deviation statistic and to compute the p-value. Default is |
Details
See (dos Santos Jr. and Parast 2026) for the theoretical details about this test.
Notes:
The function assumes the first
Ttime-specific treatment-effect parameters are stored contiguously at the beginning ofmodel$Marginal$pointandmodel$Conditional$point(and similarly forsmp). It uses the index1:(n.fixed)as implemented in the code:1:(T + n.fixed - T).-
N.bootshere is a Monte Carlo size for the null simulation (distinct from the bootstrap size used when fittingmodel).
Value
A named list with:
-
T: the observed test statistic (maximum absolute standardized deviation). -
T.crit: the 1-signif.level critical value. -
p.value: the Monte Carlo p-valuemean(T_null > T_obs).
Examples
## Not run:
fit <- fit.surr(y ~ 1,
id = id, surrogate = ~ s1 + s2, treat = trt,
data = dat, time = time, N.boots = 2000
)
time_homo_test(fit, signif.level = 0.05, N.boots = 50000)
## End(Not run)
Update spline calls in a formula
Description
Rewrites calls to fun in a formula using config_fun, evaluating arguments in an environment built from data.
Usage
update_s_in_formula(formula, data, config_fun = get.config.s, fun = "s")
Arguments
formula |
A model formula. |
data |
A data frame or list providing variables used in the formula. |
config_fun |
A function returning the replacement argument list for each matched call. |
fun |
A character string giving the function name to rewrite. |
Value
A formula with updated calls to fun.
var_decomp
Description
This function receives a covariance matrix S and creates a matrix Q, so that t(Q) %*% Q = S.
Usage
var_decomp(S)
Arguments
S |
A covariance matrix |