Run a Natural Cubic Spline (NCS) Analysis.
Source:R/ncs_analysis.R, R/ncs_analysis_subgroup.R
ncs_analysis_subgroup.RdFit and analyze an mmrm model wherein the
continuous time variable has splines applied.
ncs_analysis()fits such a model without involving subgroups.ncs_analysis_subgroup()fits a model that involves subgroups and performs additional analyses.
Usage
ncs_analysis(
data,
response = "response",
subject = "subject",
arm = "arm",
control_group,
time_observed_continuous = "time_observed_continuous",
df = 2,
spline_basis = NULL,
time_observed_index = "time_observed_index",
time_scheduled_continuous = "time_scheduled_continuous",
time_scheduled_baseline = 0,
time_scheduled_label = "time_scheduled_label",
covariates = ~1,
cov_structs = c("us", "toeph", "ar1h", "csh", "cs"),
cov_struct_group = NULL,
mmrm_args = list(method = "Satterthwaite"),
emmeans_args = list(nesting = NULL),
average_nuisance = TRUE,
conf.level = 0.95,
change_in_bl_contrast_args = list(adjust = "none"),
treatment_effect_contrast_args = list(adjust = "none"),
confint_args = list(level = conf.level),
return_models = FALSE,
expand_spline_terms = TRUE
)
ncs_analysis_subgroup(
data,
response = "response",
subject = "subject",
arm = "arm",
control_group,
subgroup = "subgroup",
subgroup_comparator = "subgroup1",
time_observed_continuous = "time_observed_continuous",
df = 2,
spline_basis = NULL,
time_observed_index = "time_observed_index",
time_scheduled_continuous = "time_scheduled_continuous",
time_scheduled_baseline = 0,
time_scheduled_label = "time_scheduled_label",
covariates = ~1,
cov_structs = c("us", "toeph", "ar1h", "csh", "cs"),
cov_struct_group = NULL,
mmrm_args = list(method = "Satterthwaite"),
emmeans_args = list(nesting = NULL),
average_nuisance = TRUE,
conf.level = 0.95,
change_in_bl_contrast_args = list(adjust = "none"),
treatment_effect_contrast_args = list(adjust = "none"),
confint_args = list(level = conf.level),
subgroup_interaction_test = TRUE,
return_models = FALSE,
expand_spline_terms = TRUE
)Arguments
- data
(
data frame)
data set supplied to thedataargument ofmmrm::mmrm()when fitting models. The supplied expression is quoted and must evaluate to a data frame. See Tidy evaluation support.- response
(
numericorstring)
the response variable. It can be astringidentifying the name of an existing variable; otherwise, the supplied expression will be quoted and added to the formula as is (see Tidy evaluation support).- subject
(
atomicorstring)
the unique subject identifier forwarded to thesubjectargument ofmmrm::cov_struct(). Ignored ifcov_structsis alist. Can be astringidentifying an existing variable; otherwise the supplied expression will be quoted and turned into astringwithrlang::expr_deparse()(see Tidy evaluation support).- arm
(
factororstring)
the study arm. It must be astringor a name identifying an existing variable (i.e., it cannot be a call). If a name, it will be quoted before being added to the model formula (see Tidy evaluation support). If it does not evaluate to a factor or ifcontrol_groupis not its first level, thedataargument will be wrapped in adplyr::mutate()call that forces this to be the case.- control_group
(
string)
the value inarmdenoting the control group. If necessary,armwill be preprocessed such that it is a factor withcontrol_groupas its first level.- time_observed_continuous
(
numericorstring)
the visit's observed time point. It must either be astringor a name identifying an existing variable (i.e., it cannot be a call). If a name is provided, it is quoted and incorporated into the model formula as is (see Tidy evaluation support).- df
(scalar
integer)
number of degrees of freedom to use to create the spline basis. Passed to thedfargument oftime_spline_basis(). Ignored if thespline_basisargument is notNULL.- spline_basis
(
basismatrix)
a spline basis: probably a value returned bytime_spline_basis()(which wrapssplines::ns()). IfNULL(the default), then the spline basis will be the result of forwardingtime_observed_continuousanddftotime_spline_basis(). See Providing a spline basis.- time_observed_index
(
orderedorstring)
the visit index that the visit shall be associated with, based on the visit's observed time point. This will be passed as thevisitsargument ofmmrm::cov_struct(). It can be astringidentifying an existing variable; otherwise the supplied expression will be quoted and turned into astringwithrlang::expr_deparse()(see Tidy evaluation support). If it does not evaluate to anorderedfactor, it will be wrapped withas.ordered(). Ignored ifcov_structsis alist.- time_scheduled_continuous
(
numericorstring)
the continuous time point when the visit was scheduled to occur. Its unique values will identify the time points at which the marginal means and other results will be calculated. It can be astringidentifying an existing variable name; otherwise the supplied expression will be quoted before being evaluated (see Tidy evaluation support).- time_scheduled_baseline
(
scalar numeric)
the continuous time point when baseline was scheduled to occur. Defaults to 0.- time_scheduled_label
(
characterorstring)
the label associated with the scheduled visit. It can be astringidentifying an existing variable name; otherwise the supplied expression will be quoted before being evaluated (see Tidy evaluation support).- covariates
(
formula)
formula containing additional terms that should be added to themmrmmodel. Defaults to~ 1, in which no additional terms will be added. Must not have a left side. Cannot contain.. To specify that the model shall not have an intercept, use include+ 0or- 1in this formula.- cov_structs
(
characterorlist)
either alistof uniquecov_structobjects or acharactervector of one or more of the covariance structure abbreviations as described inmmrm::cov_types(). These covariance structures will be attempted in order until one of them achieves a converging model fit. Defaults toc("us", "toeph", "ar1h", "csh", "cs").- cov_struct_group
(
atomicorstring)
optional grouping variable to be passed to thegroupargument ofmmrm::cov_struct(). It can be astringidentifying an existing variable name; otherwise the supplied expression will be quoted and turned into astringwithrlang::expr_deparse()(see Tidy evaluation support). Ignored ifcov_structsis alist. Defaults toNULL, in which case no grouping variable will be used.- mmrm_args
(named
list)
arguments to be passed tommrm::mmrm(). If any elements have the namesformula,data, orcovariancethey will be ignored. An element namedvcovwill also be ignored unless fitting a model with an unstructured covariance. Defaults tolist(method = "Satterthwaite").- emmeans_args
(named
list)
arguments to be passed toemmeans::emmeans(). If any elements have the namesobjectspecs, oratthey will be ignored. Ifaverage_nuisance = TRUE, any element namednuisancewill be ignored. Any elements namedparamsmay be ignored. Defaults tolist(nesting = NULL).- average_nuisance
(
flag)
flag indicating whether the names of the terms incovariatesshould be supplied as thenuisanceargument toemmeans::emmeans(). This results in treating all the covariates as nuisance parameters and averaging over them when calculating the reference grid to estimate marginal means. Seeemmeans::ref_grid()for details and limitations.- conf.level
(scalar
numeric)
confidence level for the calculation of p-values. Defaults to0.95.- change_in_bl_contrast_args, treatment_effect_contrast_args
(named
list)
arguments to be passed toemmeans::contrast()when calculating the change from baseline and treatment effect results. If any elements have the namesobjectormethodthey will be ignored. Defaults tolist(adjust = "none").- confint_args
(named
list)
arguments to be passed tostats::confint()when calculating confidence intervals for change in baseline and treatment effect. If any element has the nameobjectit will be ignored. Defaults tolist(level = conf.level).- return_models
(
flag)
flag indicating whether or not to return the model(s) used to calculate the results. See Obtaining the models used below.- expand_spline_terms
(
flag)
flag indicating whether or not to separate the cubic spline matrix into separate terms (one for each degree of freedom). Defaults toTRUE. See Expanding spline terms.- subgroup
(
factororstring)
the subgroup. It must be astringor a name identifying an existing variable (i.e., it cannot be a call). If a name, it will be quoted before being added to the model formula (see Tidy evaluation support). If it does not evaluate to a factor or ifsubgroup_comparatoris not its first level, thedataargument will be wrapped in adplyr::mutate()call that forces this to be the case.- subgroup_comparator
(
string)
the value insubgroupdenoting the "main" subgroup that all other subgroups should be compared to. If necessary,subgroupwill be preprocessed such that it is a factor withcontrol_groupas its first level.- subgroup_interaction_test
(
flag)
flag indicating whether or not the subgroup interaction test should be performed. IfTRUE, the returned value will include aninteractionelement, a data frame of results. Defaults toTRUE. See Subgroup interaction test for details.
Value
For ncs_analysis(), see splinetrials_analysis. For
ncs_analysis_subgroup(), see splinetrials_subgroup_analysis.
Overview
These functions create an mmrm model from the user-specified
arguments. They then perform a series of analyses and produce a data frame of
results with a unique row for each combination of arm,
time_scheduled_continuous, and subgroup (for ncs_analysis_subgroup()
only). The results include:
Basic diagnostics on the response variable
Estimated marginal means
Change from baseline
Treatment effect
Percent slowing
Building a model
See the details of ncs_mmrm_fit() for information on how the model is
built.
Subgroup analysis
ncs_analysis_subgroup() contains more analyses and results than
ncs_analysis(). Whereas the latter produces a data frame by default, the
former produces a list of data frames.
Treatment effects
The treatment effect is calculated twice: once between subgroups (examining
the differences between the subgroups within each study arm) and once
within subgroups (examining the differences between the study arms within
each subgroup). The main results table is effectively returned twice as both
the between element and the within element. These elements' treatment
effect values differ, and only the within element contains the percent
slowing analysis results.
Type-III ANOVA
The subgroup analyses include a type-III analysis of variance (ANOVA) on the
main analysis model's terms, using a Chi-squared test statistic. This is
accomplished via the mmrm method for car::Anova(). The results are
included in the returned value as the type3 element. See
vignette("hypothesis_testing", "mmrm") for details on the type-III ANOVA.
Subgroup interaction test
When subgroup_interaction_test = TRUE, the function runs an ANOVA to
compare a maximum-likelihood-estimated (ML) version of the original model to
a reduced version. This happens as follows:
The original analysis model is refit with
reml = FALSEif it was originally created withreml = TRUE. This may be dubbed the "full" model.A reduced version of the "full" model is created, removing the second-order interaction term (see the
armandsubgroupterms section above). This may be dubbed the "reduced" model.The "full" and "reduced" models are compared using the
mmrmmethod ofstats::anova().The results are processed into a table and added to the returned value as the
interactionelement.
Returning the models used
The model(s) used to conduct the analyses can be obtained by setting
return_models = TRUE.
For ncs_analysis(), the analysis model will be included as the
splinetrials_analysis_model attribute of the returned value.
For ncs_analysis_subgroup(), the analysis model is added to the returned
value as the analysis_model element. Furthermore, if
subgroup_interaction_test = TRUE, the "full" and "reduced" models will be
included in the returned value as the elements full and reduced (see
Subgroup interaction test above for details).
Examples
if (FALSE) { # interactive()
# Create a usable data set out of mmrm::fev_data
fev_mod <- mmrm::fev_data
fev_mod$VISITN <- fev_mod$VISITN * 10
fev_mod$time_cont <- fev_mod$VISITN + rnorm(nrow(fev_mod))
fev_mod$obs_visit_index <- round(fev_mod$time_cont)
# Without subgroup:
ncs_analysis(
data = fev_mod,
response = FEV1,
subject = USUBJID,
arm = ARMCD,
control_group = "PBO",
time_observed_continuous = time_cont,
df = 2,
time_observed_index = obs_visit_index,
time_scheduled_continuous = VISITN,
time_scheduled_baseline = 10,
time_scheduled_label = AVISIT,
covariates = ~ FEV1_BL + RACE,
cov_structs = c("ar1", "us")
)
# With subgroup:
ncs_analysis_subgroup(
data = fev_mod,
response = FEV1,
subject = USUBJID,
arm = ARMCD,
control_group = "PBO",
subgroup = SEX,
subgroup_comparator = "Male",
time_observed_continuous = time_cont,
df = 2,
time_observed_index = obs_visit_index,
time_scheduled_continuous = VISITN,
time_scheduled_baseline = 10,
time_scheduled_label = AVISIT,
covariates = ~ FEV1_BL + RACE,
cov_structs = c("ar1", "us")
)
}