brokenstick {brokenstick} | R Documentation |
Fit a brokenstick
model to irregular data
Description
The brokenstick()
function fits an irregularly observed series
of measurements onto a user-specified grid of points (knots).
The model codes the grid by a series of linear B-splines.
Each modelled trajectory consists of straight lines that join at
the chosen knots and look like a broken stick. Differences between
observations are expressed by a random effect per knot.
Usage
brokenstick(
formula,
data,
knots = NULL,
boundary = NULL,
k = 5L,
degree = 1L,
method = c("kr", "lmer"),
control = set_control(method = method, ...),
na.action = na.exclude,
light = FALSE,
hide = c("right", "left", "boundary", "internal", "none"),
...
)
Arguments
formula |
A formula specifying the outcome, the predictor and the group
variable in |
data |
A data frame or matrix containing the outcome (numeric), predictor (numeric) and group (numeric, factor, character) variable. |
knots |
Optional, but recommended. Numerical vector with the locations of the internal knots to be placed on the values of the predictor. The function sorts the internal knots in increasing order. |
boundary |
Optional, but recommended. Numerical vector of
length 2 with the left and right boundary knot. The |
k |
Optional, a convenience parameter for the number of
internal knots. If specified, then |
degree |
the degree of the spline. The broken stick model
requires linear splines, so the default is |
method |
Estimation method. Either |
control |
List of control options returned by |
na.action |
A function that indicates what |
light |
Should the returned object be lighter? If |
hide |
Should output for knots be hidden in get, print, summary and plot
functions? Can be |
... |
Forwards arguments to |
Details
The choice between method = "kr"
and method = "lmer"
depends on the size
of the data and the complexity of the model. In general, setting method = "lmer"
can require substantial calculation time for more complex models
(say > 8 internal knots) and may not converge. Method "kr"
is less
sensitive to model complexity and small samples, and has the added benefit that the
variance-covariance matrix of the random effects can be constrained through the
cormodel
argument. On the other hand, "lmer"
is the better-researched
method, and is more efficient for simpler models and datasets with many
rows.
The default algorithm since version 2.0 is the Bayesian Kasim-Raudenbush
sampler (method = "kr"
). The variance-covariance matrix of the broken stick
estimates absorbs the relations over time. The "kr"
method allows
enforcing a simple structure on this variance-covariance matrix. Currently,
there are three such correlation models: "none"
(default), "argyle"
and "cole"
. Specify the seed
argument for reproducibility.
See control_kr()
for more details.
The alternative method = "lmer"
fits the broken stick model by
lme4::lmer()
. With this method, the variance-covariance matrix can only be
unstructured. This estimate may be unstable if the number of children is
small relative to the number of specified knots. The default setting
in lme4::lmerControl()
is check.nobs.vs.nRE= "stop"
. The
[set_control()]
function changes this to check.nobs.vs.nRE= "warning"
by default, since otherwise many broken stick models would not run at all.
The method throws warnings that estimates are not stable. It can be time
for models with many internal knots. Despite the warnings,
the results often look reasonable.
Diagnostics with coda and lme4: The function returns an object
of class brokenstick
. For method = "kr"
the list component named
"mod"
contains a list of mcmc
objects that can be further analysed with
coda::acfplot()
, coda::autocorr()
, coda::crosscorr()
, coda::cumuplot()
,
coda::densplot()
, coda::effectiveSize()
, coda::geweke.plot()
,
coda::raftery.diag()
, coda::traceplot()
and the usual plot()
and summary()
functions. For method = "lmer"
the list component named
"mod"
contains an object of class lme4::merMod. These model objects
are omitted in light brokenstick
objects.
Value
A object of class brokenstick
.
Note
Note that automatic knot specification is data-dependent, and may not reproduce
on other data. Likewise, knots specified via k
are data-dependent and do not transfer
to other data sets. Fixing the model requires specifying both knots
and
boundary
.
Examples
data <- smocc_200[1:1198, ]
# using kr method, default
f1 <- brokenstick(hgt_z ~ age | id, data, knots = 0:2, seed = 123)
plot(f1, data, n_plot = 9)
# study sampling behaviour of the sigma2 parameter with coda
library("coda")
plot(f1$mod$sigma2)
acfplot(f1$mod$sigma2)
# using lmer method
f2 <- brokenstick(hgt_z ~ age | id, data, knots = 0:2, method = "lmer")
plot(f2, data, n_plot = 9)
# drill down into merMod object with standard diagnostics in lme4
summary(f2$mod)
plot(f2$mod)
# a model with more knots
knots <- round(c(0, 1, 2, 3, 6, 9, 12, 15, 18, 24, 36) / 12, 4)
# method kr takes about 2 seconds
f3 <- brokenstick(hgt_z ~ age | id, data, knots, seed = 222)
plot(f3, data, n_plot = 9)
# method lmer takes about 40 seconds
f4 <- brokenstick(hgt_z ~ age | id, data, knots, method = "lmer")
plot(f4, data, n_plot = 9)