| Type: | Package |
| Title: | Combines Changepoint Analysis with 'ggplot2' |
| Version: | 0.7.0 |
| Description: | A unified, tidy, 'ggplot2'-native interface to changepoint detection in R. A 'cpt_detect()' dispatcher covers 51 methods (penalised and optimal partitioning, multiscale and search methods, nonparametric and kernel methods, Bayesian methods, high-dimensional, functional, covariance and network methods, regression breaks through a formula interface, seasonal-trend decomposition, the classical single-change tests, and anomalous stretches that return to a baseline), with distribution families for counts, binary outcomes and waiting times, missing-value handling, grouped data, and constraints on locations and segment lengths. Every result is the same 'ggcpt' object, in one verified location convention, with 'broom'-style tidy/glance/augment methods, 'autoplot()' and composable 'ggproto' layers. Around detection: which coordinates of a multivariate series changed, certified with family-wise error control; distribution-free confidence sets for each location; effect sizes and what the series would have done without each change; a test for a change at a date fixed in advance, tests for a change anywhere, and screening of many series with false discovery rate control; a check of whether a change was abrupt or gradual; weights over the number of changes; assumption checks and goodness of fit, robustness to the noise model, stability, consensus and influence diagnostics, supervised detection, sequential monitoring including cumulative-sum and exponentially weighted moving-average control charts, power and study design, benchmarks, reports and an export under a documented 'JSON' schema. What each engine does (its runtime, whether its answer survives a change of units or a reversal of time, its false positives by noise regime and data type, its false alarms on pure noise) and the calibration of the package's own intervals, tests and monitors are measured and shipped as data, and 'cpt_recommend()' chooses from those measurements. 'cpt_register_method()' brings external and non-CRAN detectors into the same grammar. |
| Depends: | R (≥ 4.0.0) |
| License: | GPL (≥ 3) |
| Encoding: | UTF-8 |
| LazyData: | true |
| Imports: | changepoint, changepoint.np, dplyr, ecp, generics, ggplot2 (≥ 3.5.0), lifecycle, Rdpack, stats, tibble, tools, utils |
| RdMacros: | Rdpack |
| RoxygenNote: | 7.3.2 |
| Suggests: | rmarkdown, knitr, testthat (≥ 3.1.7), withr, rjags, vdiffr, svglite, wbs, breakfast, not, mosum, fpop, IDetect, stepR, cpop, bcp, ocp, Rbeast, cpm, kcpRS, CptNonPar, DeCAFS, SNSeg, InspectChangepoint, ocd, changepoint.geo, strucchange, segmented, EnvCpt, fastcpd, nsp, mcp, HDCD, changepoints, fChange, KWCChangepoint, fabisearch, NMF, wbsts, bfast, trend, ChangePointTaylor, binsegRcpp, crossvalidationCP, changepoint.influence, penaltyLearning, anomaly, zoo, xts, tsibble, jsonlite, gt, ggrepel, plotly, ggiraph, progressr, future, future.apply |
| Additional_repositories: | https://R-Forge.R-project.org, https://pursuitofdatascience.github.io/ggchangepoint/repo |
| Config/testthat/edition: | 3 |
| VignetteBuilder: | knitr |
| URL: | https://pursuitofdatascience.github.io/ggchangepoint/ |
| BugReports: | https://github.com/PursuitOfDataScience/ggchangepoint/issues |
| Config/Needs/website: | rmarkdown |
| NeedsCompilation: | no |
| Packaged: | 2026-11-05 03:02:41 UTC; youzhi |
| Author: | Youzhi Yu [aut, cre] |
| Maintainer: | Youzhi Yu <yuyouzhi666@icloud.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-11-05 04:10:02 UTC |
ggchangepoint package
Description
Unified tidy changepoint detection with ggplot2 visualisation.
Details
ggchangepoint provides a consistent S3 result class (ggcpt)
for changepoint detection results, broom-style methods
(tidy(), glance(), augment()), ggplot2
integration via autoplot() and composable geoms
(geom_changepoint(), geom_cpt_segment(),
geom_cpt_ci(), geom_cpt_region(), geom_cpt_label(),
geom_cpt_event(), stat_changepoint()), and a unified
dispatcher cpt_detect() that reaches 51 methods.
Detection engines. cpt_detect() dispatches to the methods in
cpt_methods(), across ten families:
-
Penalised/optimal: PELT, BinSeg, SegNeigh, AMOC (changepoint); FPOP (fpop); fast binary segmentation (binsegRcpp); the CROPS penalty path (
cpt_crops()); fastcpd (fastcpd, incl. AR/ARMA/GARCH); change-in-slope via CPOP (cpop). -
Multiscale/search: WBS (wbs), WBS2 and TGUH (breakfast), NOT (not), MOSUM incl. multiscale (mosum), Isolate-Detect (IDetect), SMUCE/HSMUCE with confidence intervals (stepR), WBS for nonstationary series (wbsts).
-
Inference: Narrowest Significance Pursuit (nsp), which returns intervals rather than points.
-
Nonparametric/kernel: NP (changepoint.np), E-Divisive/E-Agglo (ecp), kernel running statistics (kcpRS), NP-MOJO (CptNonPar), sequential CPM (cpm), self-normalisation (SNSeg), depth ranks (KWCChangepoint).
-
Bayesian: Barry-Hartigan posterior (bcp), online BOCPD (ocp), BEAST model averaging (Rbeast), formula-based regression with changepoints (mcp).
-
High-dimensional: sparse projection (InspectChangepoint), online ocd (ocd), geometric mapping (changepoint.geo), sparsity-adaptive ESAC and Pilliat (HDCD), and covariance, network, VAR and high-dimensional-regression changes (changepoints).
-
Functional and network: functional mean and covariance (fChange), NMF-based network structure (fabisearch).
-
Regression, trend and season: Bai-Perron breaks with CIs (strucchange), broken-line regression (segmented), changepoints-vs-autocorrelation model selection (EnvCpt), drift+AR robust detection (DeCAFS), BFAST season-and-trend breaks (bfast).
-
Classical single-change tests: Pettitt, Buishand and SNHT (trend), Taylor's analyzer (ChangePointTaylor).
-
Epidemic changes and anomalies: collective and point anomalies against a baseline, for one series or many (anomaly's CAPA).
What surrounds the detectors. Every detector returns a ggcpt
object with a stable tibble(cp, cp_value) contract, optionally
carrying a time index, engine confidence intervals, a fitted signal,
significance regions and diagnostics. Around that:
-
What to fit:
cpt_families()(Poisson, binomial, exponential and other costs), a formula for a regression break (cpt_detect(y ~ x, data)), andcpt_segment_models()andpredict()for a model per regime. -
How big, when, and whether at all:
cpt_effect(),cpt_test_at()(a date fixed in advance),cpt_attribute_event(),cpt_test_null(),cpt_null_power(). -
Should I believe it:
cpt_assumptions(),cpt_gof(),cpt_robustness(),cpt_verify(). -
Inference:
cpt_confint()(five provenances, one contract, including distribution-free conformal sets) andcpt_confint_coverage(),cpt_test(),cpt_regions(),cpt_attribute()(which coordinates changed),cpt_screen()(which of many series changed). -
What would have happened, and how:
cpt_counterfactual(),cpt_abruptness(). -
Choosing K:
cpt_select()(BIC, Zhang-Siegmund mBIC, AIC, CROPS elbow, cross-validation, stability),cpt_k_weights(),cpt_crops(),cpt_penalty(). -
Diagnostics:
cpt_influence(),cpt_leverage(),cpt_sensitivity(),cpt_stability(),cpt_statistic(),cpt_solution_path(),cpt_scale_space(). -
Supervised detection:
cpt_labels(),cpt_label_error(),cpt_label_error_curve(),cpt_learn_penalty(). -
Choosing a method:
cpt_recommend(),cpt_consensus(),ggcpt_compare(). -
Evaluation:
cpt_metrics(),cpt_metrics_annotated(),cpt_benchmark(),cpt_datasets(),cpt_load_tcpd(). -
Streaming:
cpt_monitor()(e-detector, CUSUM and EWMA control charts, cpm, ocd),cpt_update(),alarms(),cpt_replay(),cpt_delay(). -
Study design:
cpt_simulate(),cpt_power(),cpt_min_detectable(),cpt_scenarios(). -
Communication:
cpt_annotate_events(),cpt_report(),cpt_gt(),ggcpt_interactive(),cpt_cite(). -
Extension:
as_ggcpt()andcpt_register_method()bring detectors this package does not and cannot depend on into the same grammar. -
Leaving R:
as_json(),cpt_export(),cpt_import(). -
Measurements:
cpt_runtimes,cpt_invariances,cpt_noise_benchmark,cpt_data_types,cpt_null_sizes,cpt_calibration.
Every condition the package raises is classed; see ggchangepoint-conditions.
Author(s)
Maintainer: Youzhi Yu yuyouzhi666@icloud.com
See Also
The entry points, by group:
-
Detect:
cpt_detect(),cpt_methods(),cpt_families(),cpt_register_method(). -
After detection:
cpt_effect(),cpt_test_at(),cpt_assumptions(),cpt_robustness(). -
Visualise:
autoplot.ggcpt(),ggcptplot(),ggcpt_compare(). -
Inference and selection:
cpt_confint(),cpt_test(),cpt_attribute(),cpt_screen(),cpt_select(),cpt_k_weights(). -
What if:
cpt_counterfactual(),cpt_abruptness(). -
Choosing and combining methods:
cpt_consensus(),cpt_recommend(),cpt_benchmark(). -
Evaluation:
cpt_metrics(). -
Streaming:
cpt_monitor(). -
Study design:
cpt_simulate(),cpt_power(). -
Communication:
cpt_report().
Useful links:
Report bugs at https://github.com/PursuitOfDataScience/ggchangepoint/issues
The alarm log of a monitor
Description
Every observation at which a sequential monitor crossed its threshold, in
the order they fired. A monitor that never fired returns a zero-row tibble
rather than NULL, so the result is always safe to rbind() or
plot.
Usage
alarms(x, ...)
## S3 method for class 'ggcpt_monitor'
alarms(x, ...)
Arguments
x |
A |
... |
Ignored. |
Value
A tibble with one row per alarm: time (the observation at
which it fired, counted from the first one fed to the monitor),
statistic and threshold.
See Also
cpt_monitor(), cpt_delay().
Examples
set.seed(2026)
mon <- cpt_monitor("edetector", baseline = rnorm(100))
mon <- cpt_update(mon, c(rnorm(50), rnorm(50, 3)))
alarms(mon)
Annotate segments with alternating shading
Description
Adds alternating shaded rectangles to highlight segments between changepoints.
Usage
annotate_segments(cp, n, fill = c("grey90", "white"), alpha = 0.5, ...)
Arguments
cp |
Changepoint indices (including 0 and n). |
n |
Length of the series. |
fill |
Colors for alternating segments. Defaults to c("grey90", "white"). |
alpha |
Alpha for fill. Defaults to 0.5. |
... |
Additional arguments passed to |
Value
A list of ggplot annotations.
See Also
Other result class:
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
library(ggplot2)
set.seed(2026)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 4)), method = "pelt")
ggplot(fit$data, aes(index, value)) +
annotate_segments(fit$changepoints$cp, n = nrow(fit$data)) +
geom_line()
Coerce annotations to changepoint labels
Description
Turns a plain ground-truth changepoint set (the kind
cpt_metrics() takes) into labelled regions, so one
annotation can drive both the metric and the supervised machinery. Each
true changepoint becomes a "one_change" region of width
2 * margin + 1, and the stretches between them become
"no_change" regions.
Usage
as_cpt_labels(truth, n, margin = 5, negatives = TRUE, series = NA_character_)
Arguments
truth |
Integer vector of true changepoint positions. |
n |
Series length. |
margin |
Half-width of the positive regions. Defaults to |
negatives |
Add the |
series |
Optional series identifier. |
Value
A cpt_labels tibble.
Examples
as_cpt_labels(c(50, 120), n = 200)
Coerce a time series object to values plus a time index
Description
Detection itself runs on positions (every wrapped engine assumes an
equally spaced sequence), but real series carry dates, and reporting a
changepoint as "index 147" when the data are monthly rainfall is an
unnecessary translation step for the user. as_cpt_series() is the
one place that separates the two: it pulls the numeric values out of a
ts, xts, zoo, tsibble or data frame and
returns the time index alongside them, so cpt_detect() can
detect on positions and report on dates.
Usage
as_cpt_series(x, index = NULL, check_regular = TRUE)
Arguments
x |
A numeric vector or matrix, or a |
index |
Optional explicit index, one value per observation. Overrides
any index carried by |
check_regular |
Warn when the index is not equally spaced? Defaults
to |
Value
A list with components values (a numeric vector, or a
matrix for multivariate input), index (the time index, or
NULL when there is none), index_label (a name for the
x axis) and frequency (the seasonal frequency a ts
carried, or NULL; cpt_detect() hands this to
the engines that need one, such as bfast_wrapper()).
See Also
Other result class:
annotate_segments(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
as_cpt_series(1:10)$index
s <- as_cpt_series(1:10, index = as.Date("2020-01-01") + 0:9)
s$index
Turn external changepoints into a ggcpt result
Description
Wraps a set of changepoint locations (from a detector this package does
not wrap, a Python tool called through reticulate, a neural
detector, a published paper's reported breaks, or an analyst's own
annotations) into a first-class ggcpt object. Everything built on
the ggcpt contract then applies: autoplot(), the composable
geoms, tidy()/glance()/augment(),
cpt_metrics(), cpt_consensus(),
cpt_report().
Usage
as_ggcpt(
cp,
x,
fitted = NULL,
method = "custom",
change_in = "mean",
ci = NULL,
regions = NULL,
penalty = NULL,
cp_convention = c("left", "right"),
index = NULL,
fit = NULL,
extra = NULL
)
Arguments
cp |
Integer vector of changepoint locations. Out-of-range,
duplicated and missing values are dropped and the result is sorted,
the same contract every built-in wrapper is held to. But unlike a
wrapper, which is normalising an engine's output, this function is
given yours, so anything it drops it warns about, with the
values and the range they had to fall in. A fractional index is
included in that: it is truncated rather than rounded, which makes
|
x |
The series the changepoints refer to: a numeric vector, or a matrix/data frame (rows are time points) for a multivariate result. A one-column matrix or data frame is read as a univariate series. |
fitted |
Optional length- |
method |
Method label. Defaults to |
change_in |
What the changepoints are changes in. Defaults to
|
ci |
Optional two-column matrix or data frame of location confidence
intervals, one row per changepoint, giving lower and upper bounds as
positions in the same |
regions |
Optional two-column matrix or data frame of significance
regions ( |
penalty |
Optional penalty descriptor: a number, a string, or a list
with |
cp_convention |
|
index |
Optional time index, one value per observation. |
fit |
Optional raw upstream object to carry along. |
extra |
Optional named list of per-changepoint columns, each of the
same length as |
Value
A ggcpt object, with the same components as any
detector in the package returns (see new_ggcpt()
for the full list, and cpt_detect() for the summary).
See Also
cpt_register_method() to make
cpt_detect() dispatch to an external detector by name.
Other result class:
annotate_segments(),
as_cpt_series(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 4))
fit <- as_ggcpt(c(60), x, method = "my_detector")
fit
tidy(fit)
Convert a result to JSON
Description
The whole result as JSON, under a documented and versioned schema, for software that consumes changepoint results rather than a person reading them.
Usage
as_json(x, ...)
## S3 method for class 'ggcpt'
as_json(x, pretty = TRUE, data = TRUE, assumptions = TRUE, digits = NA, ...)
## Default S3 method:
as_json(x, ...)
Arguments
x |
A |
... |
Ignored. |
pretty |
Indent the output? Defaults to |
data |
Include the series itself ( |
assumptions |
Include |
digits |
Significant digits for numbers. Defaults to |
Value
A single string of class "json".
Schema 1.0.0
One object with these fields. Every field is always present; one that
does not apply is null, so a reader never has to test for a key.
schema,schema_version"ggchangepoint.ggcpt"and the version,"1.0.0".method,engine,engine_version,ggchangepoint_version,r_version,createdwhat produced the result, and when (ISO 8601).
change_in,familywhat was detected, and the distribution family if one was asked for.
penalty{"type", "value"}.cp_convention"left": a changepoint is the last observation of its segment.nthe series length.
index{"class", "label", "tz"}of the time index, ornull. Dates are written as ISO 8601 strings and timestamps with their offset;tzis a timestamp index's time zone (nullotherwise).changepointsan array of objects, one per changepoint:
cp(position) andcp_value, withcp_indexwhen there is an index, and every engine-specific column (ci_lower,ci_upper,posterior_prob, ...).segmentsseg_id,start,end,n,param_estimate.regions,coefficients,constraintsthe optional slots, as arrays of objects (or an object), or
null.diagnosticsresidual_dependence(Ljung-Boxp_value,lag,acf1),na_omittedandexpected_false_positiveswhere recorded.assumptionsthe
cpt_assumptions()rows, ornull.callthe call that made the result, as text.
data{"index", "value", "fitted", "coordinates"}arrays, ornull.coordinatesis an object with one array per coordinate of a multivariate result (nullfor a single series), whose first isvalue.
See Also
cpt_export() to write a file,
cpt_import() to read one back,
cpt_report(format = "json").
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 3)), method = "pelt")
cat(as_json(fit, data = FALSE))
Augment a ggcpt object
Description
Returns the original data with added columns: seg_id, .fitted,
.resid, and is_changepoint.
Usage
## S3 method for class 'ggcpt'
augment(x, ...)
Arguments
x |
A |
... |
Additional arguments (ignored). |
Details
For a multivariate result every coordinate is returned, but the
changepoints are shared across them, so seg_id and
is_changepoint apply to the whole row. Each coordinate also gets
its own .fitted_<name> and .resid_<name> (its segment
means and residuals), while .fitted and
.resid describe the univariate series the result
carries: $data$value, the same series
$segments$param_estimate summarises, so .resid is always
value - .fitted. For most multivariate engines that series is
the first coordinate; fmean, fcov, kwc and
fabisearch store the cross-sectional mean rowMeans()
instead, and for those .fitted/.resid describe that mean
rather than any one column. Either way the two columns agree with each
other, which is what makes .resid a residual. When an engine
supplies its own fitted signal that signal is used for .fitted in
place of the segment means, and rides along in a fitted column of
its own, so for those engines the two columns agree. The engines that
do this are exactly the ones cpt_methods() marks in its
fitted column: smuce, hsmuce, cpop,
bcp, bocpd, beast, decafs,
segmented, envcpt, mcp and bfast; a
formula fit carries its piecewise regression's fitted values the same
way.
Value
A tibble with one row per observation: the data as the result
carries it, plus four added columns. The data half depends on the
result: index and value for a univariate one,
index plus one column per coordinate (named as the
input's columns were) for a multivariate one, and an extra
fitted column for the engines that supply their own fitted
signal. The added four are always the same:
seg_idwhich segment the observation falls in, counting from 1.
.fittedthe segment's
param_estimate: the segment mean, for every method in the package, or the engine's own fitted signal where there is one. See the details below for the multivariate case..residvalue - .fitted, against the univariate series the result carries.is_changepointTRUEat each detected location, under the result'scp_convention.
Measured on a pelt fit the columns are index,
value, seg_id, .fitted, .resid,
is_changepoint.
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(60), rnorm(60, 3)), method = "pelt")
head(augment(fit))
Autoplot a ggcpt object
Description
Renders a changepoint detection result as a ggplot. The raw series is drawn
as a line (with optional points), changepoints are shown as vertical lines,
and (optionally) fitted segment levels, the engine's fitted signal, and
changepoint-location confidence intervals are overlaid. Multivariate
results (from ecp, inspect, geomcp, ...) are drawn as
faceted small-multiples with shared changepoint rules.
Usage
## S3 method for class 'ggcpt'
autoplot(
object,
show_segments = FALSE,
show_ci = FALSE,
show_fit = FALSE,
show_regions = NULL,
cptline_alpha = 1,
cptline_color = "blue",
cptline_type = "solid",
cptline_linewidth = 0.5,
show_points = NULL,
show_line = TRUE,
index = NULL,
labels = NULL,
type = c("series", "statistic", "path", "scale_space", "diagnostics", "counterfactual",
"attribution"),
...
)
Arguments
object |
A |
show_segments |
Logical. Whether to draw the fitted segment means.
Defaults to |
show_ci |
Logical. Whether to draw confidence intervals for
changepoint locations, when the engine provides them (columns
|
show_fit |
Logical. Whether to draw the engine's fitted signal (the
|
show_regions |
Logical. Whether to draw the |
cptline_alpha |
Alpha for changepoint lines. Defaults to |
cptline_color |
Color for changepoint lines. Defaults to |
cptline_type |
Linetype for changepoint lines. Defaults to |
cptline_linewidth |
Linewidth for changepoint lines. Defaults to |
show_points |
Logical. Whether to draw data points. Auto-off above 500 obs. |
show_line |
Logical. Whether to draw the line. Defaults to |
index |
Optional vector of x-axis values (e.g. dates) of the same
length as the series. Defaults to the time index carried by the result
(see the |
labels |
Optional |
type |
Which view to draw. |
... |
Unknown arguments are ignored with a warning, except when
|
Value
A ggplot object.
See Also
ggcpt_plot_methods for the base plot()
methods that delegate here, and theme_ggcpt() and
geom_changepoint() for restyling and re-assembling the
layers by hand.
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(60), rnorm(60, 3), rnorm(60)), method = "pelt")
ggplot2::autoplot(fit)
ggplot2::autoplot(fit, type = "diagnostics")
# a dated series draws its dates
dated <- cpt_detect(Nile, method = "pelt", change_in = "meanvar")
ggplot2::autoplot(dated)
Bayesian changepoint wrapper (Barry-Hartigan product partition model)
Description
Wraps bcp::bcp(), the MCMC implementation (Erdman and Emerson, 2007)
of the Barry and Hartigan (1993) product partition model. The engine
returns a posterior probability of a changepoint at every location;
locations whose posterior probability reaches prob_threshold are
reported as changepoints, and the full probability profile is kept so that
ggcpt_posterior() can draw the classic two-panel posterior
plot.
Usage
bcp_wrapper(x, prob_threshold = 0.5, burnin = 50, mcmc = 500, seed = NULL, ...)
Arguments
x |
A numeric vector. |
prob_threshold |
Posterior probability cutoff in |
burnin |
Number of burn-in MCMC iterations. Defaults to |
mcmc |
Number of post-burn-in MCMC iterations. Defaults to |
seed |
Optional seed for reproducibility of the MCMC run. The seed
is scoped to this call: |
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries a
posterior_prob column, and the data tibble carries the
posterior mean in its fitted column.
References
Barry D, Hartigan JA (1993). “A Bayesian analysis for change point problems.” Journal of the American Statistical Association, 88(421), 309–319.
Erdman C, Emerson JW (2007). “bcp: An R package for performing a Bayesian analysis of change point problems.” Journal of Statistical Software, 23(3), 1–13.
See Also
Other changepoint engines:
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
res <- bcp_wrapper(c(rnorm(60), rnorm(60, 4)), seed = 2026)
res$changepoints
ggcpt_posterior(res)
BEAST wrapper: Bayesian estimation of abrupt change, seasonality, and trend
Description
Wraps Rbeast::beast() (Zhao et al., 2019), a Bayesian
model-averaging ensemble that estimates the number and location of trend
changepoints together with their posterior occurrence probabilities.
Locations whose posterior probability reaches prob_threshold are
reported; the probability profile renders via
ggcpt_posterior().
Usage
beast_wrapper(x, prob_threshold = 0.5, seed = NULL, ...)
Arguments
x |
A numeric vector (treated as a non-seasonal series). |
prob_threshold |
Posterior probability cutoff in |
seed |
Optional seed for the engine's MCMC sampler (passed to
|
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries
posterior_prob, and the data tibble carries the posterior
mean trend in its fitted column.
References
Zhao K, Wulder MA, Hu T, Bright R, Wu Q, Qin H, Li Y, Toman E, Mallick B, Zhang X, Brown M (2019). “Detecting change-point, trend, and seasonality in satellite time series data to track abrupt changes and nonlinear dynamics: A Bayesian ensemble algorithm.” Remote Sensing of Environment, 232, 111181.
See Also
Other changepoint engines:
bcp_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
# try(): Rbeast intermittently returns an all-NaN fit and the condition
# can persist for a session, so a check must not fail on it; the
# wrapper reports it by name when it happens.
res <- try(beast_wrapper(c(rnorm(60), rnorm(60, 4)), seed = 2026),
silent = TRUE)
if (!inherits(res, "try-error")) res$changepoints
BFAST wrapper: breaks for additive season and trend
Description
Wraps the bfast family (Verbesselt et al.), the standard tool in remote sensing and land-cover monitoring. BFAST decomposes a seasonal series into trend and seasonal components and detects breaks in each separately, which is the right question for satellite time series where a shift in phenology and a shift in level mean different things.
Usage
bfast_wrapper(
x,
frequency = 12,
change_in = c("mean", "slope", "seasonality"),
h = 0.15,
season = c("harmonic", "dummy", "none"),
max_iter = 5,
...
)
Arguments
x |
A numeric vector, or a |
frequency |
Observations per season, used when |
change_in |
Which component's breaks to report: |
h |
Minimal segment size as a fraction of the series. Defaults to
|
season |
Seasonal model: |
max_iter |
Maximum iterations of the trend/season loop. Defaults to
|
... |
Additional arguments passed to |
Value
A ggcpt object whose fitted column holds the
estimated trend component (so autoplot(show_fit = TRUE) draws it)
and whose changepoints carry ci_lower/ci_upper from
strucchange's break-date intervals when available.
References
Verbesselt J, Hyndman R, Newnham G, Culvenor D (2010). “Detecting trend and seasonal changes in satellite image time series.” Remote Sensing of Environment, 114(1), 106–115. doi:10.1016/j.rse.2009.08.014.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
season <- rep(sin(seq(0, 2 * pi, length.out = 12)), 10)
y <- stats::ts(c(rnorm(60, 1), rnorm(60, 5)) + season,
frequency = 12, start = c(2000, 1))
bfast_wrapper(y)
Fast binary segmentation across loss functions
Description
Wraps binsegRcpp::binseg() (Hocking): a C++ binary segmentation
that runs in O(n \log n) for the best case and supports several
loss functions, including ones no other engine here offers (Poisson,
\ell_1). It is the package's performance path for binary
segmentation on long series, and it returns the whole nested family of
segmentations, so it also feeds cpt_solution_path().
Usage
binsegrcpp_wrapper(
x,
change_in = c("mean", "meanvar"),
distribution = NULL,
max_segments = NULL,
n_segments = NULL,
min_segment_length = NULL
)
Arguments
x |
A numeric vector. |
change_in |
|
distribution |
Loss function, overriding the mapping from
|
max_segments |
Largest number of segments searched. Defaults to
|
n_segments |
Number of segments to report. When |
min_segment_length |
Minimum segment length. Defaults to |
Value
A ggcpt object.
References
Hocking TD (2024). “Finite sample complexity analysis of binary segmentation.” arXiv preprint arXiv:2410.08654. doi:10.48550/arXiv.2410.08654.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
binsegrcpp_wrapper(c(rnorm(100), rnorm(100, 3)))
Bayesian online changepoint detection wrapper (BOCPD)
Description
Wraps ocp::onlineCPD(), an implementation of Bayesian Online
Changepoint Detection (Adams and MacKay, 2007). BOCPD recursively updates
a posterior over the current run length (time since the last
change); the maximum a posteriori set of changepoints is reported, and the
full run-length posterior is kept so that ggcpt_runlength()
can draw the signature run-length heatmap.
Usage
bocpd_wrapper(x, hazard = 100, ...)
Arguments
x |
A numeric vector. |
hazard |
The |
... |
Additional arguments passed to |
Value
A ggcpt object with the MAP changepoint set. The full
ocp fit (including the run-length posterior) is kept in
$fit.
References
Adams RP, MacKay DJ (2007). “Bayesian online changepoint detection.” arXiv preprint arXiv:0710.3742.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
res <- bocpd_wrapper(c(rnorm(60), rnorm(60, 4)))
res$changepoints
ggcpt_runlength(res)
CAPA wrapper: collective and point anomalies (epidemic changepoints)
Description
Wraps anomaly::capa() (Fisch, Eckley and Fearnhead 2022): finds
stretches of the series that depart from a persistent baseline and
return to it (collective anomalies: an outbreak that subsides, a
fault that is repaired, a campaign that ends) and single outlying
observations (point anomalies), for one series or many. For a
multivariate series it also reports which coordinates each anomaly
affects.
Usage
capa_wrapper(
x,
change_in = c("mean", "meanvar"),
robust = FALSE,
beta = NULL,
beta_tilde = NULL,
min_seg_len = 10,
max_seg_len = Inf,
max_lag = 0,
standardise = TRUE,
...
)
Arguments
x |
A numeric vector, or a matrix or data frame with one column per coordinate. |
change_in |
|
robust |
For |
beta |
Penalty for a collective anomaly: one number, or one per
coordinate. |
beta_tilde |
Penalty for a point anomaly. |
min_seg_len |
Shortest collective anomaly, at least 2. Defaults to
|
max_seg_len |
Longest collective anomaly. Defaults to |
max_lag |
For a multivariate series, how far an anomaly's start and
end may differ between coordinates. Defaults to |
standardise |
Centre and scale each coordinate by its median and
median absolute deviation before the search. Defaults to |
... |
Not used; present so the dispatcher can pass its own arguments through. Anything supplied is refused by name. |
Value
A ggcpt object whose changepoints are the anomaly
boundaries and whose regions slot lists the anomalies, plus a
baseline element holding the centre and scale used to
standardise each coordinate.
How the result reads
The baseline is everything that is not anomalous, and it is one regime,
which is what separates this model from an ordinary segmentation. Each
collective anomaly from s to e contributes two
changepoints, s - 1 (the last baseline observation before it) and
e (its last observation), so the segments alternate between the
baseline and the anomalies and every tool built on changepoints works
unchanged. The anomalies themselves are in the regions slot,
read with cpt_regions(): one row per anomaly with
start, end, type ("collective" or
"point"), coordinates (the affected coordinates, comma
separated), mean_change (the engine's squared standardised mean
change for a collective anomaly) and strength (the engine's
strength for a point anomaly). Point anomalies are outliers, not
changes, so they add no changepoint. autoplot() shades the
collective anomalies and rings the point ones, and
cpt_attribute() can certify, with error control, which
coordinates changed at each boundary.
A series whose two halves differ, with no baseline to return to, is not what CAPA models: the median of such a series lies between the two levels, so both halves look anomalous. Use an ordinary detector for a step.
References
Fisch ATM, Eckley IA, Fearnhead P (2022). “A linear time method for the detection of collective and point anomalies.” Statistical Analysis and Data Mining, 15(4), 494–508. doi:10.1002/sam.11586.
Fisch ATM, Eckley IA, Fearnhead P (2022). “Subset multivariate collective and point anomaly detection.” Journal of Computational and Graphical Statistics, 31(2), 574–585. doi:10.1080/10618600.2021.1987257.
See Also
cpt_regions(), cpt_attribute().
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(150), rnorm(40, 3), rnorm(150))
x[60] <- 9
fit <- capa_wrapper(x)
cpt_regions(fit)
ggplot2::autoplot(fit)
Sequential change point model wrapper (CPM)
Description
Wraps cpm::processStream() (Ross, 2015) for distribution-free
sequential changepoint detection via repeated two-sample tests
(Mann-Whitney for location, Mood for scale, Lepage, Kolmogorov-Smirnov and
Cramer-von-Mises for general changes, and parametric Student/Bartlett/GLR
variants). Although the engine is designed for streams, it is run here
over the full series in one pass, mimicking online monitoring with average
run length arl0.
Usage
cpm_wrapper(x, cpm_type = "Mann-Whitney", arl0 = NULL, startup = 20, ...)
Arguments
x |
A numeric vector. |
cpm_type |
Test statistic, passed to |
arl0 |
Target in-control average run length (how many observations,
on average, before a false alarm). cpm
ships thresholds only for a fixed grid (100, 200, 300, 370, 400, 500,
600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000,
9000, 10000, 20000, 30000, 40000 and 50000), and any other value is
refused, because the engine answers it by printing an error and
reporting no changepoints. The grid is the same for every
When |
startup |
Number of observations after each restart before monitoring
begins. Defaults to |
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries a
detection_time column: the index at which the sequential test
flagged each change (always later than the estimated location).
References
Ross GJ (2015). “Parametric and nonparametric sequential change detection in R: The cpm package.” Journal of Statistical Software, 66(3), 1–20.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
res <- cpm_wrapper(c(rnorm(100), rnorm(100, 3)))
res$changepoints
CPOP wrapper: optimal change-in-slope detection
Description
Wraps cpop::cpop() (Fearnhead, Maidstone and Letchford, 2019;
Fearnhead and Grose, 2024): exact penalised estimation of a
continuous piecewise-linear mean via dynamic programming with
functional pruning. This is the engine behind
cpt_detect(change_in = "slope"). The fitted broken line is stored
in the fitted column and renders via
autoplot(show_fit = TRUE).
Usage
cpop_wrapper(x, penalty = NULL, sd = NULL, ...)
Arguments
x |
A numeric vector. |
penalty |
Penalty for adding a changepoint. Defaults to
|
sd |
Noise standard deviation; when |
... |
Additional arguments passed to |
Value
A ggcpt object with change_in = "slope". For a
continuous fit the reported location is the kink point itself.
References
Fearnhead P, Maidstone R, Letchford A (2019). “Detecting changes in slope with an L0 penalty.” Journal of Computational and Graphical Statistics, 28(2), 265–275.
Fearnhead P, Grose D (2024). “cpop: Detecting changes in piecewise-linear signals.” Journal of Statistical Software, 109(7), 1–30.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
y <- cumsum(c(rep(0.3, 100), rep(-0.4, 100))) + rnorm(200)
res <- cpop_wrapper(y)
res$changepoints
ggplot2::autoplot(res, show_fit = TRUE)
Was the change abrupt? A step against a ramp, at every changepoint
Description
For each changepoint of a change in mean, fits the window around it (between the neighbouring changepoints) twice: as a step, which is what every detector assumes, and as a linear ramp from the old level to the new one, with its centre and width estimated. When the ramp fits clearly better, the change took time, and the reported location is the middle of a transition rather than a moment.
Usage
cpt_abruptness(fit, level = 0.95, max_width = NULL)
## S3 method for class 'ggcpt_abruptness'
print(x, ...)
## S3 method for class 'ggcpt_abruptness'
tidy(x, ...)
## S3 method for class 'ggcpt_abruptness'
autoplot(object, ...)
Arguments
fit |
A |
level |
Level of the interval for the transition width, and
|
max_width |
Widest ramp considered, in observations. Defaults to half the window. |
x |
A |
... |
Ignored. |
object |
A |
Value
A ggcpt_abruptness tibble with one row per changepoint:
cp, window_start, window_end, width (the
best ramp width, in observations), width_lower and
width_upper (its interval), centre (the ramp's centre),
statistic (the likelihood-ratio statistic against the step),
p_value and verdict ("abrupt" when the step is
not rejected, "gradual" when it is). autoplot() draws
each window with the step and the ramp; print() and
tidy() work as usual.
How it decides
For a ramp of width w centred at c, the level is a
before c - w/2, b after c + w/2, and linear between,
so for fixed (c, w) the fit is ordinary least squares in
(a, b). The residual sum of squares is profiled over the centre
for each width on a grid (every width up to 8, then geometric), and the
step is the width-0 member of the family. The statistic
m \log(RSS_{step} / RSS_{ramp}) over the window's m
observations is compared with a chi-squared distribution on one degree
of freedom. The step sits on the boundary of the family, which makes
that reference conservative, and the search over widths and centres,
which makes it liberal; measured on true steps (jumps of 1 to 8 noise
standard deviations, n of 300 and 1,000, Gaussian and t_3
noise, 400 replicates each, detected with pelt), the step was
rejected in 1.0 to 5.2 per cent of fits at level = 0.95. A ramp
of 2 standard deviations over 30 observations was called gradual in 53
per cent of fits at n = 300, over 60 observations in 70 per cent.
The width interval collects every width whose profile statistic is
within the chi-squared quantile of the best.
A ramp also fits a step plus a few outliers near it, and a window that
holds a second, undetected change; read "gradual" as "a step is
not an adequate description", and look at autoplot().
See Also
cpt_simulate() with transition, to measure
how a detector places a gradual change; cpt_gof().
Other inference:
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(2026)
ramp <- c(rep(0, 100), seq(0, 4, length.out = 30), rep(4, 100))
fit <- cpt_detect(ramp + rnorm(230, 0, 0.5), method = "pelt")
cpt_abruptness(fit)
step <- cpt_detect(c(rnorm(100), rnorm(100, 4)), method = "pelt")
cpt_abruptness(step)
Match detected changepoints to known events
Description
Joins a table of real-world events to a detection result and reports all
three outcomes: changepoints an event explains, changepoints no event
explains, and events no changepoint found. Matching reuses the same
tolerance rule as cpt_metrics() and
cpt_consensus(), so the package has one notion of "close
enough" throughout.
Usage
cpt_annotate_events(
object,
events,
location = NULL,
label = NULL,
tolerance = 5
)
## S3 method for class 'ggcpt_events'
print(x, ...)
## S3 method for class 'ggcpt_events'
tidy(x, ...)
## S3 method for class 'ggcpt_events'
autoplot(object, repel = NULL, ...)
Arguments
object |
A |
events |
A data frame of events with a location column and a label
column. The location may be on the position scale or, when the result
carries a time index, on the index scale (dates, say); which one is
detected automatically from the column's type and reported. An event
whose location cannot be placed on the series (a missing value, text
that is not a number, or a date string against a |
location |
Name of the location column. Defaults to the first column whose type matches the result's index (or the first numeric column). |
label |
Name of the label column. Defaults to the first character or factor column. |
tolerance |
Matching window in positions. Defaults to |
x |
A |
... |
Ignored. |
repel |
Use ggrepel for the event labels? Defaults to
|
Value
A ggcpt_events object: a list with
matchedone row per matched pair:
cp,event,event_value(the event's own location, on the index scale when it was given as one),event_position(that location as a position in the series) anddistance.unexplaineddetected changepoints with no event (
cp).undetectedevents with no changepoint (
event,event_value,event_position).
matched and unexplained carry cp_index, the
changepoint on the original scale, when (and only when) the result
carries a time index, so "cp_index" %in% names(x) is the
test for it.
tidy() flattens those three slots into one table with
a status column, and the row count is therefore the number of
changepoints plus the number of events, not either one alone.
The three values are
"matched" (a pair: both cp and event filled,
with distance), "unexplained_changepoint" (a
changepoint with no event: cp filled, event and
distance NA) and "undetected_event" (an event
with no changepoint: event and position filled,
cp and distance NA).
Filter on status, not on is.na(cp). An
"unexplained_changepoint" row has a non-missing cp, so
subset(tidy(x), !is.na(cp)) returns the matched pairs
and the unexplained changepoints, which is the natural
mistake to make, and it silently overstates how many changepoints an
event explains.
With print(), tidy() and autoplot().
See Also
geom_cpt_event(), cpt_report().
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 4))
dates <- as.Date("2020-01-01") + 0:119
fit <- cpt_detect(x, method = "pelt", index = dates)
events <- data.frame(when = as.Date(c("2020-03-01", "2020-04-15")),
what = c("policy change", "supply shock"))
cpt_annotate_events(fit, events)
Per-annotator ground truth for a benchmark dataset
Description
Returns the annotation sets of a dataset one row per (annotator, changepoint), so the disagreement between human annotators is visible instead of averaged away.
Usage
cpt_annotations(dataset)
Arguments
dataset |
A dataset in the |
Value
A tibble with dataset, annotator and cp.
See Also
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
cpt_annotations(cpt_datasets(n = 200, names = "step"))
Check the assumptions behind a segmentation
Description
A short report on whether the result's assumptions look violated for this series, what that does to the answer, and what would model it. It reports and does not act: every automatic correction measured trades true changepoints for false ones, and which side of that trade matters is the analyst's decision.
Usage
cpt_assumptions(fit, lag = NULL)
## S3 method for class 'ggcpt_assumptions'
print(x, ...)
## S3 method for class 'ggcpt_assumptions'
tidy(x, ...)
Arguments
fit |
A |
lag |
Lag for the Ljung-Box test. Defaults to |
x |
A |
... |
Ignored. |
Value
A ggcpt_assumptions tibble with one row per check:
component, value, flag (TRUE when the check
raises a concern), detail and advice. The components:
residual_dependenceLjung-Box p-value on the within-segment residuals (and their lag-1 autocorrelation in
detail). Flagged below 0.05. Autocorrelated noise is the commonest reason for spurious changepoints.scale_sensitivitythe noise standard deviation, flagged when the engine's answer depends on the data's units (measured) and the noise is far from unit scale.
expected_false_positiveshow many changepoints the engine is expected to report on this much pure noise:
n / arl0forcpm, and the measured null-size table otherwise. Flagged above one.count_plausibilityreported changepoints per hundred observations, flagged above one: more than
n / 100is more often misconfiguration than a finding.data_typewhat the series looks like (continuous, counts, binary, proportions), flagged when a Gaussian cost is fitted to non-Gaussian data.
See Also
cpt_report(), which prints this;
cpt_robustness() for the answer under other noise models.
Other inference:
cpt_abruptness(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
ar <- as.numeric(arima.sim(list(ar = 0.7), 300))
cpt_assumptions(cpt_detect(ar, method = "pelt"))
Which coordinates changed? Certified attribution for a multivariate fit
Description
For each changepoint of a multivariate result, tests every coordinate
for a change in its window and returns the set certified to have
changed, with family-wise error or false discovery rate control and a
location or scale label for each certified coordinate. This is ARM,
attribution by rank maxima (Peng et al. 2026). It accepts the
changepoints of any detector, including a registered one or a result
built with as_ggcpt(), and its guarantee does not depend
on how, or how well, they were located.
Usage
cpt_attribute(
object,
alpha = 0.05,
control = c("fwer", "holm", "fdr"),
B = 999,
margin = NULL,
seed = NULL
)
## S3 method for class 'ggcpt_attribution'
print(x, ...)
## S3 method for class 'ggcpt_attribution'
tidy(x, ...)
## S3 method for class 'ggcpt_attribution'
glance(x, ...)
## S3 method for class 'ggcpt_attribution'
autoplot(object, ...)
Arguments
object |
A multivariate |
alpha |
Error level. Defaults to |
control |
What
|
B |
Number of permutations. Defaults to |
margin |
Smallest number of observations on either side of a split, within the window. Defaults to five per cent of the window, and at least 2. It changes power, not validity. |
seed |
Optional seed for the permutations, scoped to this call. |
x |
A |
... |
Ignored. |
Value
A ggcpt_attribution tibble with one row per changepoint
and coordinate: cp, cp_index (when the result has a time
index), coordinate, statistic (the coordinate's maximum
over splits and channels), statistic_location,
statistic_scale, p_value (the per-coordinate permutation
p-value), p_adjusted (adjusted for control),
changed (TRUE when certified at alpha),
type ("location" or "scale" for a certified
coordinate, NA otherwise), window_start,
window_end, n_window (rows used, after dropping any with
a missing value) and source ("arm"). print(),
autoplot() (a coordinate-by-changepoint map with the certified
cells outlined), tidy() and glance() work on it.
What is certified, and what is not
Each changepoint is examined in its own window: the stretch of
the series between its neighbouring changepoints (the whole series for
a single changepoint). Coordinate j is tested for the null
hypothesis that its values in the window are identically distributed,
that is, that it did not change there. For every split t of the
window the location evidence is the standardised Wilcoxon rank sum and
the scale evidence the standardised Mood statistic (squared centred
ranks), each computed from that coordinate's own ranks; the
coordinate's statistic is the largest of the two over every split. That
maximum is what makes the result independent of the detector: no
estimate of the location can make a coordinate that did not change
look more changed than the maximum already allows for.
The guarantees are per changepoint. With K changepoints the
chance of any false attribution anywhere is at most K times
alpha under "fwer" and "holm". They also take the
window as given: the neighbouring changepoints were located from the
same data, so for a fit with several changepoints the guarantee holds
conditionally on those windows, and exactly for a single changepoint.
Rows of the window are assumed independent (permutation is exchangeable
only then), so serially dependent data need care, as everywhere else.
The type label is descriptive and carries no error control of its own:
"scale" when the scale evidence is the larger, "location"
otherwise.
References
Peng C, Wu M, Yan Q, Chen D, Shen Z (2026). “ARM: Detector-Agnostic Changepoint Attribution with Finite-Sample Error Control.” arXiv preprint arXiv:2608.01691.
See Also
cpt_confint() for where a changepoint is;
cpt_attribute_event() for attributing a change to a
named event rather than to a coordinate.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(2026)
n <- 120
X <- matrix(rnorm(n * 6), n, 6,
dimnames = list(NULL, paste0("sensor", 1:6)))
X[61:n, 2] <- X[61:n, 2] + 2 # a shift in sensor2
X[61:n, 5] <- X[61:n, 5] * 3 # a scale change in sensor5
fit <- cpt_detect(X, method = "ecp")
att <- cpt_attribute(fit, B = 199, seed = 1)
att
ggplot2::autoplot(att)
Was a detected change the event you have in mind?
Description
The mirror of cpt_test_at(). A detector found a change on
14 March and something is known to have happened on 1 March: is that the
same event? The detection's confidence interval answers it: an event
inside the interval is consistent with being the change, one outside is
not.
Usage
cpt_attribute_event(fit, event, level = 0.95, ...)
Arguments
fit |
A |
event |
One or more event locations: positions, values of the fit's
index, or a |
level |
Confidence level of the interval. Defaults to |
... |
Further arguments for |
Value
A tibble with one row per event: event,
event_position, the nearest changepoint cp (and
cp_index), its interval ci_lower/ci_upper,
distance (positions from the changepoint to the event),
inside and a plain-language verdict.
See Also
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
dates <- as.Date("2026-01-01") + 0:119
fit <- cpt_detect(c(rnorm(60), rnorm(60, 3)), method = "strucchange",
index = dates)
cpt_attribute_event(fit, as.Date(c("2026-02-28", "2026-04-10")))
Batch changepoint detection over many series
Description
Runs one detector over every series in a collection: the panel-data loop
that methodological and applied work both need constantly. Accepts a
matrix/data frame (one column per series) or a named list of numeric
vectors. Honours future::plan() for parallel execution when the
future.apply package is available, with parallel-safe RNG.
Usage
cpt_batch(
x,
method = "pelt",
change_in = "mean",
index = NULL,
seed = NULL,
keep_fit = TRUE,
...
)
## S3 method for class 'ggcpt_batch'
print(x, ...)
## S3 method for class 'ggcpt_batch'
tidy(x, ...)
## S3 method for class 'ggcpt_batch'
autoplot(object, ...)
Arguments
x |
For |
method |
Detection method, passed to |
change_in |
What to detect change in, passed to
|
index |
Optional time index shared by every series in the panel (a
vector of dates, say), or a named list of one index per series. A list
has to cover every series, with indices of one type, because
|
seed |
Optional seed for reproducible parallel execution (passed to
|
keep_fit |
Keep each engine's raw fit in |
... |
Additional arguments passed to every |
object |
A |
Value
A ggcpt_batch object: a tibble with one row per series and
columns series, n_changepoints, changepoints (a
list-column of tidy tibbles), and result (a list-column of
ggcpt objects). Methods: print(), tidy() (one row
per changepoint across all series, with columns series,
cp and cp_value), and autoplot() (faceted
small-multiples with each series' changepoints).
Examples
set.seed(2026)
X <- cbind(a = c(rnorm(60), rnorm(60, 4)), b = rnorm(120))
batch <- cpt_batch(X, method = "pelt")
batch
tidy(batch)
ggplot2::autoplot(batch)
Benchmark detectors across datasets
Description
Runs a grid of methods over a collection of labelled series and scores
every cell with cpt_metrics() (or
cpt_metrics_annotated() when a dataset carries several
annotators). A method that fails on one dataset (its engine errors, is
not installed, or cannot take that series: see
ggchangepoint-conditions) records the message and the grid
continues. Invalid data or arguments, which every method would reject,
stop the benchmark instead, naming the dataset and method, so a mistake
in the call is not reported as a finding about an engine.
Usage
cpt_benchmark(
datasets,
methods = c("pelt", "binseg", "wbs"),
metrics = c("covering", "f1"),
tolerance = 5,
change_in = "mean",
parallel = TRUE,
progress = TRUE,
seed = NULL,
...
)
## S3 method for class 'ggcpt_benchmark'
print(x, ...)
## S3 method for class 'ggcpt_benchmark'
tidy(x, ...)
## S3 method for class 'ggcpt_benchmark'
autoplot(
object,
plot_type = c("heatmap", "ranks", "critical_difference"),
metric = NULL,
alpha = 0.05,
...
)
Arguments
datasets |
A named list of datasets. Each element is either a plain
numeric vector (no ground truth, so only descriptive columns are filled)
or a list with |
methods |
Character vector of method names. |
metrics |
Which metrics to keep. Defaults to
|
tolerance |
Matching window passed to the metrics. Defaults to
|
change_in |
Passed to every detector. |
parallel |
Use |
progress |
Show a progressr progress bar when that package is
installed and a handler is enabled? Defaults to |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments passed to every |
x |
A |
object |
A |
plot_type |
|
metric |
Which metric to plot. Defaults to the first one scored. |
alpha |
Level for the critical distance, in |
Value
A ggcpt_benchmark object: a tibble with one row per
(dataset, method): dataset, method, n,
n_annotators (how many ground-truth sets the dataset supplied),
n_cp, the requested metrics, runtime and error,
with
print(), tidy() and autoplot()
("heatmap", "ranks", "critical_difference").
Reading the critical-difference diagram
Rank 1 is best. Each method's mean rank is taken over the datasets, in
the direction the metric calls for: higher is better for
covering, f1, precision, recall and
rand_index; lower for hausdorff,
annotation_error, mae_matched and rmse_matched.
A metric that came back NA takes the worst rank on that
dataset rather than being dropped, so a method that failed there is
penalised for it instead of quietly scoring on a smaller sample; ties
share the average rank.
The bar is the Nemenyi critical distance
CD = q_\alpha \sqrt{k(k + 1) / (6N)}
for k methods over N datasets, where q_\alpha is
the Studentised range statistic at \alpha divided by
\sqrt 2 (Demsar, 2006; the constants agree with that paper's
Table 5 to three decimals for k = 2, \ldots, 10). Two methods
whose mean ranks differ by less than CD are not distinguished at
that level.
One caveat the diagram cannot show. Nemenyi is a
post-hoc procedure, and the convention is to run it only after a
Friedman test has rejected the null that all methods rank equally.
autoplot() does not run that omnibus test (it draws the
diagram it is asked for), so a gap wider than CD on a grid where
Friedman would not have rejected is not the significant difference it
looks like. With the handful of datasets cpt_datasets()
supplies, N is small and CD correspondingly wide; read the
diagram as a descriptive summary unless N is large enough to
support the test.
References
van den Burg GJJ, Williams CKI (2020). “An evaluation of change point detection algorithms.” arXiv preprint arXiv:2003.06222. doi:10.48550/arXiv.2003.06222.
DemÅ¡ar J (2006). “Statistical comparisons of classifiers over multiple data sets.” Journal of Machine Learning Research, 7, 1–30.
See Also
cpt_datasets(), cpt_load_tcpd(),
cpt_metrics().
Examples
bm <- cpt_benchmark(cpt_datasets(n = 200, seed = 1),
methods = c("pelt", "binseg", "amoc"),
progress = FALSE)
bm
ggplot2::autoplot(bm)
What the package promises, against what it delivers
Description
The calibration suite: every guarantee the documentation states that a
simulation can check, with the realised value and its Monte Carlo
standard error. Location intervals and sets are scored for coverage
(conditional on a changepoint landing within 20 positions of the truth),
tests for their size at 5% on data with no change, monitors for their
in-control run length, and the panel screen for its false discovery
rate. The row for cpt_test() at a location the
data chose is there to show what selection_adjusted = FALSE
means: its nominal 5% is not what it delivers.
Usage
cpt_calibration
Format
A tibble with one row per guarantee and setting:
- guarantee
what is promised, and by which function.
- call
the call that was measured.
- setting
the data and the options it was measured on.
- kind
"coverage","size"(forcpt_attribute(), the family-wise error over the coordinates that did not change),"run_length"or"false_discovery_rate".- nominal
the promised value: a confidence level, a test's level or an average run length (for the e-detector, a lower bound).
- realised
the measured value.
- mcse
its Monte Carlo standard error.
- reps
replicates that counted (for coverage, those that detected the change).
Source
data-raw/calibration.R.
See Also
The calibration article on the package website, https://pursuitofdatascience.github.io/ggchangepoint/articles/calibration.html.
Other measurement tables:
cpt_data_types,
cpt_invariances,
cpt_noise_benchmark,
cpt_null_sizes,
cpt_runtimes
Examples
cpt_calibration[, c("call", "nominal", "realised", "mcse")]
Cite the method behind a result
Description
Returns the bibliographic reference(s) for the method behind a
ggcpt result (or a method name), so an analysis can cite the right
methodological paper without leaving R.
Usage
cpt_cite(x)
Arguments
x |
A |
Value
A tibble with columns method and reference,
invisibly; the references are also printed.
Examples
cpt_cite("pelt")
res <- cpt_detect(c(rnorm(50), rnorm(50, 5)), method = "pelt")
cpt_cite(res)
Confidence intervals for changepoint locations
Description
Answers "where could this changepoint be?" for any result, and says which
of five routes it used. show_ci = TRUE in autoplot() works
only for the handful of engines that ship intervals of their own; this
generic covers the rest, and (because the four routes mean genuinely
different things) reports the provenance in a source column
rather than presenting them as interchangeable.
Usage
cpt_confint(
object,
level = 0.95,
method = c("auto", "native", "nsp", "bootstrap", "posterior", "conformal"),
B = 200,
seed = NULL,
...
)
Arguments
object |
A |
level |
Confidence/credible level. Defaults to |
method |
Which route to use:
|
B |
Bootstrap replicates for |
seed |
Optional seed (bootstrap and NSP are both random). The seed
is scoped to this call: |
... |
Passed to |
Value
A tibble with one row per changepoint: cp,
ci_lower, ci_upper, level, source, plus
cp_index/ci_lower_index/ci_upper_index on the
original scale when the result carries a time index, and
n_replicates for method = "bootstrap" (how many
replicates actually contributed a draw for that changepoint), and
set_size for method = "conformal" (how many locations
the confidence set holds; an empty set has NA bounds and
warns, because no single change between exchangeable segments fits
that window).
method = "nsp" returns NA bounds for a changepoint that
falls in no region, which is a finding rather than a failure.
How well these cover
Measured over 120 replicates on a 200-point series with one changepoint
at 100 and a jump of three standard deviations, at a nominal level of
0.95: "bootstrap" on pelt covered 0.992 of the time with
a mean width of 2.2; strucchange's native intervals covered 1.000
at width 4.4; stepR's (smuce) covered 0.992 at width 4.6;
and "posterior" on bcp covered 1.000 at width 157. Every
route is conservative (none under-covers), and the width is
what separates them. The two native routes and the bootstrap are the
ones to quote; see the note on "posterior" above for why its
interval is so much wider.
The conformal route was measured with cpt_confint_coverage()
on the same design (300 replicates per cell, pelt, level 0.95).
For a jump of three standard deviations it covered 0.960 at a mean width
of 0.5 (the bootstrap: 0.973 at 2.0); for a jump of one standard
deviation 0.970 at 18.6, where the bootstrap fell short of the level at
0.926 (width 25.8); under t_3 noise with a jump of two, 0.963 at
3.5 (bootstrap 0.943 at 4.4). Its guarantee assumes exchangeable
observations within each segment, and under AR(1) noise with
\rho = 0.3 it covered 0.920 (bootstrap 0.887): dependent noise
shortens every interval here, and cpt_assumptions()
checks for it.
References
Hore R, Ramdas A (2026). “Conformal changepoint localization.” arXiv preprint arXiv:2602.06267.
See Also
cpt_confint_coverage(), which measures how often
each route covers; cpt_test(),
cpt_stability(), nsp_wrapper().
Examples
set.seed(2026)
x <- c(rnorm(80), rnorm(80, 4))
fit <- cpt_detect(x, method = "pelt")
cpt_confint(fit, method = "conformal", B = 50, seed = 1)
cpt_confint(fit, method = "bootstrap", B = 25, seed = 1)
How often do the confidence intervals cover? A Monte Carlo check
Description
Simulates series with one changepoint of known location, detects with
method, computes cpt_confint() by each route in
routes, and reports how often the interval contains the true
location and how wide it was. This is the measurement behind the
coverage statements in ?cpt_confint, and the way to check them
for your own series length, jump size and noise before relying on an
interval.
Usage
cpt_confint_coverage(
method = "pelt",
routes = c("conformal", "bootstrap"),
n = 200,
jump = 2,
noise = c("gauss", "t", "ar1"),
n_sim = 100,
level = 0.95,
B = 100,
seed = NULL,
...
)
## S3 method for class 'ggcpt_coverage'
print(x, ...)
## S3 method for class 'ggcpt_coverage'
tidy(x, ...)
## S3 method for class 'ggcpt_coverage'
autoplot(object, ...)
Arguments
method |
Detection method passed to |
routes |
Which |
n |
Series length. Defaults to |
jump |
Size of the mean shift, in noise standard deviations.
Defaults to |
noise |
Noise model, as in |
n_sim |
Number of simulated series. Defaults to |
level |
Nominal level. Defaults to |
B |
Replicates (bootstrap) or permutations (conformal) per
interval. Defaults to |
seed |
Optional seed, scoped to this call. |
... |
Passed to |
x |
A |
object |
A |
Details
The changepoint sits at floor(n / 2). Coverage is
computed over the replicates in which the detector reported at least
one changepoint, taking the one nearest the truth, so it is coverage
given a detection; n_detected says how many replicates
that is. A route that fails on a replicate (an engine that supplies no
native interval, say) is counted in n_failed rather than as a
miss.
Value
A ggcpt_coverage tibble with one row per route:
method, route, n_sim, n_detected,
n_failed, coverage, coverage_se (its Monte Carlo
standard error), mean_width, level. print(),
autoplot() (coverage with a two-standard-error bar against the
nominal level) and tidy() work on it.
See Also
cpt_confint(), cpt_calibration.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
cov <- cpt_confint_coverage(n_sim = 6, n = 80, B = 20, seed = 1)
cov
ggplot2::autoplot(cov)
Consensus changepoints across several detectors
Description
Runs a set of detectors on one series and reports the locations they agree
on. Two detections count as the same changepoint when they fall within
tolerance of each other, the same tolerance window
cpt_metrics() matches on (van den Burg and Williams, 2020),
so the package has one notion of "close enough" and not two. The
grouping necessarily differs: cpt_metrics() matches two
sets one-to-one, while consensus has to cluster K of them, so
detections are swept in order and a new cluster opens as soon as one lies
more than tolerance from the cluster's first member. That cap stops
a chain of near-neighbours merging into one arbitrarily wide cluster.
Usage
cpt_consensus(
x,
methods = c("pelt", "binseg", "amoc"),
tolerance = 5,
min_votes = "majority",
change_in = "mean",
index = NULL,
seed = NULL,
...
)
## S3 method for class 'ggcpt_consensus'
autoplot(object, plot_type = c("series", "agreement"), ...)
## S3 method for class 'ggcpt_consensus'
print(x, ...)
Arguments
x |
A |
methods |
Character vector of method names. A method that fails on
this series (its engine errors or is not installed, or it does not
offer |
tolerance |
Matching window, in positions. Defaults to |
min_votes |
Minimum number of methods that must find a location for
it to enter the consensus. Defaults to A value strictly between 0 and 1 is read as a proportion of
the methods that ran; anything else is a count, rounded up
( A count larger than the number of methods that ran cannot be reached, so the consensus would be empty by construction; that warns rather than returning a result indistinguishable from “the methods agreed on nothing”. |
change_in |
Passed to each detector. |
index |
Optional time index, carried onto the result. |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
... |
Passed on to |
object |
A |
plot_type |
|
Value
A ggcpt object (so it plots and tidies like any other
result) whose changepoints tibble carries votes and
methods (a comma-separated list of the methods that found each
location), with the per-method detections kept in a
consensus attribute and drawn by autoplot(plot_type =
"agreement").
Consensus does not remove shared false positives
Voting removes the idiosyncrasies of individual algorithms. It does not
remove a false positive that every algorithm makes for the same reason,
and a violated assumption is exactly such a reason: measured under
AR(1) noise, every one of pelt's spurious changepoints was
reproduced by wbs within five observations, and the 2-of-3
consensus of pelt, binseg and wbs had more false
positives (1.40) than two of its own members. The useful signal in a
panel is its disagreement: the disagreement value in
the consensus attribute is the share of the locations any member
found that not every member found, and a high value says the members'
shared assumption may be what is wrong (see
cpt_assumptions() and cpt_robustness()).
Consensus is not inference
Agreement among detectors is not a p-value, and a location found
by six of seven methods is not thereby significant at any level: the
methods are run on the same data and are strongly correlated, several of
them share an engine, and none of the votes is independent. Read the vote
count as a robustness display ("this feature does not depend on which
detector I picked"), and use nsp_wrapper() or
cpt_confint() when you need a guarantee.
References
van den Burg GJJ, Williams CKI (2020). “An evaluation of change point detection algorithms.” arXiv preprint arXiv:2003.06222. doi:10.48550/arXiv.2003.06222.
See Also
ggcpt_compare(), cpt_recommend(),
cpt_metrics().
Examples
set.seed(2026)
x <- c(rnorm(80), rnorm(80, 4))
cons <- cpt_consensus(x, methods = c("pelt", "binseg", "amoc"))
tidy(cons)
ggplot2::autoplot(cons)
What would have happened without the change? Observed against counterfactual
Description
For each changepoint, carries the segment before it forward over the segment after it, using that segment's own model, and sets the prediction beside what was observed. The gap is the effect of the change, observation by observation, in the units of the data: the interrupted-time-series exhibit.
Usage
cpt_counterfactual(
fit,
model = NULL,
data = NULL,
engine = stats::lm,
level = 0.95,
...
)
## S3 method for class 'ggcpt_counterfactual'
print(x, ...)
## S3 method for class 'ggcpt_counterfactual'
tidy(x, ...)
## S3 method for class 'ggcpt_counterfactual'
glance(x, ...)
## S3 method for class 'ggcpt_counterfactual'
autoplot(object, ...)
Arguments
fit |
A |
model, data, engine, ... |
Passed to |
level |
Level of the prediction interval around the counterfactual.
Defaults to |
x |
A |
object |
A |
Value
A ggcpt_counterfactual tibble with one row per
observation after each changepoint, up to the next: cp (the
change it belongs to), position, index (the time index,
or the position when there is none), observed,
counterfactual, lower and upper (the prediction
interval, NA when the model supplies none) and effect
(observed - counterfactual). autoplot() draws the series
with each counterfactual and its band; glance() gives one row
per change with the mean and cumulative effect; print() and
tidy() work as usual.
Reading it
The counterfactual is a prediction from the pre-change segment alone, so
its interval widens the further it is carried: a level is carried at
constant width, a line fans out. The interval describes the
pre-change model's uncertainty, not the location's: the changepoint is
taken as given, and cpt_confint() is the place to ask how
sure that location is. Where the detector chose the location from the
same data, the effect is the naive one, and cpt_effect()
measures it on held-out observations instead.
See Also
cpt_effect(), cpt_segment_models(),
predict.ggcpt().
Other segment models:
cpt_segment_models(),
predict.ggcpt()
Examples
set.seed(2026)
x <- c(rnorm(80, 10), rnorm(60, 13))
fit <- cpt_detect(x, method = "pelt", change_in = "meanvar")
cf <- cpt_counterfactual(fit)
glance(cf)
ggplot2::autoplot(cf)
CROPS: the full penalty path of a penalised changepoint method
Description
Runs PELT once per distinct optimal segmentation as the penalty
ranges over [pen_min, pen_max], using the CROPS algorithm of
Haynes, Eckley and Fearnhead (2017) as implemented by the
changepoint package. Instead of committing to one penalty, the
analyst sees every segmentation the data admits along the path, together
with its cost, and picks the elbow.
Usage
cpt_crops(
x,
change_in = c("mean", "var", "meanvar"),
pen_min = NULL,
pen_max = NULL,
...
)
## S3 method for class 'ggcpt_path'
autoplot(
object,
type = c("elbow", "path", "segmentations"),
max_facets = 12,
...
)
## S3 method for class 'ggcpt_path'
print(x, ...)
## S3 method for class 'ggcpt_path'
tidy(x, ...)
Arguments
x |
For |
change_in |
What to detect change in: |
pen_min, pen_max |
The penalty interval to sweep. Default to
|
... |
Additional arguments passed to the underlying
|
object |
A |
type |
Plot type for |
max_facets |
Maximum number of solutions shown by
|
Value
A ggcpt_path object: a list with a solutions tibble
(one row per distinct segmentation: penalty, n_cpts,
cost, and a cpts list-column), the data, and
metadata. penalty is the lower end of the penalty
interval on which that segmentation is optimal: CROPS returns the
breakpoints of the penalty axis, so K segmentations come with
K + 1 boundaries and each row is optimal from its own
penalty up to the next row's. Methods: print(), tidy(), and
autoplot() (elbow plot by default;
type = "path" for penalty vs. number of changepoints;
type = "segmentations" for the faceted segmentations).
References
Haynes K, Eckley IA, Fearnhead P (2017). “Computationally efficient changepoint detection for a range of penalties.” Journal of Computational and Graphical Statistics, 26(1), 134–143.
Killick R, Eckley I (2014). “changepoint: An R package for changepoint analysis.” Journal of statistical software, 58(3), 1–19.
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 3), rnorm(100, -1))
path <- cpt_crops(x)
path
ggplot2::autoplot(path)
ggplot2::autoplot(path, type = "segmentations")
False positives and power by data type
Description
Ten replicates of a 400-point series with one change at 200, at
comparable effect sizes across four data types: Gaussian (a shift of 1.4
standard deviations), Bernoulli (probability 0.15 to 0.75), Poisson (rate
2 to 10) and a proportion (binomial of 20, 0.25 to 0.6). Each engine is
at its default, as a user who does not set family gets it.
Usage
cpt_data_types
Format
A tibble with one row per engine and data type:
- method
the engine.
- data_type
"gaussian","bernoulli","poisson"or"proportion".- reps
replicates that ran.
- hit_rate
share of replicates finding the change within 20 positions.
- fp
mean number of other reported changepoints.
Source
data-raw/measure_engines.R (part datatype).
See Also
Other measurement tables:
cpt_calibration,
cpt_invariances,
cpt_noise_benchmark,
cpt_null_sizes,
cpt_runtimes
Examples
b <- subset(cpt_data_types, data_type == "bernoulli")
b[order(-b$fp), ][1:5, ]
A catalogue of benchmark datasets
Description
Builds a ready-made collection of labelled series for
cpt_benchmark(). By default these are the canonical
simulated signals this package already ships, which means the benchmark
runs offline, deterministically, and inside R CMD check. Pass
source = "tcpd" for the Turing Change Point Dataset instead, which
is downloaded and cached.
Usage
cpt_datasets(
source = c("simulated", "tcpd"),
n = 500,
seed = 1,
names = NULL,
...
)
Arguments
source |
|
n |
Length of each simulated series. Defaults to |
seed |
Seed for the simulated signals. Defaults to |
names |
Optional subset of dataset names. |
... |
Passed to |
Value
A named list of list(series, annotations) datasets, ready
for cpt_benchmark().
See Also
cpt_load_tcpd(), cpt_benchmark().
Examples
names(cpt_datasets(n = 200))
Detection delay and false-alarm rate
Description
Scores an online result the way the sequential literature does: how long
after each true change did the first alarm arrive, and how many alarms
were raised with no change behind them. cpt_metrics() is the
wrong tool for an online detector: it asks whether the location
was recovered, which a sequential procedure never claims. It will not
stop you: cpt_metrics() takes bare integer vectors and never
sees which detector produced them, so it cannot know. (An earlier
version of this sentence said it warns. It does not, and given that
signature it could not.)
Usage
cpt_delay(object, truth, max_delay = Inf)
## S3 method for class 'ggcpt_delay'
tidy(x, ...)
## S3 method for class 'ggcpt_delay'
glance(x, ...)
## S3 method for class 'ggcpt_delay'
print(x, ...)
## S3 method for class 'ggcpt_delay'
autoplot(object, ...)
Arguments
object |
A |
truth |
Integer vector of true changepoint positions, on the same
clock as the alarms. When |
max_delay |
Alarms further than this after a change are treated as
false alarms rather than late detections. Defaults to |
x |
A |
... |
Ignored. |
Value
A ggcpt_delay object: a list with per_change (one
row per true change: truth, alarm, delay,
detected), false_alarms, and the summary statistics
mean_delay, median_delay, n_false_alarms and
arl: monitored observations per false alarm. The baseline a
cpt_replay() monitor trained on is not counted, because
no alarm can fire there; n_obs is the length of the stream in
series positions, baseline included.
See Also
cpt_monitor(), cpt_replay().
Examples
set.seed(2026)
mon <- cpt_replay(c(rnorm(200), rnorm(200, 3)), method = "edetector")
cpt_delay(mon, truth = 200)
Unified changepoint detection dispatcher
Description
Runs a changepoint detection method on a sequence and returns a tidy
ggcpt result object. This is the recommended entry point for most
users. See cpt_methods() for the full method table with
engines and capabilities.
Usage
cpt_detect(
x,
method = "pelt",
change_in = "mean",
penalty = "MBIC",
index = NULL,
y = NULL,
...,
data = NULL,
family = NULL,
group = NULL,
na_action = c("error", "omit", "engine"),
fixed = NULL,
within = NULL,
min_segment = NULL,
min_effect = NULL,
keep_fit = TRUE
)
Arguments
x |
The series. A numeric vector for univariate methods, or a
numeric matrix/data frame (rows are time points) for the multivariate
methods (run Also a formula with Several series at once: a dplyr-grouped data frame, a keyed
Refused rather than coerced: a factor (its level codes are not data),
a survival object, and dates or timestamps as values (they convert to
an increasing count; pass them as |
method |
Detection method: any |
change_in |
What to detect change in. One of A compatible request may still be routed to the method's own
native change type, because several engines have no separate estimator
for the thing being asked about. That is never silent: the result's
|
penalty |
Penalty type or value. Either a character string
( |
index |
Optional time index, one value per observation (dates, say).
Detection still runs on observation positions (every wrapped engine
assumes an equally spaced sequence), but the index is stored on the
result and threaded through |
y |
Column selection for the data-frame interface:
|
... |
Additional arguments passed to the specific wrapper (see the
wrapper's help page for engine-specific options). Where an argument is
also derived from |
data |
A data frame for the formula interface. |
family |
The distribution a segment is modelled with:
|
group |
For a long data frame holding several series, the column(s)
identifying each one: a bare name, a string, or |
na_action |
What to do with missing values: |
fixed |
Changepoints known in advance, which are kept and the rest
estimated around them: the detector runs separately on each stretch
between them. Positions, or values of the series' index (a date is
placed at the last observation on or before it; for a numeric index
such as a |
within |
Windows the changepoints must fall in ("the policy took
effect sometime in Q2"): a pair |
min_segment |
Minimum segment length in observations, translated
into each engine's own argument ( |
min_effect |
Drop changepoints whose mean shift is smaller than this
many noise standard deviations (estimated from the series' first
differences, which a changepoint barely moves), removing the smallest
first and re-measuring its neighbours after each removal. For a change
in mean only. The size is measured on the same data that located the
change, so it is biased upward; see |
keep_fit |
Keep the engine's own object in |
Value
A ggcpt object: a list with changepoints
(cp, cp_value), segments (seg_id,
start, end, n, param_estimate),
data (index, value), the method,
change_in, penalty, cp_convention and
runtime that produced it, the matched call, and
fit, the raw upstream object. Optional slots
(data_wide, regions, diagnostics, ...) appear
only when an engine supplies them; new_ggcpt()
documents all of them, and tidy.ggcpt(),
glance.ggcpt() and augment.ggcpt()
are the supported way to read one.
Scale sensitivity of the penalised change-in-mean engines
"pelt", "binseg", "segneigh" and "fpop"
compare a penalty against a raw segment cost when
change_in = "mean": changepoint's Normal cost assumes a
noise standard deviation of 1, and fpop's lambda is an
absolute penalty on the residual sum of squares. Neither rescales the
data, so on a series whose noise is much wider than 1 the penalty is
effectively negligible and the segmentation shatters. On 200 observations
with one true changepoint in the middle and a jump of five standard
deviations, "pelt" returns 1 changepoint at \sigma = 1, 27
at \sigma = 3 and 76 at \sigma = 10. These are means over 20
draws, because a single draw is not stable here: the same settings gave
15/38 at n = 100 and 47/152 at n = 400, so the effect grows
with the series as well as with the noise. (0.5.0, before the two-point
minimum segment, reported 39 and 141 at n = 200: the floor halves
the damage and does not remove it.) A measured scale-sensitive engine
given noise far from unit scale warns (class
ggchangepoint_scale_sensitive). Three ways to avoid it, in order
of convenience:
standardise the series first (
cpt_detect(scale(x)[, 1], method = "pelt"));pass a penalty on the data's own scale, for example
penalty = 2 * log(length(x)) * stats::var(diff(x)) / 2;use
change_in = "meanvar", which estimates a variance per segment and is unaffected.
Most other engines are unaffected: SMUCE, WBS, WBS2, NOT, MOSUM,
Isolate-Detect, TGUH, CPOP, "bcp", "beast" and the
nonparametric and multivariate methods estimate or cancel the noise scale
internally, and returned the same segmentation at a thousandth, one and
a thousand times the units. Five did not, on the same series:
"geomcp" runs PELT on its mapped distance and angle series and so
inherits the sensitivity above; "decafs" floors its noise
estimate at about 0.03, so it under-segments a series whose noise is
smaller than that; "bocpd"'s default prior is on the data's
own scale; and "envcpt" and "var" changed their answer
with the units too (var's gamma_set and lambda_set
penalise a squared-error loss on an absolute scale). At a
thousandth of the units "decafs", "bocpd" and
"var" found nothing. Standardising first avoids all five, and
cpt_invariances holds the measurement.
See Also
cpt_methods() for what is available and what each
method can do. To get the result out: tidy.ggcpt(),
glance.ggcpt(), augment.ggcpt(),
summary.ggcpt() and print.ggcpt(). To
draw it: autoplot.ggcpt(). For the penalty:
cpt_penalty().
Examples
set.seed(2022)
x <- c(rnorm(100, 0, 1), rnorm(100, 10, 1))
result <- cpt_detect(x, method = "pelt", change_in = "mean")
result
ggplot2::autoplot(result)
# A date index: detection is unchanged, but the report speaks in dates.
dates <- as.Date("2000-01-01") + 0:199
dated <- cpt_detect(x, method = "pelt", index = dates)
tidy(dated)
# The data-frame interface.
df <- data.frame(day = dates, value = x)
cpt_detect(df, y = value, index = day, method = "pelt")
# Counts, with a cost written for them.
counts <- c(rpois(100, 2), rpois(100, 6))
cpt_detect(counts, method = "pelt", family = "poisson")
# Missing values, located in the original positions.
gappy <- x
gappy[c(20, 21, 150)] <- NA
cpt_detect(gappy, method = "pelt", na_action = "omit")$changepoints
# A changepoint known in advance, and a window for another.
cpt_detect(x, method = "pelt", fixed = 50)$changepoints
# Breakpoints in a regression.
if (requireNamespace("strucchange", quietly = TRUE)) {
d <- data.frame(t = 1:200, z = rnorm(200))
d$y <- ifelse(d$t <= 120, 1 + d$z, 3 - d$z) + rnorm(200, 0, 0.5)
fit <- cpt_detect(y ~ z, data = d, method = "strucchange")
tidy(fit, "coefficients")
}
Effect size at each changepoint
Description
The size of every change a fit reports, in the data's own units and standardised: the level before and after, their difference with an interval, the difference in noise standard deviations, the percentage change, and for count and waiting-time data the rate or hazard ratio.
Usage
cpt_effect(fit, level = 0.95, method = c("naive", "split"), seed = NULL, ...)
## S3 method for class 'ggcpt_effect'
print(x, ...)
## S3 method for class 'ggcpt_effect'
tidy(x, ...)
## S3 method for class 'ggcpt_effect'
autoplot(object, ...)
Arguments
fit |
A |
level |
Confidence level for the intervals. Defaults to |
method |
|
seed |
Optional seed for |
... |
Further arguments for the re-run |
x |
A |
object |
A |
Value
A ggcpt_effect tibble with one row per changepoint (per
changepoint and coordinate for a multivariate fit, per changepoint and
term for a regression fit): cp (and cp_index),
before, after, n_before, n_after,
delta, delta_lower, delta_upper (a Welch
interval), delta_std (the change in noise standard deviations,
the unit cpt_detect(min_effect = ) filters on),
pct_change, sd_before, sd_after,
sd_ratio, the family-specific ratio where it applies
(rate_ratio for Poisson counts, odds_ratio for binary
data, hazard_ratio for exponential waiting times, each with an
interval), selection_adjusted and method. With
print() and autoplot().
The winner's curse
A change measured at a location the same data chose is biased upward:
the detector put the boundary where the two sides differ most, so the
difference it reports is the largest the noise allowed. The bias is
worst for the marginal detections, which are exactly the ones whose size
matters. method = "naive" rows carry selection_adjusted =
FALSE for that reason, except at a changepoint fixed in advance with
cpt_detect(fixed = ), which the data did not locate and which is
TRUE. method = "split" is honest about the size
(the measuring half never influenced the locations) and less precise
about the location (the locating half has half the data), and it assumes
the noise is independent from one observation to the next, since the
two halves are interleaved.
See Also
cpt_test_at() for a change at a date fixed in
advance, cpt_detect()'s min_effect.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(100, 10), rnorm(100, 12)), method = "pelt")
cpt_effect(fit)
counts <- c(rpois(100, 4), rpois(100, 8))
cpt_effect(cpt_detect(counts, method = "pelt", family = "poisson"))
Write a result to a file, and read it back
Description
cpt_export() writes a result where software in any language can
read it; cpt_import() rebuilds a working ggcpt from the
file. A saved .rds already reads in any R session without this
package (a ggcpt is a plain list of plain data), so these are for
leaving R, or for a format a person can open.
Usage
cpt_export(fit, file, format = NULL, ...)
cpt_import(file, format = NULL, method = "imported", change_in = "mean")
Arguments
fit |
A |
file |
Path to write ( |
format |
|
... |
For |
method, change_in |
For a CSV, which carries no metadata, the method
and change type to record on the rebuilt result. Defaults to
|
Value
cpt_export() returns file, invisibly.
cpt_import() returns a ggcpt object; the engine's own
$fit is not stored in either format, so it is NULL.
See Also
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 3)), method = "pelt")
path <- tempfile(fileext = ".json")
cpt_export(fit, path)
back <- cpt_import(path)
back$changepoints
unlink(path)
Distribution families, and what each request runs
Description
The family argument of cpt_detect() names the
distribution a segment is modelled with, so count data, waiting times
and binary series can be segmented with a cost written for them rather
than a Gaussian one. cpt_families() is the table behind it: every
legal combination of method, change_in and family,
and the engine call each becomes.
Usage
cpt_families(method = NULL)
Arguments
method |
Optional method name(s) to restrict the table to. |
Value
A tibble with one row per legal combination: method,
change_in, family (NA for a distribution-free
method, which takes no family), engine_call (what is run) and
data (what the family requires of the series: "counts",
"binary", "positive" or NA).
The families
"gaussian"The default of every parametric method. On
"cpm"it also switches from the nonparametric statistics to the Gaussian ones (Student, Bartlett)."poisson"Counts:
change_in = "mean"is a change in the rate. Needs non-negative whole numbers."binomial"Binary outcomes: a change in the success probability. Needs 0/1 data.
"exponential"Waiting times: a change in the rate (the hazard), so
change_in = "mean". Needs positive data."gamma"Positive data with a known shape (pass
shape, default 1): a change in the scale."laplace"Heavy tails: a change in the median and the scale (
change_in = "meanvar")."l1"The absolute-loss cost: a change in the median, robust to outliers (
change_in = "mean").
A single-parameter family has one thing to change, so Poisson,
binomial, exponential and gamma requests use change_in = "mean".
Why an argument and not a model grammar
A grammar that marks the changing parameter
(poisson(rate = NA), normal(mean = NA, sd = 1)) would unify
change_in, family and the formula interface in one
expression, and measured against the fifty methods it fits 42 of them
cleanly. It is deferred to 1.0, where change_in can be replaced
rather than joined by a second idiom, and this table is the first half of
it: change_in = "mean", family = "poisson" already means
poisson(rate = NA) internally.
See Also
cpt_detect(), cpt_methods() (its
families column), cpt_simulate() to generate
data from each family.
Examples
cpt_families("pelt")
# every method that can fit a Poisson rate
unique(subset(cpt_families(), family == "poisson")$method)
set.seed(1)
counts <- c(rpois(100, 3), rpois(100, 9))
cpt_detect(counts, method = "pelt", family = "poisson")
Goodness of fit, segment by segment
Description
The checks behind a segmentation, as numbers: for every segment, its length, level and spread, whether its residuals look independent (Ljung-Box) and Gaussian (Shapiro-Wilk), and a flag where the segment is too short for either test to mean anything.
Usage
cpt_gof(fit, lag = NULL)
## S3 method for class 'ggcpt_gof'
print(x, ...)
## S3 method for class 'ggcpt_gof'
tidy(x, ...)
Arguments
fit |
A |
lag |
Ljung-Box lag. Defaults to |
x |
A |
... |
Ignored. |
Value
A ggcpt_gof tibble with one row per segment (per segment
and coordinate for a multivariate fit): seg_id, start,
end, n, mean, sd, acf1 (lag-1
autocorrelation of the residuals), ljung_box_p,
shapiro_p, and too_short (fewer than 12 observations,
where the tests are left NA). The whole-series Ljung-Box result
is attached as the "overall" attribute, and print()
summarises what the columns say.
See Also
autoplot(fit, type = "diagnostics") draws the same
checks; cpt_assumptions() reports them with the
alternatives.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(100), rnorm(100, 3, 2)), method = "pelt")
cpt_gof(fit)
A publication-ready changepoint table
Description
Renders the changepoints of a result as a gt table, with the time index, location intervals and segment levels formatted for a paper. Falls back to a plain tibble, with a note, when gt is not installed.
Usage
cpt_gt(object, title = NULL, subtitle = NULL, digits = 3)
Arguments
object |
A |
title, subtitle |
Table title and subtitle. Sensible defaults are derived from the result. |
digits |
Digits for the numeric columns. Defaults to |
Value
A gt table, or a tibble when gt is unavailable.
See Also
cpt_report().
Examples
set.seed(2026)
cpt_gt(cpt_detect(c(rnorm(60), rnorm(60, 4)), method = "pelt"))
Influence diagnostics for a changepoint segmentation
Description
Perturbs one observation at a time (deleting it, or replacing it with an outlier), re-runs the detector, and reports what changed: the number of changepoints, where they moved to, and how the segment parameters responded. This is the diagnostic family of Wilms, Killick and Matteson (2022), rendered in ggplot2 so it composes with the rest of the package.
Usage
cpt_influence(
object,
type = c("delete", "outlier"),
engine = c("auto", "changepoint.influence", "recompute"),
subset = NULL,
outlier_sd = 5,
seed = NULL,
...
)
## S3 method for class 'ggcpt_influence'
print(x, ...)
## S3 method for class 'ggcpt_influence'
autoplot(
object,
plot_type = c("overview", "location", "parameter", "map"),
...
)
## S3 method for class 'ggcpt_influence'
tidy(x, ...)
Arguments
object |
A |
type |
|
engine |
Which implementation to use:
|
subset |
Optional integer vector of observation positions to perturb. Influence by deletion costs one detector fit per observation, so on a long series or an expensive engine this is the argument that makes the diagnostic affordable. Defaults to every observation. |
outlier_sd |
For |
seed |
Optional seed, for detectors that randomise. The seed is
scoped to this call: |
... |
Additional arguments passed to |
x |
A |
plot_type |
Which diagnostic to draw:
|
Value
A ggcpt_influence object: a list with
influencea tibble with one row per perturbed observation:
index,n_cp,delta_n_cp(against the unperturbed fit),max_shift(largest movement of a surviving changepoint, in positions),param_shift(largest absolute change in a segment parameter) andcpts(a list-column of the perturbed changepoint sets). A perturbation whose re-fit failed hasn_cp = NA, and is warned about;paraman
n \times nmatrix of per-observation segment parameters, one row per perturbation: the input to the influence map;original,type,engine,method
with print() and autoplot() methods.
References
Wilms I, Killick R, Matteson DS (2022). “Graphical influence diagnostics for changepoint models.” Journal of Computational and Graphical Statistics, 31(3), 753–765. doi:10.1080/10618600.2021.2000873.
See Also
cpt_leverage(), cpt_sensitivity(),
cpt_stability().
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(40), rnorm(40, 4)), method = "pelt")
inf <- cpt_influence(fit)
inf
head(cpt_leverage(inf))
Install the engines behind a family of methods
Description
The package wraps a lot of upstream engines, all of them in
Suggests so that installing ggchangepoint does not drag in
dozens of packages nobody asked for. The cost of that choice is a
discovery problem: cpt_detect(x, method = "smuce") tells you to
install stepR, but only one package at a time. This installs a whole
family in one call.
Usage
cpt_install_engines(bundle = "core", dry_run = FALSE, ...)
Arguments
bundle |
Which family to install:
Several bundles may be given at once. |
dry_run |
Report what would be installed without installing
anything. Defaults to |
... |
Passed to |
Details
Every package comes from the repositories in getOption("repos")
except the two engines CRAN has archived. fpop, archived in
September 2026 at its maintainer's request, is installed from R-Forge
(https://R-Forge.R-project.org), where it is developed. ocp,
archived in October 2026, is installed from the package website
(https://pursuitofdatascience.github.io/ggchangepoint/repo/), a
CRAN-like repository that serves the last CRAN release of every engine
CRAN no longer does.
Value
Invisibly, a tibble with one row per package (package,
bundle, installed_before, installed_after).
See Also
cpt_methods() for the per-method installation
status.
Examples
cpt_install_engines("bayesian", dry_run = TRUE)
Invariances of every engine's answer
Description
Five replicates of a 200-point series with changes at 70 and 140 (a
3-coordinate version for the multivariate engines), detected as given and
transformed. A correct mean-change detector returns the same
changepoints on 10 * x, 0.1 * x and x + 100, and
n - cp on the reversed series.
Usage
cpt_invariances
Format
A tibble with one row per engine:
- method
the method.
- reps
replicates that ran.
- k
median changepoints on the series as given.
- scale_invariant
the same answer at
x,10 * xand0.1 * xin at least four of five replicates.FALSEfor the Gaussian-cost engines that assume unit noise, which is whycpt_detect()warns when one is handed noise far from unit scale.- shift_invariant
the same answer on
x + 100.- reversal_rate
share of replicates whose reversed series gives the mirrored answer.
- sequential
the reversal test fails in most replicates: the answer depends on the direction of time.
- concat_k
median changepoints on
c(x, x)(four expected, one for a single-change design).- dup_k
median changepoints when every observation is repeated twice, which makes the noise strongly autocorrelated: a measure of how badly the engine fails when its independence assumption does.
Source
data-raw/measure_engines.R (part invariance).
See Also
Other measurement tables:
cpt_calibration,
cpt_data_types,
cpt_noise_benchmark,
cpt_null_sizes,
cpt_runtimes
Examples
subset(cpt_invariances, !scale_invariant)$method
How sure is the number of changepoints? Weights over K
Description
Turns the criterion curve of cpt_select() into weights over
the candidate numbers of changepoints, and averages the candidate
segmentations under those weights into a probability, at each location,
that it is a changepoint.
Usage
cpt_k_weights(sel)
## S3 method for class 'ggcpt_k_weights'
print(x, ...)
## S3 method for class 'ggcpt_k_weights'
tidy(x, what = c("k", "locations"), ...)
## S3 method for class 'ggcpt_k_weights'
glance(x, ...)
## S3 method for class 'ggcpt_k_weights'
autoplot(object, what = c("k", "locations"), ...)
Arguments
sel |
A |
x |
A |
... |
Ignored. |
what |
|
object |
A |
Value
A ggcpt_k_weights tibble with one row per candidate:
k, value (the criterion), delta, weight
and chosen. tidy(x, what = "locations") returns the
model-averaged probability of a changepoint at each location any
candidate uses (position, index, probability);
autoplot(x) draws the weights and autoplot(x, what =
"locations") the probabilities. print() and glance()
(the chosen K, its weight, and the smallest set of K holding 95% of
the weight) work on it.
The weights
With \Delta_K the criterion of K changepoints minus the
smallest, the weight of K is \exp(-\Delta_K / 2) normalised
over the candidates. For "aic" these are Akaike weights; for
"bic" and "mbic" they approximate posterior probabilities
of each K under equal prior weight. They are conditional on the
candidate segmentations: each K is represented by the one
segmentation the ladder found for it, so the location probabilities
reflect uncertainty about how many changes there are, not about where a
given one falls (cpt_confint() answers that).
See Also
cpt_select().
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(2026)
x <- c(rnorm(80), rnorm(80, 1.2), rnorm(80, 0.4))
sel <- cpt_select(x, criterion = "bic", k_max = 6)
w <- cpt_k_weights(sel)
w
tidy(w, what = "locations")
ggplot2::autoplot(w)
Score a segmentation against labels
Description
Counts label errors: a positive region with no changepoint is a false
negative, a negative region with one is a false positive, and a
"one_change" region with two or more is a false positive as well.
This is the accuracy measure supervised changepoint detection is built on,
and, unlike an information criterion, it is defined by what the expert
asserted rather than by a model assumption.
Usage
cpt_label_error(object, labels)
## S3 method for class 'cpt_label_error'
tidy(x, ...)
## S3 method for class 'cpt_label_error'
print(x, ...)
Arguments
object |
A |
labels |
A |
x |
A |
... |
Ignored. |
Value
A tibble with one row per label: label_id,
series (the label set's series identifier, NA for a
single unnamed series), start, end, change,
n_changes (how many detections fell inside), status ("correct", "false_positive" or
"false_negative"), carrying the totals in an errors
attribute and printing them. An empty label set gives a zero-row
tibble with the same columns.
See Also
cpt_labels(),
cpt_label_error_curve(), geom_cpt_label().
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 4)), method = "pelt")
labs <- cpt_labels(c(40, 70), c(60, 95), c("one_change", "no_change"))
cpt_label_error(fit, labs)
Label error as a function of the penalty
Description
Runs one detector across a penalty grid and counts label errors at each setting: the curve penalty learning is fitted to, and the honest way to see whether any penalty can satisfy the labels.
Usage
cpt_label_error_curve(
x,
labels,
method = "pelt",
penalties = NULL,
change_in = "mean",
...
)
## S3 method for class 'ggcpt_label_curve'
print(x, ...)
## S3 method for class 'ggcpt_label_curve'
tidy(x, ...)
## S3 method for class 'ggcpt_label_curve'
autoplot(object, ...)
Arguments
x |
A |
labels |
A |
method |
Detection method. Defaults to |
penalties |
Numeric vector of penalties to try. When |
change_in |
Passed to the detector. |
... |
Additional arguments passed to |
object |
A |
Value
A ggcpt_label_curve object: a tibble with penalty,
n_cp, errors, false_positive,
false_negative, plus print(), tidy() and
autoplot().
The target attribute holds the interval of log(penalty)
achieving the minimum error, which is what
cpt_learn_penalty() regresses on.
See Also
cpt_learn_penalty(), cpt_select().
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 4))
labs <- as_cpt_labels(60, n = 120)
curve <- cpt_label_error_curve(x, labs, penalties = c(2, 8, 32, 128))
curve
Changepoint labels
Description
Builds the tidy label set that the supervised functions consume: one row per labelled region, each asserting how many changepoints that stretch of the series contains.
Usage
cpt_labels(start, end, change = "change", series = NA_character_)
## S3 method for class 'cpt_labels'
tidy(x, ...)
Arguments
start, end |
Integer vectors of region boundaries (positions, inclusive). |
change |
What the region asserts, recycled to length:
|
series |
Optional series identifier, for label sets spanning a panel. |
x |
A |
... |
Ignored. |
Value
A cpt_labels tibble with columns label_id,
series, start, end, change.
References
Hocking TD, Rigaill G, Vert J, Bach F (2013). “Learning sparse penalties for change-point detection using max margin interval regression.” In Proceedings of the 30th International Conference on Machine Learning, volume 28, 172–180.
See Also
cpt_label_error(), geom_cpt_label(),
cpt_learn_penalty(),
as_cpt_labels() to convert a plain changepoint set.
Examples
cpt_labels(c(40, 70), c(60, 90), c("change", "no_change"))
Learn a penalty from labelled series
Description
Fits the supervised penalty model of Hocking et al. (2013): each series
contributes a target interval of log-penalties (those achieving the
fewest label errors), a feature vector is computed from the series, and a
linear model is fitted by minimising the squared hinge loss on those
intervals, which is max-margin interval regression. The result has a
predict() method, and cpt_detect() accepts it
directly as penalty, so a learned penalty is used exactly like a
number.
Usage
cpt_learn_penalty(
series,
labels,
method = "pelt",
penalties = NULL,
engine = c("auto", "penaltyLearning", "native"),
...
)
## S3 method for class 'ggcpt_penalty_model'
print(x, ...)
## S3 method for class 'ggcpt_penalty_model'
coef(object, ...)
## S3 method for class 'ggcpt_penalty_model'
tidy(x, ...)
## S3 method for class 'ggcpt_penalty_model'
predict(object, newdata, ...)
Arguments
series |
A named list of numeric vectors (or a matrix/data frame with one column per series). |
labels |
Either a single |
method |
Detection method used to build the label-error curves.
Defaults to |
penalties |
Penalty grid for the curves; passed to
|
engine |
|
... |
Additional arguments passed to |
x |
A |
object |
A |
newdata |
A numeric vector (one series), or a list/matrix of series. |
Value
A ggcpt_penalty_model object with print(),
coef(), tidy() (the coefficients as term and
estimate) and predict() methods.
The two scales differ and it matters: coef() gives an
intercept plus one weight per feature on the log-penalty
scale, which is where the interval regression is fitted, while
predict() exponentiates and returns a penalty on the natural
scale, the scale cpt_penalty() and
cpt_detect() consume. So a coefficient of
-0.04 on log_n is a multiplicative effect on the
penalty, not an additive one.
Reading the coefficients
The signs are often not interpretable, and that is a property of
the labels rather than of the fit. A target interval is open above
whenever the largest penalty on the grid still achieves the minimum
label error, which is the common case, because a large penalty
usually keeps the one changepoint the labels ask for. When every
series' interval is open above, any sufficiently large prediction is
optimal, the problem does not pin the slopes, and the L_2 term
settles them near zero with whatever sign the optimiser reached.
Two measurements on four series of very different length and noise,
all with one-change labels, differing only in the data drawn. In one,
every non-intercept coefficient came out slightly negative, so the
predicted penalty decreased with n, the opposite of the
\log n growth a reader would expect from BIC, and not evidence
of anything. In the other, every feature weight went to zero and the
model became a constant: predict() returned the same
penalty for all four series. Both fits put every prediction inside its
target, which is the property the model is fitted for, and neither
outcome says anything about how a penalty should scale.
So do not read a ggcpt_penalty_model as having discovered a
relationship, and do not be surprised by a constant one.
If the coefficients need to mean something, the labels have to
constrain the penalty from both sides: widen penalties until
the largest one starts to over-segment, so the target intervals close
above. cpt_label_error_curve() shows whether they do.
References
Hocking TD, Rigaill G, Vert J, Bach F (2013). “Learning sparse penalties for change-point detection using max margin interval regression.” In Proceedings of the 30th International Conference on Machine Learning, volume 28, 172–180.
See Also
cpt_label_error_curve(),
cpt_penalty().
Examples
set.seed(2026)
series <- list(a = c(rnorm(60), rnorm(60, 4)),
b = c(rnorm(80), rnorm(80, 2)))
labels <- list(a = as_cpt_labels(60, n = 120),
b = as_cpt_labels(80, n = 160))
model <- cpt_learn_penalty(series, labels,
penalties = c(2, 8, 32, 128))
model
stats::predict(model, series$a)
Rank observations by influence
Description
Orders the observations of a cpt_influence() result by how
much perturbing them disturbs the segmentation, most influential first.
The composite leverage score is the sum of three standardised
components (the change in the number of changepoints, the largest
movement of a changepoint, and the largest change in a segment
parameter), so an observation that shifts a location without changing the count is
still ranked.
Usage
cpt_leverage(object, ...)
Arguments
object |
A |
... |
Passed to |
Value
A tibble ordered most influential first, with columns
index, delta_n_cp, max_shift,
param_shift and leverage.
Rows with leverage = NA come first, and they are the
most influential of all. max_shift and param_shift
are undefined for a perturbation that left the engine with no
changepoints at all (there is nothing to match against and no
parameters to compare), so the composite score cannot be formed for
an observation whose removal destroys the segmentation entirely. The
NA is kept rather than filled in with a fabricated number;
read the delta_n_cp column on those rows, which says how many
changepoints were lost.
An NA here is always that case. If the original fit
found no changepoints then max_shift is missing for every
observation, the standardisation returns zeros rather than
NAs, and every leverage is finite. A perturbation whose
re-fit failed is not one of these: it carries
delta_n_cp = NA as well and is sorted last, since nothing is
known about it.
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(40), rnorm(40, 4)), method = "pelt")
head(cpt_leverage(fit), 3)
Download and cache the Turing Change Point Dataset
Description
Fetches the benchmark of van den Burg and Williams (2020), real series
from many domains each annotated independently by several human
annotators, and caches it under tools::R_user_dir(). The
multi-annotator structure is the point: scoring against a single "true"
set silently discards the disagreement, and
cpt_metrics_annotated() is built to keep it.
Usage
cpt_load_tcpd(name = NULL, cache_dir = NULL, refresh = FALSE, quiet = FALSE)
Arguments
name |
Dataset name, a character vector of names, or |
cache_dir |
Where to cache. Defaults to
|
refresh |
Re-download even when a cached copy exists? Defaults to
|
quiet |
Suppress progress messages. Defaults to |
Value
With name = NULL, a tibble catalogue (name,
n_annotators, cached), read from the annotations file
alone, so listing it downloads no series.
Otherwise a named list of list(series, annotations, index,
longname) datasets, in the shape cpt_benchmark() takes.
Network access and licences
This function downloads from GitHub, so it needs a working connection and is skipped in every example and test here. The data belong to their original owners under their own licences; this package neither bundles nor redistributes them. A few TCPD series are not in the repository at all (their sources do not permit redistribution) and are reported as unavailable rather than silently omitted.
References
van den Burg GJJ, Williams CKI (2020). “An evaluation of change point detection algorithms.” arXiv preprint arXiv:2003.06222. doi:10.48550/arXiv.2003.06222.
Examples
# Not run by R CMD check: every call downloads from the Turing Change
# Point Dataset's GitHub repository, and an example must not require
# network access.
## Not run:
cpt_load_tcpd() # the catalogue
d <- cpt_load_tcpd("nile") # one dataset
cpt_benchmark(d, methods = c("pelt", "amoc"))
## End(Not run)
Introspect available changepoint detection methods
Description
Returns a tibble describing every method the package knows about (those
that are wired, those a user has registered with
cpt_register_method(), and those that are planned), along
with their capabilities and installation status. Useful for discovering
what can be run, what needs to be installed, and which methods expose the
extras the diagnostics need (confidence intervals, a fitted signal, a
posterior, a detector statistic, a solution path, a bandwidth to sweep).
Usage
cpt_methods(capabilities = TRUE)
Arguments
capabilities |
Include the capability flag columns? Defaults to
|
Value
A tibble with columns:
- method
Method name as passed to
cpt_detect().- change_in
What types of change the method can detect.
- engine
The upstream R package that implements the method.
- status
"available"(wired in this release),"registered"(supplied by the user this session; seecpt_register_method()), or"planned"(future).- installed
TRUEif the engine package is installed,FALSEif it is aSuggestsengine that is missing,NAfor planned and registered methods.- target_release
What a planned method is waiting on: a release, or
"when on CRAN"when the engine package itself is not available from CRAN.NAfor methods that are already wired. Askingcpt_detect()for a planned method reports this rather than claiming the name does not exist.- multivariate, univariate, online, ci, fitted, posterior, statistic, path, scale_space
Capability flags (omitted when
capabilities = FALSE).cimeans the engine supplies changepoint-location confidence intervals;fitteda length-nfitted signal;posteriora per-location posterior probability;statisticandpaththe internals rendered byggcpt_statistic()andggcpt_solution_path(), which error with the list of supporting engines when a result does not carry them.scale_spaceis not one of those, despite sitting beside them. Nothing stores a scale space on a result:cpt_scale_space()computes one on demand by sweeping a multiscale detector's bandwidth over the series, so it works on any series and any result, apeltfit included. What this column marks is the two engines that sweep can be run with, i.e. the domain of that function's ownmethodargument:subset(cpt_methods(), scale_space)$method.onlinemeans the algorithm is sequential (it consumes observations one at a time), and this table reports it because it governs how the method behaves in batch: an online detector's threshold is a rate per observation, so run over a whole series throughcpt_detect()it reports roughlyn / \mathrm{arl0}changepoints by construction. It does not mean the method can be passed tocpt_monitor(), which takes its own five:"edetector","cpm","ocd","cusum"and"ewma". The two sets overlap without coinciding:bocpdis an online algorithm this table marks but the monitor does not offer, andedetector,cusumandewmaare native to this package rather than wrapped engines, so they have no row here at all.- families, choices, formula, min_segment, na_handling, cp_convention_upstream
The modelling vocabulary (omitted when
capabilities = FALSE): the distribution familiescpt_detect(family = )accepts (seecpt_families();NAfor a distribution-free method); the engine's modelling-choice arguments and their legal values, whichcpt_detect()validates; whether it takes a formula with covariates; the engine argumentmin_segmentis translated into; what the engine does with a missing value, measured rather than read from its documentation ("native","compacts","silent_loss"or"reject"; seecpt_detect(na_action = )); and the engine's own changepoint convention, which the wrapper translates to"left"("right": it reports the first observation after the change;"continuous": a location it estimates on a continuous scale;"design": rows of a lagged design).- scale_invariant, sequential, max_cp, tier, noise_model_arg, rate_arg, cost, max_n
Measured and recorded properties (omitted when
capabilities = FALSE): whether the answer is the same atx,10 * xand0.1 * x; whether it depends on the direction of time; how many changepoints the method can return where that is fixed;"general"for the general-purpose workhorses; the argument that selects the noise model and the one that sets the false-alarm rate; the runtime class atn = 10{,}000("fast"under a second,"moderate"under ten,"slow"); and the longest series it finished within the measurement's time cap (0when it did not finish 1,000 observations). The measurements behind them are thecpt_runtimesandcpt_invariancesdata sets.
See Also
cpt_install_engines() to install a whole family of
the engines this table reports on; cpt_detect() to run
one; cpt_register_method() to add your own.
Examples
cpt_methods()
# which methods can draw a confidence interval?
subset(cpt_methods(), ci)$method
Changepoint accuracy metrics
Description
Computes standard accuracy metrics comparing predicted changepoints to ground truth, including precision/recall/F1 with margin, covering metric, Hausdorff distance, adjusted Rand index, annotation error, and MAE/RMSE of matched locations.
Usage
cpt_metrics(pred, truth, n = NULL, margin = 5)
Arguments
pred |
Predicted changepoint indices (integer vector), or a
|
truth |
Ground truth changepoint indices (integer vector). |
n |
Length of the series. Taken from |
margin |
Tolerance margin for matching (default 5). |
Details
Precision/recall use a one-to-one matching: each truth may be
claimed by at most one prediction (predictions are scanned in order and
take the earliest unmatched truth within margin, which yields a
maximum matching for interval-structured problems). The covering metric
follows van den Burg and Williams (2020): the prediction-side partition is
always well defined, so an empty pred scores the covering of the
trivial single-segment partition rather than 0.
Value
A tibble with one row and the columns below. “Higher” and
“lower” mark which direction is better, the same directions
cpt_benchmark() ranks by.
n,n_pred,n_truththe series length and the two changepoint counts, after out-of-range indices are dropped.
precision,recall,f1higher is better. The fraction of predictions that matched a truth, the fraction of truths that were matched, and their harmonic mean, all under the one-to-one matching within
margin, so they score whether a change was found, not how precisely it was located.coveringhigher is better, in
[0, 1]. The segmentation covering metric: each true segment's best Jaccard overlap with a predicted segment, averaged weighted by segment length. Unlike F1 it needs no margin and degrades smoothly with location error. It has a floor: an empty prediction scores about1/(K+1)forKtrue changepoints (0.5 for one change in the middle), so covering is not comparable across problems with differentKand should not be averaged over them.cpt_benchmark()ranks within each dataset instead for exactly that reason.covering_floor,covering_scaledthe covering an empty prediction scores on this truth (the sum of the squared true segment shares,
1/(K+1)when the segments are equal), and covering rescaled so that the floor is 0 and a perfect segmentation 1,(covering - floor)/(1 - floor): comparable across problems with differentK.NAwhenK = 0, where the floor is already 1.hausdorfflower is better, in observations. The largest distance from any changepoint on either side to the nearest one on the other: a worst-case location error, so one badly placed changepoint dominates it.
rand_indexhigher is better. The adjusted Rand index between the two segment labellings: 1 for identical partitions, 0 for chance agreement, and negative for worse than chance.
annotation_errorlower is better. A count difference only:
abs(n_pred - n_truth). It says nothing about location, so a segmentation with the right number of changepoints in entirely the wrong places scores a perfect 0. Read it besidecoveringorhausdorff, never alone.mae_matched,rmse_matchedlower is better, in observations. Mean absolute and root-mean-square location error over the matched pairs only, so they describe how well the changepoints that were found are placed and ignore the ones that were missed.
NAwhen nothing matched.
precision, recall and f1 are
thresholded at margin: a changepoint off by
margin counts as found and one off by margin + 1 as
missed, so they can move from 1 to 0 on a one-observation change.
covering, hausdorff, rand_index and the matched
errors are continuous in the location.
Degenerate cases, and which way each metric resolves them
Three of the twelve columns are ratios with a zero denominator when one side is empty, and the row does not resolve them all the same way, so the conventions are worth stating rather than inferring from a benchmark table:
-
Both empty. The segmentation is exactly right:
precision,recall,f1,coveringandrand_indexare all 1 andannotation_erroris 0. (A metric that scored this 0 was a 0.4.0 bug.) -
One side empty.
precisionandrecallare 0 rather thanNA(finding nothing where there was a change, and finding a change where there was none, both score badly), and so isf1.rand_indexis 0 for the same reason. -
Nothing matched.
hausdorff,mae_matchedandrmse_matchedareNA, because they are distances and there is no pair to measure. They are alsoNAwhenever either side is empty. This is the one place the row mixes conventions: an all-wrong answer givesf1 = 0andmae_matched = NAin the same row.cpt_benchmark()treats anNAas the worst rank rather than dropping it.
An index outside 1..(n - 1) is dropped with a warning: locations
follow the "left" convention, and an out-of-range one would
corrupt the partition metrics rather than merely miss.
See Also
cpt_metrics_annotated() for scoring against
multiple annotators, and cpt_benchmark() to run a
method-by-dataset grid on these metrics.
Examples
cpt_metrics(c(100, 200), c(100, 200), n = 300)
cpt_metrics(c(101, 205), c(100, 200), n = 300, margin = 5)
Multi-annotator evaluation
Description
Computes averaged covering and F1 scores against multiple annotation sets, as used in the Turing Change Point Dataset benchmark.
Usage
cpt_metrics_annotated(pred, annotations, n = NULL, margin = 5)
Arguments
pred |
Predicted changepoint indices, or a |
annotations |
A list of ground-truth annotation vectors. |
n |
Length of the series; taken from |
margin |
Tolerance margin (default 5). |
Value
A tibble with one row: n, n_annotators,
n_pred, and the four metrics this averages:
precision, recall, f1 and covering.
Each is a plain unweighted mean of the per-annotator value from
cpt_metrics(), over all n_annotators of them.
This is a narrower table than cpt_metrics()
returns, so a call moved from one to the other loses columns:
n_truth (there is no single truth), and the location metrics
hausdorff, mae_matched, rmse_matched,
rand_index and annotation_error.
The three distance metrics are omitted for a reason worth stating,
because it is not obvious: they are NA whenever an annotator
shares no matched pair with the prediction, so averaging them would
quietly divide by fewer annotators than n_annotators reports.
Measured on three annotators against one prediction
(list(c(100, 200), integer(0), 150) at n = 300),
mae_matched was available for one of the three and
hausdorff for two, while f1 and covering were
finite for all three. Score those per annotator with
cpt_metrics() and combine them yourself if you want
them, so the divisor is yours to choose.
covering and f1 are the pair the Turing Change Point
Dataset benchmark reports, which is why they are the ones averaged
here; precision and recall come along as F1's parts.
See Also
cpt_metrics() for the full single-truth table
and what each column means.
Examples
# two annotators who disagree slightly about where the change is
cpt_metrics_annotated(c(100, 200),
annotations = list(c(98, 200), c(100, 203)),
n = 300, margin = 5)
The smallest detectable change
Description
Inverts cpt_power(): searches for the change size at which
the detector reaches a target power. The study-design counterpart of a
power curve, and the number that belongs in a pre-registration.
Usage
cpt_min_detectable(
n,
sigma = 1,
method = "pelt",
power = 0.8,
range = c(0.1, 5),
n_sim = 100,
tolerance = 5,
change_in = "mean",
location = 0.5,
noise = "gauss",
rho = 0,
df = 3,
tol = 0.05,
max_iter = 12,
seed = NULL,
...
)
## S3 method for class 'ggcpt_min_detectable'
tidy(x, ...)
## S3 method for class 'ggcpt_min_detectable'
print(x, ...)
Arguments
n |
Series length. |
sigma |
Noise standard deviation. Defaults to |
method |
Detection method. Defaults to |
power |
Target detection probability. Defaults to |
range |
Search range for the change size, in standard deviations.
Defaults to |
n_sim |
Replicates per evaluation. Defaults to |
tolerance |
A detection counts as finding the change when it falls
within this many positions of it. Defaults to |
change_in |
What changes. Defaults to |
location |
Changepoint position, as a fraction of |
noise |
Noise model, passed to |
rho |
AR(1) parameter when |
df |
Degrees of freedom when |
tol |
Bisection tolerance on the change size. Defaults to
|
max_iter |
Maximum bisection steps. Defaults to |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Ignored. |
x |
A |
Value
A list with jump (the smallest change reaching
power), achieved_power, mc_se, and the
trace of evaluations, with print() and tidy()
(one row) methods.
See Also
cpt_power().
Examples
# n_sim = 10, max_iter = 3: the search is n_sim detector fits per
# iteration, and n_sim = 30 with max_iter = 4 measured 5.4 s against
# CRAN's 5 s example budget. Raise both for a usable answer.
cpt_min_detectable(n = 200, n_sim = 10, max_iter = 3, seed = 1)
A stateful sequential changepoint monitor
Description
Creates a detector that consumes observations as they arrive and raises
alarms, rather than segmenting a series that is already complete. Feed it
with cpt_update(), read its alarm log with
alarms(), and score it with cpt_delay(),
because for an online method "did you find the location?" is the wrong
question and "how long did you take, and how often do you false-alarm?"
is the right one.
Usage
cpt_monitor(
method = c("edetector", "cpm", "ocd", "cusum", "ewma"),
baseline = NULL,
alpha = 0.01,
arl0 = 500,
cpm_type = "Mann-Whitney",
patience = 5000,
deltas = c(0.5, 1, 2),
reset = TRUE,
relearn = 20,
thresh = "MC",
mc_reps = 100,
...,
k = 0.5,
lambda = 0.2,
limit = NULL
)
## S3 method for class 'ggcpt_monitor'
tidy(x, ...)
## S3 method for class 'ggcpt_monitor'
print(x, ...)
## S3 method for class 'ggcpt_monitor'
autoplot(
object,
plot_type = c("timeline", "statistic", "runlength", "control_chart"),
...
)
Arguments
method |
Which sequential detector:
|
baseline |
A numeric vector (or, for |
alpha |
Target false-alarm probability for |
arl0 |
Target in-control average run length for |
cpm_type |
Statistic for |
patience |
Target patience (average run length) for |
deltas |
Shift sizes, in baseline standard deviations, mixed over by
|
reset |
After an alarm, restart the detector ( |
relearn |
How many observations after an alarm are used to re-learn
the in-control baseline, during which no further alarm can fire.
Defaults to |
thresh |
Threshold rule for |
mc_reps |
Monte Carlo repetitions for the |
... |
Additional arguments passed to the engine's constructor
( |
k |
CUSUM reference value, in baseline standard deviations: half
the shift the chart is tuned to detect fastest. Defaults to |
lambda |
EWMA smoothing weight on the newest observation, in (0, 1].
Defaults to |
limit |
Optional control limit, overriding the calibration to
|
x |
A |
object |
A |
plot_type |
|
Value
A ggcpt_monitor object: a list carrying the detector's
state between calls, so it is meant to be passed to
cpt_update() and re-assigned rather than read field by
field. The parts worth reading are
alarmsthe tibble
alarms()andtidy()return: one row per alarm, withtime,statisticandthreshold. Empty (zero rows) until something fires.thow many observations the monitor has consumed through
cpt_update(), not counting the baseline; an alarm'stimeis on this same clock. A monitor built bycpt_replay()also carriesoffset, the number of leading observations it trained on, sotime + offsetis a position in the replayed series (cpt_delay()applies it for you).dataevery monitored observation so far, baseline excluded (the first coordinate, for a multivariate monitor), which is what
autoplot()draws.method,alpha,n_baseline,reset,relearnthe settings this call fixed, kept so a later
cpt_update()cannot silently disagree with them.statethe detector's internal statistics. Engine internals: their shape differs by
methodand is not part of the interface.
Control charts
"cusum" and "ewma" are the two charts statistical process
control runs, and they are sequential changepoint detectors under
another name. Each standardises the stream by the baseline's mean and
standard deviation (Phase I; the baseline should be in control) and
then monitors it (Phase II). The CUSUM keeps S_t^+ =
\max(0, S_{t-1}^+ + z_t - k) and S_t^- = \max(0, S_{t-1}^- - z_t -
k) and alarms when either reaches h; the EWMA keeps z_t =
\lambda x_t + (1 - \lambda) z_{t-1} and alarms when it leaves \pm L
\sqrt{\lambda / (2 - \lambda)}. The limit is solved for arl0 by
the Markov-chain approximation of the run length (Brook and Evans 1972;
Lucas and Saccucci 1990), which reproduces the published tables: a CUSUM
with k = 0.5 and h = 4 or 5 has in-control run lengths of
168 and 465, and an EWMA with lambda = 0.1 and L = 2.814
one of 500. Measured through this function with a 5,000-observation
baseline and arl0 = 100, the first alarm on in-control data came
after 99.4 observations on average for the CUSUM and 99.8 for the EWMA
(400 runs each, standard errors about 5). The calibration treats the
baseline's mean and standard deviation as exact, so a short baseline
shortens the in-control run length: a few hundred observations is a
reasonable minimum. Rational subgroups, run rules and capability indices are not
modelled; for a formal quality-control programme use a dedicated
package such as qcc. autoplot(plot_type = "control_chart")
draws the chart.
The e-detector, and why it is implemented rather than wrapped
Shin, Ramdas and Rinaldo (2023) give a nonparametric sequential framework
with non-asymptotic control of the average run length, and it has no R
implementation. The construction used here is the mixture Shiryaev-Roberts
e-detector for a sub-Gaussian shift. For each candidate shift
\delta the increment is the likelihood ratio
e_t^{(\delta)} = \exp(\delta (X_t - \mu_0)/\sigma^2 -
\delta^2/(2\sigma^2)), which has unit mean under the null; the running
statistic is R_t^{(\delta)} = (1 + R_{t-1}^{(\delta)})
e_t^{(\delta)}; the shifts are combined by averaging,
M_t = K^{-1} \sum_\delta R_t^{(\delta)}; and an alarm is raised
the first time M_t \ge 1/\alpha.
The averaging is not a detail. Under the null M_t - t is a
mean-zero martingale, so optional stopping at the alarm time \tau
gives E_\infty[\tau] = E_\infty[M_\tau] \ge 1/\alpha: a
finite-sample lower bound on the in-control average run length, with no
asymptotics and no calibration run. A convex combination of e-detectors
is an e-detector; a maximum of them is not, and taking one
silently multiplies the false-alarm rate by roughly the number of shifts
mixed over. Apart from it and the two textbook control charts below,
every detector in this package wraps published, separately maintained
code; the three native monitors are labelled as such wherever they
appear.
References
Shin J, Ramdas A, Rinaldo A (2023). “E-detectors: a nonparametric framework for sequential change detection.” The New England Journal of Statistics in Data Science, 1(2), 229–260. doi:10.51387/23-NEJSDS49.
Page ES (1954). “Continuous inspection schemes.” Biometrika, 41(1/2), 100–115. doi:10.1093/biomet/41.1-2.100.
Roberts SW (1959). “Control chart tests based on geometric moving averages.” Technometrics, 1(3), 239–250. doi:10.1080/00401706.1959.10489860.
Brook D, Evans DA (1972). “An approach to the probability distribution of CUSUM run length.” Biometrika, 59(3), 539–549. doi:10.1093/biomet/59.3.539.
Lucas JM, Saccucci MS (1990). “Exponentially weighted moving average control schemes: properties and enhancements.” Technometrics, 32(1), 1–12. doi:10.1080/00401706.1990.10484583.
See Also
cpt_update(), alarms(),
cpt_replay(), cpt_delay().
Examples
set.seed(2026)
mon <- cpt_monitor("edetector", baseline = rnorm(100))
mon <- cpt_update(mon, rnorm(50)) # still in control
mon <- cpt_update(mon, rnorm(50, 3)) # a change arrives
alarms(mon)
False positives and power under four noise regimes
Description
Ten replicates of a 300-point series with mean changes of two marginal
standard deviations at 100 and 200, under independent Gaussian noise,
heavy-tailed noise (t_3, scaled to unit variance), AR(1) noise with
\rho = 0.7 and heteroscedastic noise (standard deviations 0.5, 1
and 2.5 by segment), for every univariate engine at its default and at
each setting of its noise-model argument. A recommendation is a call,
not a name: smuce and smuce with family = "hsmuce"
are different detectors.
Usage
cpt_noise_benchmark
Format
A tibble with one row per engine, setting and regime:
- method, setting
the engine and the argument setting (
"default"or the argument as written).- call
the
cpt_detect()call the row measures.- regime
"iid","heavy","ar1"or"hetero".- reps
replicates that ran.
- hits
mean number of the two real changes found within ten positions.
- fp
mean number of reported changepoints more than ten positions from either.
Source
data-raw/measure_engines.R (part noise).
See Also
Other measurement tables:
cpt_calibration,
cpt_data_types,
cpt_invariances,
cpt_null_sizes,
cpt_runtimes
Examples
ar <- subset(cpt_noise_benchmark, regime == "ar1")
ar[order(ar$fp), c("call", "hits", "fp")]
What an empty answer could have detected
Description
When a detection comes back empty, the useful question is whether a
change of the size you care about would have been found. This runs
cpt_min_detectable() at the fit's own length, method and
penalty, with the noise level estimated from the series, and reports the
smallest shift detected with the requested power: changes smaller than
that could well be there and missed.
Usage
cpt_null_power(fit, power = 0.8, n_sim = 50, seed = NULL, ...)
## S3 method for class 'ggcpt_null_power'
print(x, ...)
## S3 method for class 'ggcpt_null_power'
tidy(x, ...)
Arguments
fit |
A |
power |
Target power. Defaults to |
n_sim |
Simulations per power evaluation. Defaults to |
seed |
Optional seed, scoped to this call. |
... |
Further arguments for |
x |
A |
Value
A ggcpt_null_power list with n, sigma (the
noise level used), jump (the smallest detectable change, in the
data's units), jump_sd (the same in noise standard deviations),
change_in (the fit's change type, which sets what jump
measures: a shift in the mean, a rise in the standard deviation, both,
or a trend, as cpt_power() defines them), power,
method and constant (TRUE when the series has no
variation, in which case nothing is simulated). With print() and
tidy() methods. A formula fit is refused: the simulation has no
covariates to draw.
See Also
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_robustness(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
fit <- cpt_detect(rnorm(100), method = "pelt")
cpt_null_power(fit, n_sim = 20, seed = 1)
False alarms on pure noise at scale
Description
Independent Gaussian noise with no changepoint anywhere, at 1,000 (50 replicates), 10,000 (10) and 100,000 (6) observations, for the engines the runtime table shows finishing that length quickly. Every changepoint reported is a false alarm.
Usage
cpt_null_sizes
Format
A tibble with one row per engine and length:
- method
the engine.
- n
the series length.
- reps
replicates that ran.
- size
share of replicates reporting at least one changepoint.
- mean_fp
mean number of changepoints reported.
Source
data-raw/measure_engines.R (part null).
See Also
Other measurement tables:
cpt_calibration,
cpt_data_types,
cpt_invariances,
cpt_noise_benchmark,
cpt_runtimes
Examples
subset(cpt_null_sizes, n == max(n))
Construct changepoint penalties
Description
Helper to construct standard penalty values for use with changepoint detection methods. Returns a numeric penalty value.
Usage
cpt_penalty(type, n = NULL, k = 1, value = NULL, alpha = 1.01, series = NULL)
Arguments
type |
Penalty type: |
n |
Series length (at least 3 for the |
k |
Number of parameters per changepoint (typically 2 for
mean+variance, 1 for mean-only). Defaults to 1. The |
value |
Numeric value for |
alpha |
Exponent of the strengthened SIC ( |
series |
The series a learned penalty is predicted for. Required
only when |
Value
A numeric penalty value.
Penalty semantics across engines
The same penalty name may be interpreted differently by different engines:
-
changepoint-based methods (PELT, BinSeg, SegNeigh, AMOC): accept character penalties (
"MBIC","BIC","AIC","Hannan-Quinn","None") and pass them to the upstream changepoint package. A numeric penalty is translated to that package'spenalty = "Manual"pluspen.value. The one exception is Segment Neighbourhood, for which changepoint does not implement MBIC:cpt_detect(method = "segneigh")andcpt_wrapper(cp_method = "SegNeigh")therefore fall back to"SIC"when the default penalty is left in place, so a segneigh result is not directly penalty-comparable with a PELT one. Passpenaltyexplicitly to pin it. For a change in mean these engines also read the penalty on the data's own scale rather than a standardised one; see the scale-sensitivity section ofcpt_detect. -
Functional-pruning methods (
fpop,cpop,decafs): accept numeric penalties only. When a character penalty is supplied viacpt_detect(), it is resolved to a numeric value usingcpt_penalty()before dispatch. -
Search-based methods (WBS, WBS2, NOT, MOSUM, IDetect, TGUH): use internal model-selection criteria (e.g., sSIC, threshold) and generally ignore the
penaltyargument. Specify thresholds via the wrapper's own arguments. -
fastcpdtakes its penalty asbeta, on its own scale, and defaults to its native"MBIC".cpt_detect()forwards a numericpenaltyasbeta, and translates the three names the two packages share ("MBIC","BIC"/"SIC","MDL"). Any other character penalty ("AIC","Hannan-Quinn","sSIC","None") has no fastcpd equivalent and is left to the engine's default rather than being silently approximated; passbetayourself to pin it. Whatever is used is recorded on the result, soprint()andglance()report the penalty of the fit in hand. -
Inference/Bayesian methods (
smuce,bcp,bocpd,beast,cpm,sn): are tuned by a significance level, posterior-probability threshold, hazard, or average run length rather than a penalty; see each wrapper. -
MBICincpt_penalty()is a BIC-type penalty that adds a combinatorial term for the number of wayskchangepoints can be placed innobservations,0.5(k+1)\log n + \log{n \choose k}. It is deliberately stronger than"BIC". It is not the modified BIC of Zhang and Siegmund (2007), whose penalty is1.5 k \log n + 0.5 \sum_i \log(l_i / n)on the log-likelihood scale (equivalently3 k \log n + \sum_i \log(l_i / n)on the deviance scale, which is howcpt_select()states it and the scale itscostcolumn uses). It depends on the segment lengthsl_iand so cannot be expressed by a function ofnandkalone. Use the character"MBIC"with changepoint-based methods to get the engine's native MBIC, andcpt_select(criterion = "mbic")for the Zhang-Siegmund one.
Examples
cpt_penalty("BIC", n = 100)
cpt_penalty("AIC", n = 100)
cpt_penalty("Manual", value = 5)
Detection power for a changepoint scenario
Description
Simulates replicate series under a scenario and reports how often the detector finds the change, how accurately it locates it, and how often it reports changes that are not there. This is the calculation that should precede an analysis, and the one applied papers are increasingly asked for.
Usage
cpt_power(
n,
jump,
sigma = 1,
method = "pelt",
location = 0.5,
n_sim = 200,
tolerance = 5,
change_in = "mean",
noise = "gauss",
rho = 0,
df = 3,
seed = NULL,
parallel = TRUE,
family = "gaussian",
baseline = NULL,
...
)
## S3 method for class 'ggcpt_power'
tidy(x, ...)
## S3 method for class 'ggcpt_power'
print(x, ...)
## S3 method for class 'ggcpt_power'
autoplot(object, ...)
Arguments
n |
Series length. |
jump |
Size of the change, in units of |
sigma |
Noise standard deviation. Defaults to |
method |
Detection method. Defaults to |
location |
Changepoint position, as a fraction of |
n_sim |
Replicates per scenario. Defaults to |
tolerance |
A detection counts as finding the change when it falls
within this many positions of it. Defaults to |
change_in |
What changes. Defaults to |
noise |
Noise model, passed to |
rho |
AR(1) parameter when |
df |
Degrees of freedom when |
seed |
Optional seed. The seed is scoped to this call:
|
parallel |
Use |
family |
|
baseline |
The family's parameter before the change, for a
non-Gaussian |
... |
Additional arguments passed to |
x |
A |
object |
A |
Value
A ggcpt_power object: a tibble with one row per scenario,
with columns n, jump, sigma, location,
power (proportion of replicates detecting the change within
tolerance), mc_se (the Monte Carlo standard error of that
proportion), mean_abs_error (location error among detections;
NaN when no replicate detected a changepoint within
tolerance of the true one, because there is no distance to
average, and power reads 0 in the same row),
false_positives (mean number of extra changepoints per
replicate) and n_sim; with print() and
autoplot().
Reproducibility under a parallel plan
A seeded call is reproducible for a given future::plan(),
and not across plans. Under a parallel plan the replicates' random numbers
come from future.apply's parallel-safe L'Ecuyer streams, derived
from seed; run sequentially they come from the calling stream that
seed set. Both are deterministic, and they are not the same
numbers. Measured on cpt_power(n = c(100, 200), jump = 0.5,
n_sim = 8, seed = 11): power = 0.25, 0.125 sequentially and
0, 0.375 on two workers. The scenario is named because the
numbers depend on it and on the worker count; what does not depend on
either is that the two disagree.
So the guarantee is: same seed and same plan, same answer, every time,
whichever plan it is. If a power figure needs to be reproducible by
someone else, pin the execution as well as the seed: pass
parallel = FALSE, or state the plan alongside the seed. Raising
n_sim narrows the gap, because it is Monte Carlo error rather
than disagreement: both estimates are of the same quantity, and
mc_se says how precisely.
This is specific to cpt_power(), which is the one function here
whose parallel tasks consume random numbers. The other six that dispatch
on future::plan() (cpt_benchmark(),
cpt_batch(), cpt_consensus(),
cpt_influence(), cpt_sensitivity() and
ggcpt_compare()) farm out work that is deterministic
given its input, and were measured to return identical results under a
sequential and a two-worker plan, stochastic engines included.
See Also
cpt_min_detectable(), cpt_scenarios(),
cpt_simulate().
Examples
pw <- cpt_power(n = 200, jump = c(0.5, 1, 2), n_sim = 30, seed = 1)
pw
ggplot2::autoplot(pw)
Recommend a detection method
Description
Turns the capability matrix and the package's measurements into an
answer. Given what the analyst knows about their problem (how many
dimensions, what kind of change, what the noise and the data look like,
how long the series is, how many changes they expect, whether they need
uncertainty or an online alarm), this returns the methods that fit, as
calls, with the power and false-alarm rate measured for each in that
situation, a reason and the caveats. It is a decision table, not a
model: everything it knows is in cpt_methods() and the
measurement tables (cpt_noise_benchmark,
cpt_data_types, cpt_runtimes), and making that
explicit and printable is the point.
Usage
cpt_recommend(
dimension = c("univariate", "multivariate"),
change_in = "mean",
noise = c("iid", "heavy", "autocorrelated", "heteroscedastic"),
n = NULL,
need_uncertainty = FALSE,
online = FALSE,
installed_only = FALSE,
n_expected = NULL,
data_type = c("continuous", "counts", "binary", "proportion"),
family = NULL,
fit = NULL,
jump = NULL
)
## S3 method for class 'ggcpt_recommendation'
tidy(x, ...)
## S3 method for class 'ggcpt_recommendation'
print(x, top = 5, ...)
## S3 method for class 'ggcpt_recommendation'
autoplot(object, top = 15, ...)
Arguments
dimension |
|
change_in |
What kind of change is expected: any value accepted by
|
noise |
Noise structure: |
n |
Series length. Methods the runtime table saw fail to finish at that length are left out (and listed), and the slow ones carry a caveat. Optional. |
need_uncertainty |
Does the answer have to come with a confidence
interval or significance region? Defaults to |
online |
Is detection sequential (alarms as data arrive) rather than
retrospective? Defaults to |
installed_only |
Restrict to engines that are installed. Defaults to
|
n_expected |
How many changes you expect, if you know. The
single-change designs ( |
data_type |
What the values are: |
family |
Optional distribution family the method must fit (see
|
fit |
Optional |
jump |
Optional expected change size, in noise standard deviations.
With |
x |
A |
... |
Ignored. |
top |
How many candidates to print. Defaults to |
object |
A |
Value
A ggcpt_recommendation tibble ordered by suitability, with
columns method, engine, installed, score,
tie (candidates with the same score share a number: the
recommender cannot tell them apart on what was supplied), call
(the cpt_detect() call to run, including the noise-model or
family argument the recommendation depends on), hits and
false_positives (measured in the stated regime: mean real
changes found out of two, and mean spurious ones), power (when
jump is given), why and caveat. print()
reads as advice and autoplot() shows the scores and the ties.
How the score is built
Where the method was measured in the stated noise regime, the score
starts from 3 - E, where E is the expected number of errors
per series in that benchmark (real changes missed plus false alarms),
taking the method's best setting of its noise-model argument (which is
then the one in call). A method not measured there starts at 1.
Then: minus 3 for a single-change design unless n_expected = 1;
minus the log of one plus its measured false positives on the stated
data type, and plus 1.5 if it fits that data type's family; plus 1 for a
location interval and 0.5 for a posterior when uncertainty is needed;
at n \ge 5000, plus 0.5 for a fast engine and minus 1 for a slow
one; and small tie-breakers for the general-purpose methods (0.25) and
for an installed engine (0.1). Sort by false_positives instead if
a false alarm costs you more than a miss.
See Also
cpt_methods(), cpt_consensus(),
cpt_cite().
Examples
cpt_recommend(noise = "autocorrelated")
cpt_recommend(data_type = "counts", n_expected = 2)
cpt_recommend(dimension = "multivariate", change_in = "covariance")
Tidy the significance regions of a ggcpt object
Description
The interval-valued methods (currently nsp_wrapper())
return regions rather than points: each is guaranteed to contain at least
one changepoint at a prescribed global significance level. A
region is a different object from a confidence interval around an
estimate, so it lives in its own slot and has its own accessor rather
than being folded into tidy().
Usage
cpt_regions(x)
Arguments
x |
A |
Value
A tibble with columns start, end (positions),
length, and, when the result carries a time index,
start_index/end_index on the original scale. Any further
columns the engine supplied are carried through after those:
nsp_wrapper() adds value, the region's statistic.
A zero-row tibble when the result carries no regions.
See Also
nsp_wrapper(), geom_cpt_region(),
cpt_confint().
Examples
set.seed(2026)
fit <- as_ggcpt(50, c(rnorm(50), rnorm(50, 4)),
regions = data.frame(start = 45, end = 56))
cpt_regions(fit)
Register an external changepoint detector
Description
Teaches cpt_detect() about a detector this package does not
(and often cannot) depend on: an engine that is not on CRAN, a Python
detector reached through reticulate, a deep-learning model, a
proprietary in-house method, or a hand-curated set of changepoints. The
registered method then works with everything built on the ggcpt
contract: autoplot(), the geoms, tidy()/glance()/
augment(), cpt_metrics(), ggcpt_compare(),
cpt_stability(), cpt_consensus(), cpt_benchmark()
and cpt_report().
Usage
cpt_register_method(
name,
fn,
change_in = "mean",
engine = "user",
citation = NULL,
capabilities = list(),
cp_convention = c("left", "right"),
overwrite = FALSE
)
cpt_unregister_method(name)
cpt_registered_methods()
Arguments
name |
Method name, as it will be passed to |
fn |
A function called as A returned |
change_in |
Character vector of |
engine |
Name of the package or system supplying the detector, for
display in |
citation |
Optional citation string returned by
|
capabilities |
Optional named list of capability flags overriding the
defaults (all |
cp_convention |
|
overwrite |
Replace an existing registration of the same name?
Defaults to |
Value
Invisibly, the method name.
cpt_registered_methods() returns a tibble with one row per
registered method (columns method, change_in,
engine, has_citation), or a zero-row tibble when none are
registered.
Registered methods are labelled, not endorsed
A registered method is visibly user-supplied: cpt_methods() gives it
status = "registered", print() on its results marks it, and
cpt_cite() reports the citation you supplied or states that none
was given. The package validates the shape of what your function
returns (through as_ggcpt(), which runs the same contract
checks as every built-in wrapper); it does not and cannot validate the
method.
See Also
as_ggcpt() to turn changepoints into a result
object without registering a method;
cpt_unregister_method();
cpt_registered_methods().
Examples
# A deliberately trivial detector: split at the largest jump.
cpt_register_method(
"biggest_jump",
fn = function(x, ...) which.max(abs(diff(x))),
change_in = "mean",
engine = "example",
citation = "No citation supplied (illustration only)."
)
set.seed(1)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 5)), method = "biggest_jump")
fit
cpt_unregister_method("biggest_jump")
Replay a series through a sequential detector
Description
Runs a whole series through a monitor in one call, so the alarm timeline
of an online method can be studied retrospectively without hand-rolling
the update loop. This is the honest version of what 0.4.0's cpm,
ocd and bocpd wrappers do implicitly: it reports
alarms, which arrive after the change, rather than pretending they
are estimated changepoint locations.
Usage
cpt_replay(
x,
method = c("edetector", "cpm", "ocd", "cusum", "ewma"),
baseline = NULL,
...
)
Arguments
x |
A numeric vector, or a matrix with rows as time points. |
method |
Sequential detector; see |
baseline |
Number of leading observations used as pre-change training
data (an integer), or an explicit baseline vector. Defaults to
|
... |
Additional arguments passed to |
Value
A ggcpt_monitor that has already consumed the series:
the same object cpt_monitor() returns, described
there, with alarms filled in for whatever fired.
See Also
cpt_delay(), cpt_monitor().
Examples
set.seed(2026)
mon <- cpt_replay(c(rnorm(200), rnorm(200, 3)), method = "edetector")
alarms(mon)
A reproducible report of a changepoint analysis
Description
Assembles everything a reader needs to judge a changepoint result into one artifact: the method and its citation, the penalty, the number and locations of the changepoints with intervals where available, the segment table, stability and diagnostics if they were computed, and the session information. Reproducibility and correct attribution in one call.
Usage
cpt_report(
object,
format = c("md", "text", "gt", "json"),
file = NULL,
stability = NULL,
events = NULL,
confint = TRUE,
session = TRUE
)
Arguments
object |
A |
format |
|
file |
Optional path to write to. The report is returned invisibly
when a file is written. Ignored for |
stability |
Optional |
events |
Optional |
confint |
Include a |
session |
Include |
Value
A character vector of report lines (or a gt table when
format = "gt").
See Also
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(60), rnorm(60, 4)), method = "pelt")
cat(cpt_report(fit, session = FALSE), sep = "\n")
Does a changepoint survive a change of noise model?
Description
Re-runs a detector under each setting of its noise-model argument
(family for stepR's SMUCE, variant for NSP, the cost
for the changepoint engines, ...) and reports which changepoints
appear under every setting and which only under some. A changepoint that
survives a change of noise model is evidence; one that survives a
bootstrap (cpt_stability()) or a change of algorithm
(cpt_consensus()) may only be a feature of the noise, which
resampling and other algorithms reproduce.
Usage
cpt_robustness(
x,
method = "pelt",
over = "noise_model",
settings = NULL,
margin = 5,
seed = NULL,
...
)
## S3 method for class 'ggcpt_robustness'
print(x, ...)
## S3 method for class 'ggcpt_robustness'
tidy(x, ...)
## S3 method for class 'ggcpt_robustness'
autoplot(object, ...)
Arguments
x |
A numeric series, or a |
method |
The detector, when |
over |
What to vary. Only |
settings |
Optional named list of settings, each a list of
arguments for |
margin |
Positions within which two changepoints count as the same.
Defaults to |
seed |
Optional seed, scoped to this call. |
... |
Further arguments for every |
object |
A |
Value
A ggcpt_robustness object: a list with settings
(one row per setting: setting, n_cp, powered and
error), changepoints (one row per changepoint of the
reference setting: cp, found_by (how many other powered
settings find it within margin), of (how many powered
alternatives there are) and survives), union and
intersection (distinct locations found by any and by every
powered setting) and fits. With print() and
autoplot().
Powerless settings are reported, not counted
A setting that finds nothing where the reference finds several is not a
vote against them: measured, NSP's variant = "ar" removes the
false positives of autocorrelated noise by removing detection altogether
(0 of 2 real changes found). Such a setting is marked
powered = FALSE and left out of found_by.
See Also
cpt_assumptions(), cpt_sensitivity()
for sweeping any argument.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_screen(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(1)
x <- c(rnorm(100), rnorm(100, 2)) + as.numeric(arima.sim(list(ar = 0.6), 200))
cpt_robustness(x, method = "pelt")
Engine runtimes by series length
Description
One timed cpt_detect() call per engine and length, each in its own
R process running an installed (byte-compiled) build, after a warm-up
call, so the time is the fit and not loading or compiling anything, with
a time cap of 120 seconds (300 at a million). A length is attempted only
when the previous one finished in under ten seconds.
One run per cell: this answers "will it finish?", and is not a basis for
claiming one engine is faster than another by a given factor.
Usage
cpt_runtimes
Format
A tibble with one row per engine and length attempted:
- method
the method, as
cpt_detect()takes it.- n
the series length: 1,000, 10,000, 100,000 or 1,000,000, with four mean changes of two noise standard deviations (three coordinates for the multivariate engines).
- seconds
elapsed time of the fit.
- k
changepoints reported (four are real; a single-change method reports one).
- status
"ok","timeout"or"error".
Source
data-raw/measure_engines.R (part runtime).
See Also
cpt_methods()'s cost and max_n
columns, cpt_recommend().
Other measurement tables:
cpt_calibration,
cpt_data_types,
cpt_invariances,
cpt_noise_benchmark,
cpt_null_sizes
Examples
subset(cpt_runtimes, n == 1e5 & status == "ok")
Scale space: the statistic across bandwidths
Description
Sweeps a multiscale detector's bandwidth and returns the statistic at every (location, bandwidth) pair. The resulting heatmap answers the question a single-bandwidth fit cannot: at which resolutions does this feature exist? A change that is significant only at a wide bandwidth is a slow shift; one that appears only at a narrow bandwidth is a spike.
Usage
cpt_scale_space(x, bandwidths = NULL, method = c("mosum", "npmojo"), ...)
ggcpt_scale_space(x, bandwidths = NULL, method = c("mosum", "npmojo"), ...)
Arguments
x |
A numeric vector (or, for |
bandwidths |
Integer vector of bandwidths to sweep. Defaults to a
geometric grid between |
method |
Which engine to sweep: |
... |
Additional arguments passed to the engine at each bandwidth. |
Value
cpt_scale_space() returns a tibble with index,
bandwidth, statistic, threshold,
significant (the statistic at that location and bandwidth
exceeds the threshold) and detected (the engine reported a
changepoint there at that bandwidth). The two differ: a location can
clear the threshold without surviving the engine's own pruning. ggcpt_scale_space() draws the heatmap with
the accepted changepoints overlaid.
See Also
Examples
set.seed(2026)
x <- c(rnorm(300), rnorm(300, 2))
ss <- cpt_scale_space(x, bandwidths = c(20, 40, 80))
head(ss)
A grid of simulation scenarios
Description
Builds the scenario grid a simulation study varies over, as data rather
than as nested loops, so it can be inspected, filtered, subsetted and
passed straight to cpt_benchmark().
Usage
cpt_scenarios(
n = 500,
jump = c(0.5, 1, 2),
location = 0.5,
noise = "gauss",
rho = 0.5,
change_in = "mean",
n_rep = 1,
seed = 1,
as_datasets = TRUE
)
Arguments
n |
Series lengths. |
jump |
Change sizes, in standard deviations. |
location |
Change positions, as fractions of |
noise |
Noise models; any value |
rho |
AR(1) parameters (used by |
change_in |
Change types. |
n_rep |
Replicates per scenario. Defaults to |
seed |
Base seed; replicate |
as_datasets |
Return simulated datasets in
|
Value
A named list of datasets, or a tibble of scenarios when
as_datasets = FALSE.
See Also
cpt_power(), cpt_benchmark().
Examples
scen <- cpt_scenarios(n = 200, jump = c(1, 3), as_datasets = FALSE)
scen
Which of many series changed? Screening with error control across the panel
Description
Tests every series in a panel for a change anywhere, with one of
cpt_test_null()'s tests, adjusts the p-values across the
panel, and returns the series ordered by evidence with the ones that
survive flagged. Optionally runs a detector on the flagged series, so
the segmentation is spent only where there is something to segment.
Usage
cpt_screen(
x,
test = c("pettitt", "cusum", "supF"),
alpha = 0.05,
control = c("fdr", "fdr_dependent", "fwer", "none"),
method = NULL,
...
)
## S3 method for class 'ggcpt_screen'
print(x, ...)
## S3 method for class 'ggcpt_screen'
tidy(x, ...)
## S3 method for class 'ggcpt_screen'
glance(x, ...)
## S3 method for class 'ggcpt_screen'
autoplot(object, ...)
Arguments
x |
A list of numeric vectors, or a matrix or data frame with one
column per series, as for |
test |
Which test gives each series its p-value:
|
alpha |
Error level across the panel. Defaults to |
control |
|
method |
Optional detection method. When given, every flagged
series is segmented with |
... |
Passed to |
object |
A |
Value
A ggcpt_screen tibble with one row per series, ordered by
p-value: series, rank, n, statistic,
p_value, p_adjusted, flagged and location
(where the test statistic peaks), plus n_changepoints and
result (a list-column of ggcpt fits, NULL for
series not flagged) when method is given. print(),
autoplot() (the sorted p-values against the rejection line),
tidy() and glance() work on it.
Why the panel needs its own correction
Each series' p-value is valid for that series. Across a panel of
m stable series, testing each at alpha flags about
m \alpha of them, and nothing in a per-series answer says so. The
adjustment is over the series, so its guarantee is about the panel:
under "fdr", of the series flagged, the expected share that did
not change is at most alpha. The tests assume independent
observations within a series, and autocorrelation makes every one of
them reject too often; cpt_assumptions() checks a single
fit for it.
See Also
cpt_batch(), which segments every series and
adjusts nothing; cpt_test_null().
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_test_at(),
cpt_test_null()
Examples
set.seed(2026)
panel <- c(lapply(1:15, function(i) rnorm(120)),
lapply(1:5, function(i) c(rnorm(60), rnorm(60, 1.5))))
names(panel) <- paste0("store", 1:20)
sc <- cpt_screen(panel)
sc
ggplot2::autoplot(sc)
Fit a model to every segment of a segmentation
Description
Detection says where the regimes change; this fits your model to
each regime. Every segment of fit gets its own copy of
model, fitted by engine to that segment's rows, and the
result is a table with one fitted model per segment that
tidy(), glance() and predict() read.
Usage
cpt_segment_models(fit, model = NULL, data = NULL, engine = stats::lm, ...)
## S3 method for class 'ggcpt_segment_models'
tidy(x, conf_level = 0.95, ...)
## S3 method for class 'ggcpt_segment_models'
glance(x, ...)
## S3 method for class 'ggcpt_segment_models'
print(x, ...)
Arguments
fit |
A |
model |
A formula. For a result from a formula fit it defaults to
that formula; for a series it defaults to |
data |
Optional data frame with one row per observation, supplying covariates the model uses. For a formula fit the covariates are taken from the result. |
engine |
The fitting function, called as |
... |
Further arguments for |
x |
A |
conf_level |
Confidence level for the coefficient intervals. |
Value
A ggcpt_segment_models tibble with one row per segment:
segment, start, end, n and model (a
list-column of fitted models, NULL where the fit failed).
tidy() gives the coefficient table with a segment
column; glance() one row per segment with n,
sigma, r_squared, AIC, BIC and
logLik.
See Also
predict.ggcpt() to forecast from a segment,
tidy.ggcpt(what = "coefficients") for the coefficients
the detection itself implies.
Other segment models:
cpt_counterfactual(),
predict.ggcpt()
Examples
set.seed(1)
d <- data.frame(x = runif(200))
d$y <- ifelse(seq_len(200) <= 100, 1 + 2 * d$x, 3 - d$x) + rnorm(200, 0, 0.3)
fit <- cpt_detect(y ~ x, data = d, method = "strucchange")
sm <- cpt_segment_models(fit)
tidy(sm)
glance(sm)
Choose the number of changepoints
Description
Builds a ladder of candidate segmentations with K = 0, 1, \ldots
changepoints and scores each one, returning the chosen K, the
criterion curve behind the choice, and the fitted result at that K.
Five criteria are available, including the consistent sample-splitting
cross-validation of Zou, Wang and Li (2020) and the segment-length mBIC of
Zhang and Siegmund (2007).
Usage
cpt_select(
x,
method = "pelt",
criterion = c("bic", "mbic", "aic", "crops_elbow", "cv", "stability"),
k_max = 20,
folds = 5,
B = 100,
change_in = "mean",
index = NULL,
seed = NULL,
...
)
## S3 method for class 'ggcpt_selection'
print(x, ...)
## S3 method for class 'ggcpt_selection'
tidy(x, ...)
## S3 method for class 'ggcpt_selection'
autoplot(
object,
plot_type = c("criterion", "segmentation", "ladder"),
max_facets = 12,
...
)
Arguments
x |
A numeric vector, or a |
method |
Detection method used to build the candidate ladder.
Defaults to |
criterion |
Which criterion selects
|
k_max |
Largest number of changepoints considered. Defaults to
|
folds |
Folds for |
B |
Bootstrap replicates for |
change_in |
Passed to the detector, and inherited from The three closed-form criteria assume a change in the mean
whatever this is set to. |
index |
Optional time index (a vector of dates, or a |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments passed to |
object |
A |
plot_type |
|
max_facets |
Maximum number of rungs drawn by
|
Value
A ggcpt_selection object: a list with
criterion_table (one row per candidate K: k,
value, cost, chosen, and a cpts
list-column), k (the chosen number), fit (the
ggcpt at that K), criterion and data.
Methods: print(), tidy() and autoplot() with
plot_type = "criterion", "segmentation" or
"ladder".
References
Zou C, Wang G, Li R (2020). “Consistent selection of the number of change-points via sample-splitting.” The Annals of Statistics, 48(1), 413–439. doi:10.1214/19-AOS1814.
Zhang NR, Siegmund DO (2007). “A modified Bayes information criterion with applications to the analysis of comparative genomic hybridization data.” Biometrics, 63(1), 22–32. doi:10.1111/j.1541-0420.2006.00662.x.
Haynes K, Eckley IA, Fearnhead P (2017). “Computationally efficient changepoint detection for a range of penalties.” Journal of Computational and Graphical Statistics, 26(1), 134–143.
See Also
cpt_crops(), cpt_penalty(),
cpt_sensitivity().
Examples
set.seed(2026)
x <- c(rnorm(80), rnorm(80, 4), rnorm(80, 1))
sel <- cpt_select(x, criterion = "bic", k_max = 6)
sel
ggplot2::autoplot(sel)
ggplot2::autoplot(sel, plot_type = "ladder")
Sensitivity of a segmentation to its tuning parameters
Description
The parameter analogue of cpt_influence(): instead of asking
which observation drives the answer, it asks which setting does.
Runs the detector over a grid of tuning values and reports the detected
locations for each, which is the direct answer to the commonest reviewer
question about a changepoint analysis: "is this robust to the penalty?".
Usage
cpt_sensitivity(x, method = "pelt", over = list(), seed = NULL, ...)
## S3 method for class 'ggcpt_sensitivity'
print(x, ...)
## S3 method for class 'ggcpt_sensitivity'
tidy(x, ...)
## S3 method for class 'ggcpt_sensitivity'
autoplot(object, ...)
Arguments
x |
A numeric vector (the series), or a |
method |
Detection method. Taken from |
over |
A named list of parameter vectors to sweep. Every combination
is run, so keep the grid small:
|
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments held fixed across the grid and passed to
|
object |
A |
Value
A ggcpt_sensitivity object: a list with a grid
tibble (one row per setting: the parameter columns, n_cp, and a
cpts list-column), the data, and the swept parameter
names. Methods: print(), tidy() (one row per detected
changepoint) and autoplot() (a location heatmap over the grid).
See Also
cpt_influence(), cpt_select().
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 3))
s <- cpt_sensitivity(x, method = "pelt",
over = list(penalty = c(2, 10, 40)))
s
ggplot2::autoplot(s)
Generate simulated changepoint data
Description
Creates a synthetic time series with known changepoints for testing and benchmarking.
Usage
cpt_simulate(
n,
changepoints = integer(),
change_in = c("mean", "var", "meanvar", "slope"),
params = NULL,
noise = c("gauss", "t", "ar1", "rw"),
sd = 1,
df = 3,
rho = 0,
seasonality = NULL,
sd_trend = NULL,
seed = NULL,
family = c("gaussian", "poisson", "binomial", "exponential"),
transition = 0
)
rcpt(...)
Arguments
n |
Length of the series. |
changepoints |
Integer vector of changepoint locations (last index of each segment before the change). |
change_in |
What changes: |
params |
A list of parameters per segment. For |
noise |
Noise type: |
sd |
Noise standard deviation, non-negative (for Gaussian and t;
t-noise is rescaled so its standard deviation is exactly |
df |
Degrees of freedom for t-noise; must exceed 2 so the variance exists. Defaults to 3. |
rho |
AR(1) autocorrelation parameter, strictly between -1 and 1 for
stationarity. Defaults to 0. Used only when |
seasonality |
Optional seasonal component added to the signal, as a
list with |
sd_trend |
Optional smoothly varying noise scale: a length-2 numeric
giving the multiplier on |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
family |
The distribution of the observations: |
transition |
Width, in observations, of a gradual change in level:
the mean moves linearly from one segment's value to the next across
|
... |
Passed to |
Value
A tibble with columns index, value, and seg_id.
The true changepoints are stored in the true_changepoints attribute.
See Also
Other test signals:
signal_blocks(),
signal_fms(),
signal_mix(),
signal_stairs(),
signal_teeth()
Examples
dat <- cpt_simulate(200, changepoints = c(100), change_in = "mean",
params = c(0, 10), seed = 2022)
attr(dat, "true_changepoints")
# a seasonal series with a level shift, and one with drifting noise
seasonal <- cpt_simulate(240, changepoints = 120, params = c(0, 3),
seasonality = list(period = 12, amplitude = 2),
seed = 1)
drifting <- cpt_simulate(240, changepoints = 120, params = c(0, 3),
sd_trend = c(0.5, 3), seed = 1)
# a change that takes 30 observations instead of one
gradual <- cpt_simulate(240, changepoints = 120, params = c(0, 3),
transition = 30, seed = 1)
# counts whose rate doubles
counts <- cpt_simulate(200, changepoints = 100, params = c(4, 8),
family = "poisson", seed = 1)
The solution path of a search-based detector
Description
The order in which candidate changepoints entered the model, with the contrast (or split criterion) at each step. Binary segmentation splits recursively, WBS/WBS2/NOT/TGUH rank random intervals; in every case the final answer is a prefix of a path, and seeing the path shows how decisively each changepoint beat the next.
Usage
cpt_solution_path(object)
ggcpt_solution_path(object, max_steps = 40)
Arguments
object |
A |
max_steps |
Longest prefix of the path drawn. Defaults to |
Value
cpt_solution_path() returns a tibble with step,
cp, contrast and, for interval-based searches,
start/end of the interval that proposed it, plus a
selected flag marking the changepoints in the final model.
ggcpt_solution_path() draws it.
contrast is the engine's own ordering criterion, and it is a
different quantity per engine: a penalty value for
binseg/segneigh (from
changepoint::pen.value.full()), |CUSUM| for wbs,
|max.contrast| for not, and
breakfast's candidate criterion for wbs2/tguh.
The values order the candidates within one result; they are not
comparable across engines, and the plot legend names the quantity
rather than calling all of them "Contrast".
For wbs2 and tguh the path is recomputed with
breakfast, because their fit objects do not keep the candidate
list. wbs2's search is randomised, so its path is a second
search of the same series rather than a record of the first: it can
differ between calls, and selected can be FALSE
throughout if the recomputed candidates miss the fit's own
changepoints. Every other engine's path is read off the fit.
See Also
cpt_statistic(), cpt_crops() for the
penalty path of an optimal-partitioning method.
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(150), rnorm(150, 3)), method = "binseg")
cpt_solution_path(fit)
Changepoint stability diagnostics via bootstrap
Description
Most engines report a point set of changepoints with no measure of how
fragile it is. cpt_stability() fits the detector once, then
resamples residuals within the fitted segments (so the estimated
regime structure is preserved), re-runs the detector on each replicate,
and reports how often each location is re-detected. The resulting
detection-frequency profile is a cheap, model-agnostic confidence signal
available for every wrapped engine, including the many that ship no
confidence intervals.
Usage
cpt_stability(
x,
method = "pelt",
B = 100,
margin = 5,
seed = NULL,
bootstrap = c("iid", "block"),
block_length = NULL,
reversal = TRUE,
...
)
## S3 method for class 'ggcpt_stability'
print(x, ...)
## S3 method for class 'ggcpt_stability'
tidy(x, ...)
## S3 method for class 'ggcpt_stability'
autoplot(object, ...)
Arguments
x |
A numeric vector, or a |
method |
Detection method, passed to |
B |
Number of bootstrap replicates. Defaults to |
margin |
Tolerance (in indices) when counting a replicate detection
as a re-detection of a location. Defaults to |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
bootstrap |
|
block_length |
Block length for |
reversal |
Also run the detector once on the reversed series, and
flag each changepoint that the reversed series does not find within
|
... |
Additional arguments passed to every |
object |
A |
Value
A ggcpt_stability object: a list with frequency
(a tibble of index and freq, the proportion of replicates
detecting a changepoint within margin of that index),
original (the point-estimate ggcpt), B,
n_failed (replicates on which the detector failed, which are
left out of the proportion rather than counted as "found nothing"),
bootstrap, block_length and reversal (one row per
original changepoint: cp and survives).
Methods: print(), tidy() (one row per original
changepoint: cp, stability and, when reversal ran,
survives_reversal) and autoplot() (frequency profile with
the original detections marked).
What a high score means
Reproducible under resampling, which is not the same as
real, and under dependent noise the two diverge: measured under
AR(1) noise, a spurious changepoint reached a stability of 1.00 and the
score separated real from spurious changepoints in only 4 of 10
replicates. The artifact is a feature of the realised noise path, and an
i.i.d. resample of the residuals rebuilds it every time.
bootstrap = "block" lets it vary; cpt_robustness(),
which changes the noise model rather than the sample, is the check that
touches the cause; and cpt_assumptions() tests the
residuals directly.
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 4))
st <- cpt_stability(x, method = "pelt", B = 20)
st
ggplot2::autoplot(st)
The detector's statistic as a function of location
Description
Returns the criterion the engine evaluated at each position, which is what
explains why a changepoint landed where it did. Available for the
engines that expose it
(subset(cpt_methods(), statistic)$method lists them), and an error
naming those engines for the ones that do not.
Usage
cpt_statistic(object)
ggcpt_statistic(object)
Arguments
object |
A |
Value
cpt_statistic() returns a tibble with index,
statistic, threshold (the engine's rejection threshold, or
NA) and label (what the statistic is).
ggcpt_statistic() returns a two-panel ggplot: the series above,
the statistic below, sharing the x axis.
See Also
cpt_solution_path(),
cpt_scale_space().
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(200), rnorm(200, 3)), method = "mosum")
head(cpt_statistic(fit))
ggcpt_statistic(fit)
Test detected changepoints
Description
Attaches a test to each detected changepoint (type = "jump") or to
each fitted segment (type = "segment"), using the engine's own
test where it has one and an explicitly unadjusted two-sample test
where it does not.
Usage
cpt_test(
object,
type = c("jump", "segment"),
correction = "none",
relevance = NULL
)
Arguments
object |
A |
type |
|
correction |
Multiple-testing correction applied across the rows, one
of the |
relevance |
Optional smallest change worth acting on, in noise
standard deviations. The null hypothesis becomes "the change is no
larger than |
Value
A tibble with columns cp (or seg_id),
estimate, statistic, p_value, method and
selection_adjusted, plus cp_index on the original scale
when the result carries a time index (as cpt_confint()
does), and p_adjusted when correction is not
"none". estimate is the change in the segment mean
(the breakpoint's slope change for segmented), and NA
for a regression-mode strucchange fit, whose change is a vector
of coefficients; its Chow test is run on the full regression model.
A multivariate result is refused: both routes test one series.
Selection bias
read this before quoting a p-value:
Testing a changepoint at a location that was chosen because the data
looked like it changed there is circular, and the resulting p-values are
anti-conservative, often severely. The selection_adjusted column
records, per row, whether the test accounts for that:
-
TRUEfor segmented's Davies test, which is built for a nuisance parameter present only under the alternative. It is one global test of "is there a breakpoint", not a test per breakpoint, so on a multi-break fit every row carries the same statistic and p-value, and the method string says so. -
FALSEfor the generic Welch two-sample fallback, which compares the segments either side of the changepoint as if the location had been fixed in advance. Useful as a descriptive effect size with a scale attached; not a valid significance test for the existence of the change. The exception is a changepoint that was fixed in advance, throughcpt_detect(fixed = ): its row isTRUE. The fallback compares means whatever the fit detected, so on a fit of a change in variance, slope or distribution it tests a different change from the one found, and warns (class
ggchangepoint_assumption).-
FALSEfor strucchange's route as well, which is the Chow F evaluated at each estimated break date. The Chow statistic's reference distribution assumes the date was fixed in advance, so quoting it at a date the Bai-Perron dynamic program chose is exactly the circularity this column exists to flag. Reporting it is conventional in that literature, which does not make it adjusted. The selection-adjusted objects there are the sup-type statistics and the Bai-Perron critical values.
Two further limits worth knowing. type = "segment" is
always the unadjusted Welch test: the native routes above apply
only to type = "jump", so a segmented fit tested
per-segment does not use Davies' test. And the split above is by
engine and type, not by engine alone.
For a guarantee that survives selection, use nsp_wrapper()
(regions with exact global coverage) or cpt_confint() with
method = "nsp". The canonical post-detection tests of Jewell,
Fearnhead and Witten (2022) are implemented in ChangepointInference,
which is not on CRAN; cpt_register_method() is the supported
way to bring it in.
See Also
cpt_confint(), nsp_wrapper().
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(60), rnorm(60, 4)), method = "pelt")
cpt_test(fit)
Test for a change at a date fixed in advance
Description
The question behind most applied changepoint work: the policy took effect on 1 March, the plant was retooled in week 14, the drug was approved in Q2. Did anything change then? Because the date was chosen before looking at the data, this is an ordinary two-sample comparison at a fixed split and needs no adjustment for selection: the p-value means what it says.
Usage
cpt_test_at(
x,
when,
window = 0,
change_in = c("mean", "var", "meanvar", "distribution"),
family = c("gaussian", "poisson", "binomial", "exponential", "l1"),
span = NULL,
index = NULL,
data = NULL,
level = 0.95,
B = 999,
seed = NULL
)
## S3 method for class 'ggcpt_test_at'
print(x, ...)
## S3 method for class 'ggcpt_test_at'
tidy(x, ...)
Arguments
x |
A numeric series (a vector, |
when |
When the change took effect: the first observation
of the new regime, as a position or a value of the series' index (a
date; for a numeric index such as a |
window |
Allow the change anywhere within |
change_in |
What to test: |
family |
For |
span |
Optional number of observations each side of the split to compare. Defaults to all of them; a span keeps a change elsewhere in a long series out of the comparison. |
index |
Optional time index when |
data |
A data frame, for formula input. |
level |
Confidence level for the interval on the change. |
B |
Permutations for |
seed |
Optional seed for the permutations, scoped to this call. |
... |
Ignored. |
Value
A ggcpt_test_at tibble with one row: when,
cp (the last observation before it, in the package's
convention) and cp_index, window, estimate (the
change: a difference in means, a ratio of rates or variances),
conf_low, conf_high, statistic, p_value,
n_before, n_after, method and
selection_adjusted (TRUE: the location was not chosen
from the data, and a window's search is paid for by the permutation).
See Also
cpt_attribute_event() for the mirror question
(was a detected change the event you know about?),
cpt_effect().
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_null()
Examples
set.seed(1)
dates <- as.Date("2026-01-01") + 0:119
x <- c(rnorm(60), rnorm(60, 0.8))
cpt_test_at(x, when = as.Date("2026-03-02"), index = dates)
# the policy took effect sometime in that fortnight
cpt_test_at(x, when = 61, window = 7, seed = 1)
Test for a change anywhere in a series
Description
A test of the global null hypothesis "the series has no changepoint", the question an empty detection raises. Nothing is located first, so nothing is selected, and the p-value means what it says.
Usage
cpt_test_null(x, method = c("cusum", "pettitt", "supF"), index = NULL)
Arguments
x |
A numeric series, or a |
method |
Which test:
|
index |
Optional time index for a bare series. |
Value
A tibble with one row: method, statistic,
p_value, location (where the statistic peaks: the most
likely changepoint, reported for orientation only), n and
selection_adjusted (TRUE).
Assumptions
All three assume independent observations. Under positive
autocorrelation they reject too often, which is the same failure the
detectors share; see cpt_assumptions().
See Also
cpt_null_power() for what an empty answer could
have detected, cpt_test_at() for a pre-specified date.
Other inference:
cpt_abruptness(),
cpt_assumptions(),
cpt_attribute(),
cpt_attribute_event(),
cpt_confint_coverage(),
cpt_effect(),
cpt_gof(),
cpt_k_weights(),
cpt_null_power(),
cpt_robustness(),
cpt_screen(),
cpt_test_at()
Examples
set.seed(1)
cpt_test_null(rnorm(200))
shifted <- c(rnorm(100), rnorm(100, 0.6))
cpt_test_null(shifted, method = "pettitt")
cpt_test_null(shifted, method = "supF")
Feed observations to a monitor
Description
Pushes new data through a cpt_monitor(), updating its
internal state and appending to its alarm log. The monitor is returned, so
the idiom is mon <- cpt_update(mon, new_obs).
Usage
cpt_update(monitor, new_obs)
Arguments
monitor |
A |
new_obs |
New observations: a numeric vector, or a matrix with rows as time points for a multivariate monitor. |
Value
The updated ggcpt_monitor: the same structure as the
input (see cpt_monitor()), with t advanced by
the number of new observations (rows, for a matrix) and any new rows
appended to alarms.
Re-assign it: the monitor is a value, not a mutable object, so
cpt_update(mon, y) without assignment discards the update.
See Also
cpt_monitor(), alarms().
Examples
set.seed(2026)
mon <- cpt_monitor("edetector", baseline = rnorm(100))
mon <- cpt_update(mon, c(rnorm(50), rnorm(50, 3)))
alarms(mon)
Re-run a result against the engines installed now
Description
A result records which version of its engine produced it (see
glance()'s engine_version). cpt_verify() answers the
question that record exists for: does the answer still hold? It
re-runs the same method on the same series with the settings the result
recorded, using whatever engines are installed today, and reports whether
the changepoints moved and which versions changed in between.
Usage
cpt_verify(object, ..., tolerance = 0)
## S3 method for class 'ggcpt_verification'
print(x, ...)
## S3 method for class 'ggcpt_verification'
tidy(x, ...)
Arguments
object |
A |
... |
Further arguments for the re-run, overriding what was recovered from the result (for instance an engine argument the recorded call held as a variable, which cannot be recovered from the object). |
tolerance |
Positions a changepoint may move and still count as
the same. Defaults to |
x |
A |
Details
Upstream engines change: a default is revised, a bug is fixed, a tie-breaking rule moves. None of that raises an error, so a result produced last year and re-run today can differ without anything saying so. This is the check to run when re-opening an analysis, and before quoting an old result as current.
The re-run uses the series stored on the result, its method, the change
type it can be asked for, its penalty and family, the missing-value
handling and constraints it recorded (na_action, fixed,
within, min_segment, min_effect), and every engine
argument of the original call that was written as a literal (seed = 42,
n_intervals = 500). An argument written as a variable cannot be
recovered from the object, and is listed in not_recovered; pass
it again through ... if it mattered. A result read back with
cpt_import() from JSON keeps the call it was written with,
so it replays the same way; one made by anything but cpt_detect()
or a wrapper (as_ggcpt(), the fit
cpt_select() returns) is refused, since re-running
cpt_detect() would not reproduce how it was made.
Value
A ggcpt_verification object: a list with verified
(TRUE when every changepoint reproduces within
tolerance), then and now (the two sets of
locations), added and removed (locations in one set with
no partner in the other), versions (a tibble with
component, then, now and changed),
not_recovered (call arguments that could not be replayed) and
refit, the new ggcpt. With a print() method.
See Also
glance.ggcpt() for the recorded
engine_version.
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(80), rnorm(80, 4)), method = "pelt")
cpt_verify(fit)
Changepoint wrapper
Description
This function wraps a number of cpt functions from the changepoint
package and the cpt.np() function from the changepoint.np package.
It is handy that users can use this function to get the same changepoint
results as these functions output individually. Moreover, it returns a tibble
that inherits the tidyverse style. Functions from the changepoint package do
require data normality assumption by default, yet changepoint.np is a
non-parametric way to detect changepoints and let data speak by itself.
If user sets change_in as np (or cpt_np), a seed should
be set before using the function for the sake of reproducibility. For more
details on the changepoint and changepoint.np packages, please refer to
their documentation.
Usage
cpt_wrapper(data, change_in = "mean_var", cp_method = "PELT", ...)
Arguments
data |
A numeric vector. |
change_in |
Choice of |
cp_method |
A wide range of choices (i.e., |
... |
Extra arguments for each |
Value
A tibble including which point(s) is/are the changepoint along with
raw changepoint value corresponding to that changepoint. Changepoint
locations follow the convention of the changepoint package: the
last index of the left segment. The upstream cpt object is
attached as the "ggcpt_fit" attribute, which is what
cpt_detect() stores in the result's $fit.
Standardise the data for a change in mean
With change_in = "mean" the upstream Normal cost assumes a noise
standard deviation of 1 and the penalty is compared against the raw
residual sum of squares, so a series with wider noise is under-penalised
and over-segmented: about 39 changepoints instead of 1 at
\sigma = 3 on 200 observations (mean over 20 draws). Standardise the series first, or use
change_in = "mean_var", which estimates a variance per segment and
is unaffected. See the scale-sensitivity section of
cpt_detect.
References
Killick R, Eckley I (2014). “changepoint: An R package for changepoint analysis.” Journal of statistical software, 58(3), 1–19.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2022)
cpt_wrapper(c(rnorm(100,0,1),rnorm(100,0,10)))
cpt_wrapper(c(rnorm(100,0,1),rnorm(100,10,1)))
DeCAFS wrapper: changes amid drift and autocorrelated noise
Description
Wraps DeCAFS::DeCAFS() (Romano, Rigaill, Runge and Fearnhead,
2022), which detects abrupt mean changes when the underlying signal also
drifts (random-walk fluctuations) and the noise is AR(1)-autocorrelated,
the two regimes in which plain change-in-mean methods over-detect. Model
parameters are estimated automatically unless supplied.
Usage
decafs_wrapper(x, penalty = NULL, model_param = NULL, ...)
Arguments
x |
A numeric vector. |
penalty |
Penalty |
model_param |
Optional list of model parameters
( |
... |
Additional arguments passed to |
Value
A ggcpt object. The data tibble carries the
estimated signal in its fitted column.
References
Romano G, Rigaill G, Runge V, Fearnhead P (2022). “Detecting abrupt changes in the presence of local fluctuations and autocorrelated noise.” Journal of the American Statistical Association, 117(540), 2147–2162.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- decafs_wrapper(c(rnorm(100), rnorm(100, 5)))
res$changepoints
ecp wrapper
Description
The ecp package provides a non-parametric way to detect changepoints. Unlike
the changepoint package, it does not assume raw data to have any formal
distribution. This wrapper function wraps two functions from the ecp package,
i.e., e.divisive() and e.agglo(). Users can use either function
by switching the algorithm argument. Before using the wrapper function,
seed should be set for the sake of reproducibility.
Usage
ecp_wrapper(data, algorithm = "divisive", min_size = 2, seed = NULL, ...)
Arguments
data |
A numeric vector (for univariate) or matrix/data.frame (for multivariate). |
algorithm |
Either |
min_size |
Minimum number of observations between change points. By
default is 2. This argument is only applied when |
seed |
Optional. A seed for reproducibility of the stochastic
permutation test. The seed is scoped to this call: |
... |
Extra arguments to pass on either from |
Value
A tibble includes which point(s) is/are the changepoint along with
raw changepoint value corresponding to that changepoint. Changepoint
locations follow the ecp package convention: the first index of the
right segment. When no changepoint is found, an empty tibble is returned
(0 rows). The upstream fit is not retained ($fit is
NULL on a ggcpt from cpt_detect(method = "ecp")),
because ecp::e.agglo()'s cluster-progression matrix is quadratic
in the series length; call the ecp functions directly if you need
their full output.
References
James NA, Matteson DS (2014). “ecp: An R package for nonparametric multiple change point analysis of multivariate data.” Journal of Statistical Software, 62(7), 1–25. doi:10.18637/jss.v062.i07.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2022)
ecp_wrapper(c(rnorm(100,0,1),rnorm(100,0,10)))
ecp_wrapper(c(rnorm(100,0,1),rnorm(100,10,1)))
EnvCpt wrapper: changepoints versus trends versus autocorrelation
Description
Wraps EnvCpt::envcpt() (Beaulieu and Killick, 2018), which fits up
to twelve competing models (constant mean or linear trend, each with or
without changepoints, and with white-noise, AR(1) or AR(2) errors) and
lets an information criterion decide whether the series really contains
changepoints or merely trend/autocorrelation ("memory"). The changepoints
of the winning model (if any) are returned, and the winning model's name
is recorded, guarding against the classic false positive of running a
mean-shift detector on autocorrelated data.
Usage
envcpt_wrapper(
x,
models = c("mean", "meancpt", "meanar1", "meanar2", "meanar1cpt", "meanar2cpt",
"trend", "trendcpt", "trendar1", "trendar2", "trendar1cpt", "trendar2cpt"),
criterion = c("AIC", "BIC"),
minseglen = 5,
...
)
Arguments
x |
A numeric vector. |
models |
Character vector of models to fit; see
|
criterion |
Model selection criterion: |
minseglen |
Minimum segment length. Defaults to |
... |
Additional arguments passed to |
Value
A ggcpt object. $fit holds the full envcpt
output; the selected model name is stored in the penalty descriptor and
printed by glance() via penalty_type. Individual model
fits that fail are expected (the criterion ignores them), so the
engine's own try() output is not passed on; genuine warnings
still are, and a series on which no model fits at all raises an error.
A constant series has no changepoints and is not handed to the engine,
so $fit is NULL there.
References
Beaulieu C, Killick R (2018). “Distinguishing trends and shifts from memory in climate data.” Journal of Climate, 31(23), 9519–9543.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- envcpt_wrapper(c(rnorm(100), rnorm(100, 3)))
res$changepoints
ESAC wrapper: sparsity-adaptive high-dimensional detection
Description
Wraps HDCD::ESAC() (Moen, Glad and Tveten, 2023): Efficient
Sparsity Adaptive Changepoint estimation for a change in the mean vector
of a high-dimensional series. Where inspect projects onto a single
estimated sparse direction, ESAC adapts across the whole sparsity range at
once, which is a different regime rather than a refinement of the same one:
it is competitive both when a handful of coordinates change and when all
of them do.
Usage
esac_wrapper(
x,
threshold_d = 1.5,
threshold_s = 1,
empirical = FALSE,
N = 1000,
seed = NULL,
...
)
Arguments
x |
A numeric matrix or data frame with rows as time points and columns as coordinates. |
threshold_d, threshold_s |
Leading constants of the dense and sparse
thresholds. Defaults follow the engine ( |
empirical |
Calibrate the thresholds by Monte Carlo rather than using
the theoretical values? Slower but sharper; defaults to |
N |
Monte Carlo samples when |
seed |
Optional seed (used by the empirical calibration). The seed
is scoped to this call: |
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries
cusum (the ESAC statistic at each detected location) and
depth (its level in the recursion).
References
Moen PAJ, Glad IK, Tveten M (2024). “Efficient sparsity adaptive changepoint estimation.” Electronic Journal of Statistics, 18(2), 3975–4038. doi:10.1214/24-EJS2294.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- matrix(rnorm(100 * 20), nrow = 100)
X[51:100, 1:5] <- X[51:100, 1:5] + 3
esac_wrapper(X)
Network-structure changepoints via non-negative matrix factorisation
Description
Wraps fabisearch::detect.cps() (Ondrus, Olds and Cribben, 2024):
factorised binary search for changes in the network structure of a
high-dimensional series. Each candidate split is scored by how much better
a rank-r non-negative matrix factorisation fits the two halves
separately than together, and significance is assessed by permutation.
Usage
fabisearch_wrapper(
x,
min_dist = 35,
n_runs = 50,
n_reps = 100,
alpha = NULL,
rank = NULL,
n_core = 1,
seed = NULL,
...
)
Arguments
x |
A non-negative numeric matrix or data frame with rows as time points and columns as nodes. Non-negativity is a hard requirement of NMF, not a preference; see the section below. |
min_dist |
Minimum distance between changepoints. Defaults to
|
n_runs |
NMF runs per candidate split. Defaults to |
n_reps |
Replicates on each side of the significance test: the
split is refitted |
alpha |
Significance level applied to the p-value each candidate
split receives. Defaults to |
rank |
NMF rank, a positive whole number. |
n_core |
Cores for the permutation stage. Defaults to |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments passed to |
Value
A ggcpt object with change_in = "network". Multivariate input is
reduced to one series per observation by taking the
cross-sectional mean of the columns, and that is the series stored on
the result: autoplot() draws it, tidy()'s
cp_value reads it, and $segments$param_estimate and
augment()'s .fitted/.resid are computed from it.
It is not any one column of the input. The full input is kept in
$data_wide for autoplot(type = "coordinates").
Non-negativity, cost, and the attached namespace
Three practical notes. (1) NMF is undefined for negative entries, so this
wrapper refuses them rather than letting the engine fail deep inside a
factorisation; shift or rescale the series first if it has negatives.
(2) It is by far the most expensive engine here (n_runs times
n_reps factorisations per candidate split), so the defaults are
lowered in the examples. The engine's own progress output is suppressed,
so a long call is silent until it returns. (3) fabisearch calls
NMF's multi-run machinery, which resolves helpers through the
search path and fails with "none of the packages are loaded" when
NMF is merely loaded; this wrapper therefore attaches NMF for
the duration of the call and detaches it again afterwards.
References
Ondrus M, Cribben I (2024). “fabisearch: a package for change point detection in and visualization of the network structure of multivariate high-dimensional time series in R.” Neurocomputing, 578, 127321. doi:10.1016/j.neucom.2024.127321.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
# A change in *structure*, not in scale: two latent factors drive
# different halves of the node set before and after the change.
# Deliberately tiny: this is by far the most expensive engine in the
# package (n_runs x n_reps factorisations per candidate split). Measured
# at 5-6 s across fresh sessions, against 27 s for the 2 x 25 /
# n_reps = 4
# version this replaced, and this is the floor: `n_reps = 1` fails
# inside fabisearch with "not enough 'x' observations" (the permutation
# test needs two), and smaller matrices are not reliably cheaper because
# the search then evaluates more splits relative to `min_dist` (2 x 10 at
# min_dist = 8 measured 6.6 s). So this one example stays near CRAN's 5 s
# budget by necessity; `cran-comments.md` says so. Use the defaults on
# real data; the settings here are for the budget, not for detection.
set.seed(2026)
block <- function(n, cols) {
f <- abs(stats::rnorm(n)) + 0.5
Y <- matrix(abs(stats::rnorm(n * 5)) * 0.2 + 0.1, n, 5)
Y[, cols] <- Y[, cols] + f
Y
}
Y <- rbind(block(12, 1:2), block(12, 3:5))
fabisearch_wrapper(Y, min_dist = 10, n_runs = 1, n_reps = 2,
alpha = 0.25, rank = 2)
fastcpd wrapper: fast changepoint detection via sequential gradient descent
Description
Wraps the fastcpd package (Li and Zhang, 2024), a modern PELT-family
engine that pairs pruning with sequential gradient descent so that exact or
near-exact segmentations of many model families run in near-linear time.
Every family the engine documents is reachable except its user-supplied
custom cost: Gaussian mean, variance and both; the count and
binary families ("poisson", "binomial") and waiting times
("exponential"); linear and penalised regression ("lm",
"lasso") and generalised linear models ("poisson",
"binomial" with covariates); and the time-series models
"ar", "arma", "arima", "garch" and, for a
multivariate series, "var".
Usage
fastcpd_wrapper(
x,
family = c("mean", "variance", "meanvariance", "ar", "arma", "arima", "garch", "var",
"lm", "lasso", "poisson", "binomial", "exponential"),
order = NULL,
covariates = NULL,
...
)
Arguments
x |
A numeric vector, or (for |
family |
Model family. |
order |
Model order for |
covariates |
Optional numeric matrix of regressors, one row per
observation, for |
... |
Additional arguments passed to the corresponding
|
Value
A ggcpt object. The engine's per-segment parameter
estimates (thetas) are kept as $coefficients, one row
per segment and parameter, for the families where they are
coefficients (the regressions and the intercept-only count, binary and
waiting-time models).
References
Li X, Zhang X (2024). “fastcpd: Fast change point detection in R.” arXiv preprint arXiv:2404.05933.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- fastcpd_wrapper(c(rnorm(100), rnorm(100, 4)))
res$changepoints
# A change in a Poisson rate
counts <- fastcpd_wrapper(c(rpois(100, 3), rpois(100, 9)),
family = "poisson")
counts$changepoints
Functional covariance changepoints
Description
Wraps fChange::fchange() for changes in the covariance operator,
eigenstructure or trace of a functional time series: the changes that
leave the mean curve untouched.
Usage
fcov_wrapper(
x,
target = c("covariance", "trace", "eigenjoint", "eigensingle"),
statistic = c("Tn", "Mn"),
critical = c("simulation", "resample", "welch"),
type = c("segmentation", "single"),
alpha = 0.05,
...
)
Arguments
x |
A numeric matrix or data frame with one row per time point and one column per grid location (the curve's resolution). |
target |
What to test: |
statistic |
Test statistic: |
critical |
How critical values are obtained: |
type |
|
alpha |
Significance level. Defaults to |
... |
Additional arguments passed to |
Value
A ggcpt object with change_in = "covariance". Multivariate input is
reduced to one series per observation by taking the
cross-sectional mean of the columns, and that is the series stored on
the result: autoplot() draws it, tidy()'s
cp_value reads it, and $segments$param_estimate and
augment()'s .fitted/.resid are computed from it.
It is not any one column of the input. The full input is kept in
$data_wide for autoplot(type = "coordinates").
For a covariance change this matters when reading the plot: a change in
the covariance structure need not move the cross-sectional mean at all,
so autoplot() can legitimately show changepoint rules on a
series with no visible change in it. That is the detector working, not
misfiring; use autoplot(type = "coordinates") to see the
columns the change is in.
How long this takes
Minutes, not seconds, on a series of a hundred points: by a
wide margin the most expensive engine in the package, and slow enough
that a first call looks like a hung session. Timed on one Linux x86-64
machine, against fmean_wrapper() on the identical input
so the comparison is the same package and the same data:
| input | fmean | fcov |
n = 60, p = 5 | 4.5 s | 316 s |
n = 120, p = 5 | 2.9 s | 598 s |
The cost is roughly linear in the number of time points and it is in the
engine's own estimation rather than in this wrapper. It is, however,
dominated by target, which the rest of this section used to deny.
Measured at n = 60, p = 6, M = 50 on one Linux
x86-64 machine:
| target | time | changepoints found |
"covariance" (default) | 477 s | none |
"eigenjoint" | 21.7 s | none |
"eigensingle" | 21.7 s | none |
"trace" | 2.1 s | 16, 30, 38 |
So the default is some two hundred times the cost of "trace", and
the example below uses "trace" for that reason. Read that as a
choice of test and not as a free speedup: the trace is a scalar summary
of the covariance operator, so it is a weaker instrument that happens to
be cheap, and the row above is one series rather than a comparison of
power. If a covariance change matters and the full operator test is the
one you want, budget for it.
Two practical consequences either way: size the call before starting it,
and do not put the default in a loop: a twelve-replicate study at
n = 120 is two hours. Another machine will give different
absolute numbers; the ratios are the part to plan around.
The “Benchmarks” article compares the engines that do scale.
References
Aue A, Rice G, Sönmez O (2020). “Structural break analysis for spectrum and trace of covariance operators.” Environmetrics, 31(1), e2617.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
# See the note in ?fmean_wrapper on why this is 10 curves and M = 50.
X <- matrix(rnorm(60 * 10), nrow = 60)
X[31:60, ] <- X[31:60, ] * 3
fcov_wrapper(X, target = "trace", M = 50)
Functional mean changepoints
Description
Wraps fChange::fchange() for changes in the mean function of
a functional time series: each observation is a curve, and the question is
when the average curve shape changes. The binary-segmentation
("segmentation") mode finds multiple changes; the "single"
mode runs the one-change test and reports its p-value.
Usage
fmean_wrapper(
x,
statistic = c("Tn", "Mn"),
critical = c("simulation", "resample", "welch"),
type = c("segmentation", "single"),
alpha = 0.05,
robust = FALSE,
...
)
Arguments
x |
A numeric matrix or data frame with one row per time point and one column per grid location (the curve's resolution). |
statistic |
Test statistic: |
critical |
How critical values are obtained: |
type |
|
alpha |
Significance level. Defaults to |
robust |
Use the robust ( |
... |
Additional arguments passed to |
Value
A ggcpt object; the changepoints tibble carries the
engine's p_value for each location. Multivariate input is
reduced to one series per observation by taking the
cross-sectional mean of the columns, and that is the series stored on
the result: autoplot() draws it, tidy()'s
cp_value reads it, and $segments$param_estimate and
augment()'s .fitted/.resid are computed from it.
It is not any one column of the input. The full input is kept in
$data_wide for autoplot(type = "coordinates").
References
Aue A, Rice G, Sönmez O (2018). “Detecting and dating structural breaks in functional data without dimension reduction.” Journal of the Royal Statistical Society: Series B, 80(3), 509–529. doi:10.1111/rssb.12257.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
# 10 curves and M = 50, not 20 and 200: the example is a demonstration,
# and the wider version measured 6.7 s against CRAN's 5 s budget.
X <- matrix(rnorm(60 * 10), nrow = 60)
X[31:60, ] <- X[31:60, ] + 2
fmean_wrapper(X, M = 50)
FPOP wrapper: Functional Pruning Optimal Partitioning
Description
Wraps the fpop package for optimal changepoint detection via
functional pruning.
Usage
fpop_wrapper(x, penalty = NULL, ...)
Arguments
x |
A numeric vector. |
penalty |
Penalty value. Defaults to |
... |
Additional arguments passed to |
Details
fpop was archived from CRAN in 2026 at its maintainer's request and
is still built on R-Forge, where it is developed. Install it with
install.packages("fpop", repos = "https://R-Forge.R-project.org"),
or with cpt_install_engines("core").
Value
A ggcpt object.
References
Maidstone R, Hocking T, Rigaill G, Fearnhead P (2017). “On Optimal Multiple Changepoint Algorithms for Large Data.” Statistics and Computing, 27(2), 519–533. doi:10.1007/s11222-016-9636-3.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 4))
fpop_wrapper(x)$changepoints
# the default penalty assumes sd 1; scale it for wider noise
y <- 5 * x
fpop_wrapper(y, penalty = log(length(y)) * var(diff(y)))$changepoints
Changepoint vertical rules geom
Description
Draws vertical lines at changepoint locations. Mimics geom_vline
but designed to work with the tidy changepoint data frames returned by
the package. Can be used as a standalone layer:
geom_changepoint(data = cp_df, aes(xintercept = cp)).
Usage
geom_changepoint(
mapping = NULL,
data = NULL,
...,
na.rm = FALSE,
show.legend = NA
)
Arguments
mapping |
Set of aesthetic mappings created by |
data |
A data frame with changepoint information. |
... |
Other arguments passed to |
na.rm |
If |
show.legend |
Whether to show legend. |
Value
A ggplot layer.
See Also
Other ggplot2 layers:
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
cp <- data.frame(cp = cpt_detect(d$y, method = "pelt")$changepoints$cp)
ggplot(d, aes(t, y)) + geom_line() +
geom_changepoint(aes(xintercept = cp), data = cp, colour = "blue")
Changepoint confidence interval geom
Description
Draws horizontal whiskers for changepoint-location confidence intervals (e.g. from MOSUM, stepR, strucchange, segmented).
Usage
geom_cpt_ci(mapping = NULL, data = NULL, ..., na.rm = FALSE, show.legend = NA)
Arguments
mapping |
Aesthetic mappings. Requires |
data |
A data frame with CI information. |
... |
Other arguments passed to |
na.rm |
If |
show.legend |
Whether to show legend. |
Value
A ggplot layer.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
ci <- data.frame(xmin = 45, xmax = 56, y = 0)
ggplot(d, aes(t, y)) + geom_line() +
geom_cpt_ci(aes(xmin = xmin, xmax = xmax, y = y), data = ci,
inherit.aes = FALSE, width = 0.4, colour = "blue")
Event annotation geom
Description
Marks known real-world events on a changepoint plot: a vertical rule plus
a text label. "Changepoint at index 147" is not a finding; "changepoint at
2020-03-11, matching the WHO pandemic declaration" is.
cpt_annotate_events() produces the frame this layer expects
and, crucially, also reports the changepoints no event explains and the
events no changepoint found.
Usage
geom_cpt_event(
mapping = NULL,
data = NULL,
...,
colour = "grey30",
linetype = "dotted",
angle = 90,
size = 3,
vjust = -0.4,
hjust = 0,
repel = NULL,
inherit.aes = FALSE,
na.rm = FALSE
)
Arguments
mapping |
Aesthetic mappings. Requires |
data |
A data frame of events (see
|
... |
Other arguments passed to the text layer. |
colour |
Rule and text colour. Defaults to |
linetype |
Rule linetype. Defaults to |
angle |
Text angle in degrees. Defaults to |
size |
Text size. Defaults to |
vjust, hjust |
Text justification. |
repel |
Use ggrepel to keep labels from overlapping? Defaults
to |
inherit.aes |
Whether the label layer inherits the plot's
aesthetics. Defaults to |
na.rm |
If |
Value
A list of two ggplot layers (a rule and a label), which can be added to a plot exactly like a single layer.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
ev <- data.frame(x = 50, label = "policy change")
ggplot(d, aes(t, y)) + geom_line() +
geom_cpt_event(aes(xintercept = x, label = label), data = ev,
repel = FALSE)
Changepoint label geom
Description
Draws labelled regions behind a series: the central object of supervised
changepoint detection (Hocking et al.), where an expert marks intervals as
containing a change or not and the penalty is learned from those labels.
Fill defaults to the label's change status, so a plot of labels
reads as a picture of what the expert asserted; map fill to the
status column of cpt_label_error() instead to get the
correct / false-positive / false-negative display.
Usage
geom_cpt_label(
mapping = NULL,
data = NULL,
...,
alpha = 0.25,
colour = NA,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE
)
Arguments
mapping |
Aesthetic mappings. Requires |
data |
A data frame of labels, e.g. |
... |
Other arguments passed to |
alpha |
Fill transparency. Defaults to |
colour |
Border colour. Defaults to |
na.rm |
If |
show.legend |
Whether to show a legend. |
inherit.aes |
Whether to inherit the plot's aesthetics. Defaults to
|
Value
A ggplot layer.
See Also
cpt_labels(), cpt_label_error(),
scale_fill_cpt_label().
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
labs <- cpt_labels(c(40, 70), c(60, 90), c("change", "no_change"))
ggplot(d, aes(t, y)) +
geom_cpt_label(aes(xmin = start, xmax = end, fill = change),
data = labs) +
geom_line() +
scale_fill_cpt_label()
Significance region geom
Description
Draws a changepoint that is an interval: a vertical band spanning
xmin to xmax and the full height of the panel. This is the
display Narrowest Significance Pursuit needs
(nsp_wrapper()): NSP returns intervals each of which
contains at least one changepoint at a prescribed global
significance level, which is neither a point estimate nor a confidence
interval around one. autoplot() adds this layer automatically for
a result that carries regions.
Usage
geom_cpt_region(
mapping = NULL,
data = NULL,
...,
alpha = 0.2,
fill = "steelblue",
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE
)
Arguments
mapping |
Aesthetic mappings. Requires |
data |
A data frame of regions, e.g. |
... |
Other arguments passed to |
alpha |
Fill transparency. Defaults to |
fill |
Band fill colour. Defaults to |
na.rm |
If |
show.legend |
Whether to show a legend. |
inherit.aes |
Whether to inherit the plot's aesthetics. Defaults to
|
Value
A ggplot layer.
See Also
nsp_wrapper(), cpt_regions().
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
regions <- data.frame(xmin = 44, xmax = 57)
ggplot(d, aes(t, y)) +
geom_cpt_region(aes(xmin = xmin, xmax = xmax), data = regions) +
geom_line()
Changepoint segment level geom
Description
Draws horizontal segments representing the estimated level of each segment
between changepoints. Typically used with data from augment().
Usage
geom_cpt_segment(
mapping = NULL,
data = NULL,
...,
na.rm = FALSE,
show.legend = NA
)
Arguments
mapping |
Aesthetic mappings. Requires |
data |
A data frame with segment information. |
... |
Other arguments passed to |
na.rm |
If |
show.legend |
Whether to show legend. |
Value
A ggplot layer.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
ggchangepoint-ggproto,
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
fit <- cpt_detect(c(rnorm(50), rnorm(50, 4)), method = "pelt")
ggplot(fit$data, aes(index, value)) + geom_line(colour = "grey70") +
geom_cpt_segment(aes(x = start, xend = end, y = param_estimate,
yend = param_estimate),
data = fit$segments, colour = "blue", linewidth = 1)
Geometrically-inspired multivariate changepoint wrapper (geomcp)
Description
Wraps changepoint.geo::geomcp() (Grundy, Killick and Mihaylov,
2020): each multivariate observation is mapped to its distance from, and
angle to, a reference point, and univariate PELT is run on the two mapped
series. Distance changes capture shifts in magnitude, angle changes
capture shifts in orientation/correlation structure.
Usage
geomcp_wrapper(
x,
penalty = "MBIC",
mapping = c("both", "distance", "angle"),
...
)
Arguments
x |
A numeric matrix or data frame with one row per time point. |
penalty |
Penalty for the univariate PELT runs (a
changepoint-style character penalty). Defaults to |
mapping |
Which mapped series' changepoints to report:
|
... |
Additional arguments passed to
|
Value
A ggcpt object whose changepoints tibble carries a
mapping column ("distance" or "angle"; a location
found in both is labelled "both").
References
Grundy T, Killick R, Mihaylov G (2020). “High-dimensional changepoint detection via a geometrically inspired mapping.” Statistics and Computing, 30, 1155–1166.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- rbind(matrix(rnorm(100 * 4), 100), matrix(rnorm(100 * 4, 2), 100))
res <- geomcp_wrapper(X)
res$changepoints
Conditions raised by ggchangepoint
Description
Every error, warning and message this package raises carries a class, so code that calls it can react to the kind of failure rather than matching its wording. The text is written for a person and may be improved between releases; the classes and the fields listed here are the interface, and follow the package's deprecation policy.
Errors
Every error inherits from ggchangepoint_error (and from
error and condition). The subclasses, most specific first:
ggchangepoint_input_errorThe call itself is not usable: a bad argument or data that violates a precondition. Its subclasses say which precondition:
ggchangepoint_short_series(too few observations, for the package or for the engine that was asked; fieldn),ggchangepoint_wrong_dimension(a univariate method handed a matrix, or the reverse),ggchangepoint_non_finite(NA,NaNorInfwhere the method needs finite data),ggchangepoint_bad_type(a factor, text, a survival object or timestamps where a numeric series was expected) andggchangepoint_bad_argument(an argument value outside its documented range or vocabulary).ggchangepoint_unsupportedThe request is well formed but not something this method offers: a
change_in,familyor capability the registry does not list for it. Fieldsmethod,requestedandsupportedwhere they apply. Subclasses:ggchangepoint_capability_absent(the result carries no interval, statistic, path or posterior to read),ggchangepoint_planned_method(named incpt_methods()but not wired) andggchangepoint_unknown_method.ggchangepoint_engine_missingA suggested engine package is not installed. Field
package, andinstall, the call that installs it.ggchangepoint_engine_errorThe upstream engine failed. Fields
engine,methodand, where it was caught,parent, the engine's own condition.ggchangepoint_upstream_bugA known, version-guarded defect in an engine, refused rather than returned. Fields
packageandversion.ggchangepoint_internal_errorA state the package should never reach: a bug here, worth reporting.
The functions that run many fits (cpt_benchmark(),
cpt_consensus()) record a failure that belongs to one
method (ggchangepoint_engine_error,
ggchangepoint_engine_missing, ggchangepoint_unsupported,
ggchangepoint_upstream_bug, or a series of the wrong shape or
length for that method) and carry on; any other error stops them, since
every method would have hit it.
Warnings
Every warning inherits from ggchangepoint_warning. The ones worth
handling by class: ggchangepoint_assumption and its subclasses
ggchangepoint_scale_sensitive, ggchangepoint_data_type and
ggchangepoint_dependence (the method's assumptions look violated
for this series); ggchangepoint_degenerate_segmentation (a
changepoint after every observation); ggchangepoint_implausible_count
(more changepoints than the series can plausibly hold);
ggchangepoint_change_in_routed (the request was answered with the
method's native change type); ggchangepoint_argument_ignored;
ggchangepoint_level_not_applied; ggchangepoint_selection_unadjusted
(p-values computed at data-chosen locations);
ggchangepoint_collapsed_ladder; ggchangepoint_replicates_failed;
ggchangepoint_cp_dropped (locations normalised away by
as_ggcpt()); ggchangepoint_irregular_index;
ggchangepoint_na_omitted; ggchangepoint_wide_interval;
ggchangepoint_large_fit; ggchangepoint_short_series_warning
(a series too short for the result to be interpretable);
ggchangepoint_dropped_input (constant coordinates or out-of-range
locations left out); ggchangepoint_engine_failed (some methods
failed and were left out); ggchangepoint_recycled_input;
ggchangepoint_constraint and ggchangepoint_deprecated.
Anything else is plain ggchangepoint_warning.
Messages
Informational messages inherit from ggchangepoint_message, so
suppressMessages(classes = "ggchangepoint_message") silences this
package without silencing the engines.
See Also
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
is_ggcpt(),
new_ggcpt(),
print.ggcpt()
Examples
res <- tryCatch(cpt_detect(c(1, 2), method = "pelt"),
ggchangepoint_short_series = function(e) "too short")
res
# Branch on the kind of failure, not on its wording:
tryCatch(
cpt_detect(rnorm(50), method = "pelt", change_in = "network"),
ggchangepoint_unsupported = function(e) {
paste("unsupported:", e$method, "offers", toString(e$supported))
}
)
ggproto objects for the changepoint layers
Description
The layers are real ggplot2 extensions: each geom_*() is a
layer built on one of these, with its own default aesthetics, required
aesthetics and legend glyph, so they take part in scales, guides and the
position system like any geom, and can be extended with
ggplot2::ggproto(). Until 0.6.0 every layer was a thin wrapper
around a stock geom and borrowed its glyph.
GeomChangepointa vertical rule at each
xintercept(geom_changepoint()); key: a vertical rule.GeomCptSegmenta segment level (
geom_cpt_segment()).GeomCptCia horizontal interval with caps (
geom_cpt_ci()); key: the same interval.GeomCptRegiona band from
xmintoxmax, full height unlessymin/ymaxare mapped (geom_cpt_region()); key: a shaded band.GeomCptLabela labelled interval behind the series (
geom_cpt_label()).GeomCptEventa dotted rule with its label (
geom_cpt_event()); key: a dotted rule with a flag.StatChangepoint,StatCptRegiondetection inside the layer (
stat_changepoint(),stat_cpt_region()).
Format
ggproto objects.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
stat_changepoint(),
stat_cpt_region()
Examples
library(ggplot2)
class(GeomChangepoint)
GeomCptRegion$default_aes
Compare multiple changepoint detection methods
Description
Runs several detectors on the same data and returns a faceted or overlaid
ggplot comparison. Respects future::plan() for parallel execution
if the future.apply package is available.
Usage
ggcpt_compare(
x,
methods = c("pelt", "binseg", "amoc"),
layout = c("facet", "overlay"),
change_in = "mean",
seed = NULL,
...
)
Arguments
x |
A numeric vector (the data series). A one-column matrix or data
frame is accepted; wider input is refused, because these detectors are
univariate and flattening the columns would invent a changepoint at
every seam. Use |
methods |
Character vector of method names (passed to |
layout |
Layout type. |
change_in |
What to detect change in. Passed to each detector. |
seed |
Optional seed for reproducible parallelism. Passed to
|
... |
Additional arguments passed to each detector. |
Value
A ggplot object.
Positions, not a time index
Unlike cpt_detect(), cpt_batch() and
autoplot.ggcpt(), these two take no index: the
input is reduced to a bare numeric vector, so a ts, xts,
zoo or tsibble is plotted (and tabulated) in observation
positions with an "Index" axis. To compare detectors on dated data, run
cpt_detect(x, method = m, index = dates) per method and read
tidy()'s cp_index, or plot the results with
autoplot().
Choosing the method by its answer
Running several methods and reporting the one that found a change, as
if it were the only one run, is a garden of forking paths with a plot
attached, and 51 methods behind one call make it easier here than
anywhere else. A method chosen because of its answer carries no valid
p-value, and neither does any test at its changepoints: the selection
across methods is a second selection on top of the one each method
already makes (see cpt_test()'s selection_adjusted).
Choose the method before seeing the data (cpt_recommend()
answers from what you know about the problem, not from the series), or
report every method you ran. Agreement across methods, as
cpt_consensus() counts it, is a robustness display, not a
correction: the methods share engines, costs and assumptions.
Examples
set.seed(2022)
x <- c(rnorm(100, 0, 1), rnorm(100, 10, 1))
ggcpt_compare(x, methods = c("pelt", "binseg"))
Comparison table
Description
Returns a tidy tibble combining the results of multiple detectors on the same series.
Usage
ggcpt_compare_table(
x,
methods = c("pelt", "binseg", "amoc"),
change_in = "mean",
...
)
Arguments
x |
A numeric vector (the data series). A one-column matrix or data
frame is accepted; wider input is refused, because these detectors are
univariate and flattening the columns would invent a changepoint at
every seam. Use |
methods |
Character vector of method names. |
change_in |
What to detect change in. |
... |
Additional arguments passed to each detector. |
Value
A tibble with columns method, cp, cp_value.
See Also
Other plotting:
ggcpt_eval(),
ggcpt_interactive(),
ggcptplot(),
ggecpplot()
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 5))
ggcpt_compare_table(x, methods = c("pelt", "binseg"))
Evaluation visualization
Description
Overlays predictions and ground truth on the series with tolerance windows,
colouring true positives, false positives, and misses. Uses the same
one-to-one matching as cpt_metrics(), so the plot and the
metrics agree.
Usage
ggcpt_eval(pred, truth, data_vec = NULL, margin = 5)
Arguments
pred |
Predicted changepoint indices, or a |
truth |
Ground truth changepoint indices. |
data_vec |
The original data vector (for context). Taken from
|
margin |
Tolerance margin (default 5). |
Value
A ggplot object.
See Also
Other plotting:
ggcpt_compare_table(),
ggcpt_interactive(),
ggcptplot(),
ggecpplot()
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 5))
fit <- cpt_detect(x, method = "pelt")
ggcpt_eval(fit$changepoints$cp, truth = 100, data_vec = x)
Interactive changepoint plot
Description
Renders a ggcpt result (or any ggplot built from one) as an
interactive HTML widget, with values on hover. A thin convenience
wrapper: the static autoplot() path is untouched.
Usage
ggcpt_interactive(
x,
engine = c("plotly", "ggiraph"),
width_svg = 8,
height_svg = 5,
...
)
Arguments
x |
A |
engine |
Which renderer: |
width_svg, height_svg |
Figure size in inches for
|
... |
Additional arguments passed to |
Value
A plotly or ggiraph htmlwidget.
See Also
Other plotting:
ggcpt_compare_table(),
ggcpt_eval(),
ggcptplot(),
ggecpplot()
Examples
res <- cpt_detect(c(rnorm(50), rnorm(50, 5)), method = "pelt")
ggcpt_interactive(res)
Coerce, format, and plot ggcpt objects
Description
Convenience S3 methods for working with ggcpt objects: coerce the
changepoints to a tibble or data frame, render a one-line summary string, or
produce the default plot (a base-graphics fallback that delegates to
autoplot.ggcpt).
Usage
## S3 method for class 'ggcpt'
as_tibble(x, ..., .name_repair = NULL)
## S3 method for class 'ggcpt'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
## S3 method for class 'ggcpt'
format(x, ...)
## S3 method for class 'ggcpt'
plot(x, ...)
Arguments
x |
A |
... |
Additional arguments passed to methods. |
.name_repair |
Ignored (the changepoints tibble already has valid, unique names); present for signature compatibility with the generic. |
row.names, optional |
Passed to |
Value
as_tibble() and as.data.frame() return the changepoints
table; format() returns a length-one character string; plot()
draws the default plot and returns the ggplot object invisibly.
See Also
ggcpt_plot_methods for plot() on the other
result classes, and tidy.ggcpt() for the tidy accessors.
Examples
set.seed(2022)
res <- cpt_detect(c(rnorm(50), rnorm(50, 5)), method = "pelt")
as_tibble(res)
as.data.frame(res)
format(res)
Base plot() methods for ggchangepoint result objects
Description
Every result class in the package has an autoplot() method, but
plot() is the reflex most users reach for first. Without a method,
plot() on a list-shaped result falls through to
plot.default and fails with 'x' is a list, but
does not have components 'x' and 'y', a message that names neither this
package nor autoplot(). These methods delegate to the corresponding
autoplot() method so that plot(result) draws the intended
figure.
Usage
## S3 method for class 'ggcpt_selection'
plot(x, ...)
## S3 method for class 'ggcpt_stability'
plot(x, ...)
## S3 method for class 'ggcpt_sensitivity'
plot(x, ...)
## S3 method for class 'ggcpt_influence'
plot(x, ...)
## S3 method for class 'ggcpt_batch'
plot(x, ...)
## S3 method for class 'ggcpt_benchmark'
plot(x, ...)
## S3 method for class 'ggcpt_consensus'
plot(x, ...)
## S3 method for class 'ggcpt_monitor'
plot(x, ...)
## S3 method for class 'ggcpt_delay'
plot(x, ...)
## S3 method for class 'ggcpt_path'
plot(x, ...)
## S3 method for class 'ggcpt_power'
plot(x, ...)
## S3 method for class 'ggcpt_effect'
plot(x, ...)
## S3 method for class 'ggcpt_robustness'
plot(x, ...)
## S3 method for class 'ggcpt_recommendation'
plot(x, ...)
## S3 method for class 'ggcpt_events'
plot(x, ...)
## S3 method for class 'ggcpt_label_curve'
plot(x, ...)
## S3 method for class 'ggcpt_attribution'
plot(x, ...)
## S3 method for class 'ggcpt_coverage'
plot(x, ...)
## S3 method for class 'ggcpt_counterfactual'
plot(x, ...)
## S3 method for class 'ggcpt_abruptness'
plot(x, ...)
## S3 method for class 'ggcpt_screen'
plot(x, ...)
## S3 method for class 'ggcpt_k_weights'
plot(x, ...)
Arguments
x |
A result object created by one of the package's |
... |
Passed to the corresponding |
Details
The plot is drawn as a side effect and the ggplot object is returned
invisibly, so plot() works inside a loop or a function while
p <- plot(result) still gives you the object to add layers to.
Value
The ggplot object, invisibly. Called for the side effect of
drawing the plot.
See Also
autoplot.ggcpt; ggcpt_methods for the
ggcpt class itself.
Examples
set.seed(2024)
x <- c(stats::rnorm(60), stats::rnorm(60, 4))
plot(cpt_select(x, method = "pelt", criterion = "bic", k_max = 4))
plot(cpt_crops(x, pen_min = 1, pen_max = 30))
# the object is still available to build on
p <- plot(cpt_stability(x, method = "pelt", B = 20, seed = 1))
p + ggplot2::labs(title = "Bootstrap stability")
Posterior probability plot for Bayesian results
Description
Draws the classic Bayesian changepoint display: the series with its
posterior mean (top panel) and the per-location posterior probability of
a changepoint (bottom panel). Works with results from
bcp_wrapper() and beast_wrapper().
Usage
ggcpt_posterior(x, prob_threshold = NULL)
Arguments
x |
A |
prob_threshold |
Probability cutoff drawn as a horizontal reference line in the probability panel; defaults to the threshold recorded on the object (or 0.5). |
Value
A ggplot object (two facets sharing the x axis).
Examples
res <- bcp_wrapper(c(rnorm(60), rnorm(60, 4)), seed = 2026)
ggcpt_posterior(res)
Run-length posterior heatmap for Bayesian online results
Description
Draws the signature BOCPD graphic: the posterior distribution of the run
length (time since the last changepoint) at every observation, as a
heatmap, with the series overlaid on top. Works with results from
bocpd_wrapper().
Usage
ggcpt_runlength(x, prob_floor = 0.001)
Arguments
x |
A |
prob_floor |
Posterior probabilities below this value are not drawn
(keeps the heatmap legible). Defaults to |
Value
A ggplot object.
Examples
res <- bocpd_wrapper(c(rnorm(60), rnorm(60, 4)))
ggcpt_runlength(res)
Plot for the changepoint package
Description
The plot for changepoints detected by the changepoint package is a line plot for the raw data and the vertical lines representing each changepoint. The x-axis is the row number of the raw data in the original data vector. The plot inherits ggplot2, meaning users can add ggplot2 functions on top the changepoint plot for customization.
Usage
ggcptplot(
data,
change_in = "mean_var",
cp_method = "PELT",
...,
cptline_alpha = 1,
cptline_color = "blue",
cptline_type = "solid",
cptline_linewidth = 0.5,
cptline_size = lifecycle::deprecated(),
index = NULL,
show_points = NULL,
show_line = TRUE
)
Arguments
data |
A numeric vector. |
change_in |
Choice of |
cp_method |
A wide range of choices (i.e., |
... |
Extra arguments for each |
cptline_alpha |
The value of alpha for the vertical changepoint line(s), default is 1, meaning no transparency. |
cptline_color |
The color for the vertical changepoint line(s), default
is |
cptline_type |
The linetype for the vertical changepoint line(s),
default is |
cptline_linewidth |
The linewidth for the vertical changepoint line(s),
default is |
cptline_size |
Deprecated. Use |
index |
Optional. A vector of x-axis labels (e.g. dates) of the same
length as |
show_points |
Logical. Whether to draw data points. Defaults to
|
show_line |
Logical. Whether to draw the line. Defaults to |
Value
A line plot with data points along with the vertical lines representing changepoints.
See Also
Other plotting:
ggcpt_compare_table(),
ggcpt_eval(),
ggcpt_interactive(),
ggecpplot()
Examples
ggcptplot(c(rnorm(100,0,1),rnorm(100,0,10)))
ggcptplot(c(rnorm(100,0,1),rnorm(100,10,1)))
Plot for the ecp package
Description
The plot for changepoints detected by the ecp package is a line plot for the raw data and the vertical lines representing each changepoint. The x-axis is the row number of the raw data in the original data vector. The plot inherits ggplot2, meaning users can add ggplot2 functions on top the changepoint plot for customization.
Usage
ggecpplot(
data,
algorithm = "divisive",
min_size = 2,
...,
cptline_alpha = 1,
cptline_color = "blue",
cptline_type = "solid",
cptline_linewidth = 0.5,
cptline_size = lifecycle::deprecated(),
index = NULL,
show_points = NULL,
show_line = TRUE
)
Arguments
data |
A numeric vector (for univariate) or matrix/data.frame (for multivariate). |
algorithm |
Either |
min_size |
Minimum number of observations between change points. By
default is 2. This argument is only applied when |
... |
Extra arguments to pass on either from |
cptline_alpha |
The value of alpha for the vertical changepoint line(s), default is 1, meaning no transparency. |
cptline_color |
The color for the vertical changepoint line(s), default
is |
cptline_type |
The linetype for the vertical changepoint line(s),
default is |
cptline_linewidth |
The linewidth for the vertical changepoint line(s),
default is |
cptline_size |
Deprecated. Use |
index |
Optional. A vector of x-axis labels (e.g. dates) of the same
length as |
show_points |
Logical. Whether to draw data points. Defaults to
|
show_line |
Logical. Whether to draw the line. Defaults to |
Value
A line plot with data points along with the vertical lines representing changepoints.
See Also
Other plotting:
ggcpt_compare_table(),
ggcpt_eval(),
ggcpt_interactive(),
ggcptplot()
Examples
ggecpplot(c(rnorm(100,0,1),rnorm(100,0,10)))
ggecpplot(c(rnorm(100,0,1),rnorm(100,10,1)))
Glance at a ggcpt object
Description
Returns a one-row summary of a changepoint detection result.
Usage
## S3 method for class 'ggcpt'
glance(x, ...)
Arguments
x |
A |
... |
Additional arguments (ignored). |
Details
total_cost is reported on whatever scale the engine itself uses, so
it is meaningful when comparing penalties within one method and not when
comparing one method against another. For the changepoint engines it
is the unpenalised -2\log L of the chosen segmentation. Four cases
there are NA rather than filled with a number that would not mean
the same thing:
-
"binseg"and"segneigh", whosecpt.rangefits report the raw within-segment cost instead: for one and the same segmentation that is 219.7 where a PELT fit reports 659.9; -
"np", because changepoint.np defines nologLikmethod; a change in mean under the default
"MBIC"penalty. Loading changepoint.np (which this package imports, so it is always loaded) replaces changepoint'slogLikmethod forcptobjects with one that errors on exactly that combination. Any other penalty ("BIC","AIC", a numeric value) reports normally, as dochange_in = "var"and"meanvar".
Value
A one-row tibble with columns: n, n_changepoints,
method, change_in, penalty_type, penalty_value,
cp_convention, total_cost (NA when the engine does
not expose a cost), runtime (elapsed seconds when measured by
cpt_detect(), otherwise NA) and engine_version
(the version of the engine package that produced the result, recorded
when it was made, or NA for a result with no engine package,
such as one built by as_ggcpt(); see
cpt_verify()) and family (the distribution family
the fit was asked for with cpt_detect(family = ), or NA
for the method's own default).
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(60), rnorm(60, 3)), method = "pelt")
glance(fit)
High-dimensional covariance changepoints
Description
Wraps changepoints::BS.cov() (Wang, Yu and Rinaldo): binary
segmentation on the sample covariance operator, which detects a change in
the dependence structure of a multivariate series even when every
marginal mean and variance is unchanged. No other engine in the package
can see that.
Usage
hdcov_wrapper(
x,
threshold = NULL,
alpha = 0.05,
n_perm = 20,
delta = NULL,
seed = NULL
)
Arguments
x |
A numeric matrix or data frame, rows as time points. |
threshold |
Detection threshold on the CUSUM statistic. When
|
alpha |
Family-wise level for the permutation threshold. Defaults to
|
n_perm |
Permutations used to calibrate the threshold. Defaults to
|
delta |
Minimum spacing between changepoints. Defaults to
|
seed |
Optional seed (the permutation calibration is random). The
seed is scoped to this call: |
Value
A ggcpt object with change_in = "covariance"; the
changepoints tibble carries the CUSUM statistic in cusum.
References
Wang D, Yu Y, Rinaldo A (2021). “Optimal covariance change point localization in high dimensions.” Bernoulli, 27(1), 554–575. doi:10.3150/20-BEJ1249.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
p <- 5
A <- matrix(rnorm(100 * p), ncol = p)
B <- matrix(rnorm(100 * p), ncol = p)
B[, 2] <- B[, 1] + 0.2 * B[, 2] # correlation appears
hdcov_wrapper(rbind(A, B), n_perm = 20, alpha = 0.05, seed = 1)
High-dimensional regression changepoints
Description
Wraps changepoints::CV.search.DP.regression() (Rinaldo, Wang, Wen,
Willett and Yu): dynamic programming with an \ell_0 penalty for
changes in the coefficient vector of a high-dimensional sparse regression,
with the two tuning parameters chosen by cross-validation. Where
strucchange_wrapper() dates breaks in a low-dimensional
regression by dynamic programming on the residual sum of squares, this
handles the case where there are more covariates than the segments have
observations to fit them with.
Usage
hdreg_wrapper(
x,
response = NULL,
gamma_set = NULL,
lambda_set = NULL,
delta = NULL,
...
)
Arguments
x |
A numeric matrix or data frame of covariates, rows as time points. |
response |
A numeric vector of responses, one per row of |
gamma_set |
Candidate values of the |
lambda_set |
Candidate lasso penalties. Defaults to
|
delta |
Minimum spacing. Defaults to |
... |
Additional arguments passed to the engine. |
Value
A ggcpt object with change_in = "regression". The
plotted series is the response, which is what a reader of a
regression-break plot expects to see.
References
Rinaldo A, Wang D, Wen Q, Willett R, Yu Y (2021). “Localizing changes in high-dimensional regression models.” In Proceedings of the 24th International Conference on Artificial Intelligence and Statistics, volume 130 of Proceedings of Machine Learning Research, 2089–2097.
See Also
var_wrapper(), strucchange_wrapper().
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
p <- 10
n <- 80
X <- matrix(stats::rnorm(n * p), n, p)
beta1 <- c(rep(2, 3), rep(0, p - 3))
beta2 <- c(rep(0, p - 3), rep(2, 3))
y <- c(X[1:40, ] %*% beta1, X[41:n, ] %*% beta2) + stats::rnorm(n)
hdreg_wrapper(X, response = y, gamma_set = c(1, 10),
lambda_set = c(0.1, 1))
Isolate-Detect wrapper
Description
Wraps the IDetect package. Requires the IDetect package.
Usage
idetect_wrapper(x, seed = NULL, ...)
Arguments
x |
A numeric vector. |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
... |
Additional arguments passed to |
Value
A ggcpt object. When the engine finds no changepoints
(including when it signals "No change-points found"), an empty result
is returned rather than an error. A constant series likewise returns the
empty result; see the note below.
Constant input
IDetect::ID() does not treat a flat series consistently: its
statistics become 0/0, and what comes back depends on the value and
the length. rep(3, 200) yields 126 changepoints, at
1, 3, 4, 6, 7, ...; rep(0, 100) raises "No change-points found";
rep(-2.5, 60) returns the sentinel 0. A constant series plainly has
no changepoint, and every other search wrapper here reports none, so this
one short-circuits to the empty result. Constancy is decided by exact
equality, so a series with tiny but genuine variation still reaches the
engine.
References
Anastasiou A, Fryzlewicz P (2022). “Detecting Multiple Generalized Change-Points by Isolating Single Ones.” Metrika, 85, 141–174. doi:10.1007/s00184-021-00821-6.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
idetect_wrapper(c(rnorm(60), rnorm(60, 4)))$changepoints
# a flat series has no changepoint; see "Constant input" above
nrow(idetect_wrapper(rep(3, 100))$changepoints)
inspect wrapper: high-dimensional changepoints via sparse projection
Description
Wraps InspectChangepoint::inspect() (Wang and Samworth, 2018). For
a p-variate series whose mean changes in an unknown sparse subset of
coordinates, the algorithm computes the CUSUM transformation, finds the
optimal sparse projection direction via a convex relaxation, and locates
changepoints on the projected univariate series, recursing via wild binary
segmentation.
Usage
inspect_wrapper(x, lambda = NULL, threshold = NULL, ...)
Arguments
x |
A numeric matrix or data frame with one row per time point and one column per coordinate. |
lambda |
Regularisation parameter of the sparse projection; when
|
threshold |
Detection threshold; when |
... |
Additional arguments passed to
|
Value
A ggcpt object. The changepoints tibble carries a
strength column (the maximum projected CUSUM statistic). The
first coordinate is used for cp_value and the univariate plot
line; the full matrix is kept for the faceted multivariate
autoplot(). Coordinates that are constant carry no changepoint
information and would make the engine's variance rescaling undefined, so
they are dropped (with a warning) before detection and an all-constant
matrix returns an empty result; the dropped coordinates are still kept
for plotting, and reported locations always refer to the original rows.
References
Wang T, Samworth RJ (2018). “High dimensional change point estimation via sparse projection.” Journal of the Royal Statistical Society: Series B, 80(1), 57–83.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- cbind(c(rnorm(80), rnorm(80, 3)), c(rnorm(80), rnorm(80, -2)),
rnorm(160))
res <- inspect_wrapper(X)
res$changepoints
Test if an object is a ggcpt object
Description
A class check, useful when a function accepts either a detection result or
the raw series. It tests for ggcpt in the class vector, so a
genuine ggcpt subclass (ggcpt_consensus is the one)
returns TRUE. The other ggcpt_* classes in the package
(ggcpt_batch, ggcpt_benchmark, ggcpt_monitor,
ggcpt_selection and the rest) are not subclasses of
ggcpt (most are tibble subclasses) and return
FALSE.
Usage
is_ggcpt(x)
Arguments
x |
An object to test. |
Value
TRUE if x inherits from ggcpt.
See Also
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
new_ggcpt(),
print.ggcpt()
Examples
set.seed(2026)
fit <- cpt_detect(c(rnorm(40), rnorm(40, 4)), method = "pelt")
is_ggcpt(fit)
is_ggcpt(fit$changepoints)
Kernel changepoint wrapper (KCP on running statistics)
Description
Wraps kcpRS::kcpRS() (Cabrieto et al., 2018; the KCP framework of
Arlot, Celisse and Harchaoui, 2019). The data are mapped to a running
statistic (mean, variance, autocorrelation, or correlation) computed on a
sliding window, and a Gaussian-kernel change point analysis with a
permutation significance test is run on the statistic. Detecting changes
in running correlations or variances captures higher-order changes that
mean-based methods miss. Multivariate input (matrix or data frame) is
supported.
Usage
kcp_wrapper(
x,
running_stat = c("mean", "var", "autocorr", "corr"),
wsize = 25,
nperm = 1000,
kmax = 10,
alpha = 0.05,
seed = NULL,
...
)
Arguments
x |
A numeric vector, matrix, or data frame (columns are variables). |
running_stat |
Which running statistic to monitor: |
wsize |
Sliding window size for the running statistic. Defaults to
|
nperm |
Number of permutations for the significance test, at least 2.
Defaults to |
kmax |
Maximum number of changepoints considered. Defaults to
|
alpha |
Significance level of the permutation test. Defaults to
|
seed |
Optional seed for reproducibility of the permutation test.
The seed is scoped to this call: |
... |
Additional arguments passed to |
Value
A ggcpt object. Reported locations refer to the centre of
the sliding window in which the change occurs. The series must be at
least wsize long to form one window. Constant coordinates make
every running statistic NA, so they are dropped (with a warning)
before detection and an all-constant input returns an empty result.
References
Arlot S, Celisse A, Harchaoui Z (2019). “A kernel multiple change-point algorithm via model selection.” Journal of Machine Learning Research, 20(162), 1–56.
Cabrieto J, Adolf J, Tuerlinckx F, Kuppens P, Ceulemans E (2018). “Detecting long-lived autodependency changes in a multivariate system via change point detection and regime switching models.” Scientific Reports, 8, 15637.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
res <- kcp_wrapper(c(rnorm(60), rnorm(60, 3)), nperm = 100, seed = 2026)
res$changepoints
Robust depth-based changepoints for functional and multivariate data
Description
Wraps KWCChangepoint (Ramsay and Chenouri): the functional Kruskal-Wallis covariance test, which ranks observations by statistical depth and segments on the ranks. Because it never touches the values themselves it is insensitive to heavy tails and outlying curves, which is exactly where the moment-based functional tests degrade.
Usage
kwc_wrapper(
x,
algorithm = c("fkwc", "dwbs"),
depth = NULL,
change_in = c("covariance", "distribution"),
seed = NULL,
...
)
Arguments
x |
A numeric matrix or data frame with one row per observation (time point) and one column per grid location or coordinate. |
algorithm |
|
depth |
Depth function. For |
change_in |
Reported change type: |
seed |
Optional seed: the random-projection depths and the wild
binary segmentation both randomise. The seed is scoped to this call:
|
... |
Additional arguments passed to the engine. |
Value
A ggcpt object. Multivariate input is
reduced to one series per observation by taking the
cross-sectional mean of the columns, and that is the series stored on
the result: autoplot() draws it, tidy()'s
cp_value reads it, and $segments$param_estimate and
augment()'s .fitted/.resid are computed from it.
It is not any one column of the input. The full input is kept in
$data_wide for autoplot(type = "coordinates").
References
Ramsay K, Chenouri S (2025). “Robust changepoint detection in the variability of multivariate functional data.” Journal of Nonparametric Statistics. doi:10.1080/10485252.2025.2503891.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- matrix(rnorm(100 * 20), nrow = 100)
X[51:100, ] <- X[51:100, ] * 3
kwc_wrapper(X, seed = 1)
Bayesian formula-based changepoint regression (mcp)
Description
Wraps mcp::mcp() (Lindeløv): a Bayesian multiple-changepoint
regression specified as a list of formulas, one per segment. This
is the most expressive detector in the package: each segment can have its
own intercept, slope, variance and autocorrelation, and the changepoints
themselves get full posterior distributions rather than point estimates,
summarised here as ci_lower/ci_upper on the changepoints
tibble. (ggcpt_posterior() draws a per-location
probability profile, which only bcp and Rbeast expose; it
does not accept an mcp result.)
Usage
mcp_wrapper(
x,
change_in = c("mean", "slope", "var"),
n_changepoints = 1,
model = NULL,
prior = list(),
iter = 3000,
adapt = 1000,
chains = 3,
seed = NULL,
...
)
Arguments
x |
A numeric vector. |
change_in |
Shorthand for the segment model when |
n_changepoints |
Number of changepoints in the shorthand model.
Defaults to |
model |
An explicit mcp model: a list of formulas. Overrides
|
prior |
Optional named list of priors, passed to |
iter, adapt, chains |
Sampler settings, passed through. |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries the
posterior mean location together with ci_lower/ci_upper
from the posterior quantiles, each converted from mcp's
continuous cp_1, cp_2, ... to the last observation
before the change (ceiling(cp) - 1, because mcp starts a
segment at x >= cp), and $data$fitted holds the
posterior predictive mean, so autoplot(show_ci = TRUE,
show_fit = TRUE) shows both.
JAGS is a system dependency
mcp samples through JAGS, a separate program installed outside R.
Having the package is not the same as being able to run it:
mcp imports rjags, and on some platforms rjags
installs happily and only fails when it looks for the JAGS library at run
time, in which case mcp::mcp() returns a fit carrying no
posterior samples, with a warning rather than an error. This wrapper
checks for that and says so plainly instead of failing several frames
later inside summary(). Everything else in the package works
without JAGS.
References
Lindeløv JK (2020). “mcp: An R package for regression with multiple change points.” OSF Preprints. doi:10.31219/osf.io/fzqxv.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
# Not run by R CMD check: whether this works depends on a *system*
# library, and no test of installed R packages predicts that reliably --
# `rjags` can be present and still fail to find JAGS at run time.
## Not run:
set.seed(2026)
fit <- mcp_wrapper(c(rnorm(60), rnorm(60, 4)), iter = 500, adapt = 200)
fit
## End(Not run)
MOSUM wrapper: Moving Sum
Description
Wraps the mosum package for moving-sum-based changepoint
detection, either at a single bandwidth or (with
multiscale = TRUE) across a bandwidth grid with localised pruning.
Usage
mosum_wrapper(x, G = NULL, multiscale = FALSE, seed = NULL, ...)
Arguments
x |
A numeric vector. |
G |
Bandwidth. If |
multiscale |
Logical. Use the multiscale MOSUM procedure
( |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
... |
Additional arguments passed to |
Value
A ggcpt object.
References
Eichinger B, Kirch C (2018). “A MOSUM Procedure for the Estimation of Multiple Random Change Points.” Bernoulli, 24(1), 526–564. doi:10.3150/16-BEJ887.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 3))
mosum_wrapper(x, G = 20)$changepoints
mosum_wrapper(x, multiscale = TRUE)$changepoints
Dynamic-network changepoints
Description
Wraps changepoints::WBS.network() (Yu, Padilla, Wang and Rinaldo):
wild binary segmentation on a sequence of networks, detecting the times at
which the edge-probability structure changes. The input is one row per
time point holding the vectorised adjacency matrix, so a series of
p \times p networks over n times is an n \times p^2
matrix.
Usage
network_wrapper(
x,
copy2 = NULL,
n_intervals = 100,
threshold = NULL,
alpha = 0.05,
n_perm = 20,
delta = NULL,
seed = NULL
)
Arguments
x |
The network sequence: an |
copy2 |
An independent second observation of the same network sequence, in the same shape. The method's guarantees rest on sample splitting; see the section below for what happens when there is only one copy. |
n_intervals |
Number of random intervals. Defaults to |
threshold |
Detection threshold. When |
alpha, n_perm |
Level and number of permutations for that calibration. |
delta |
Minimum spacing. Defaults to |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A ggcpt object with change_in = "network". The
series it carries (and so the one autoplot() draws) is the
mean edge weight at each time point, rowMeans() of the
vectorised adjacency matrices. This is the one multivariate method with
no data_wide slot: a p \times p network has p^2
entries per time point, so a facet per coordinate would be unreadable.
The changepoints are estimated from the networks themselves, not from
the summary.
When you have only one copy of the network
WBS.network() takes two independent observations of the sequence,
which is how the theory controls the bias of the squared-Frobenius
statistic. Given a single sequence of binary networks this wrapper
constructs the second copy by splitting each edge indicator at random
(each present edge is assigned to one copy with probability one half),
which is the usual independent-thinning device and is reported in a
message. For weighted networks it splits the weight instead, which is
exact for Poisson weights and approximate otherwise. If you have a genuine
replicate, pass it as copy2 and none of this applies.
References
Yu Y, Padilla OHM, Wang D, Rinaldo A (2021). “Optimal network online change point localisation.” arXiv preprint arXiv:2101.05477. doi:10.48550/arXiv.2101.05477.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
p <- 5
mk <- function(n, prob) {
t(replicate(n, as.numeric(matrix(stats::rbinom(p * p, 1, prob), p))))
}
X <- rbind(mk(40, 0.2), mk(40, 0.6))
network_wrapper(X, n_intervals = 20, n_perm = 20, seed = 1)
Create a ggcpt object
Description
The low-level constructor for the class every detector in this package
returns. It assembles the components into a ggcpt without checking
them, which is what makes it useful inside a wrapper and unsuitable as the
entry point for hand-built input; use as_ggcpt() for that.
Usage
new_ggcpt(
changepoints = tibble::tibble(cp = integer(), cp_value = numeric()),
segments = tibble::tibble(seg_id = integer(), start = integer(), end = integer(), n =
integer(), param_estimate = numeric()),
data = tibble::tibble(index = integer(), value = numeric()),
method = NA_character_,
change_in = NA_character_,
penalty = list(type = NA_character_, value = NA_real_),
fit = NULL,
call = NULL,
cp_convention = "left",
runtime = NA_real_
)
Arguments
changepoints |
A tibble with columns |
segments |
A tibble with segment information: |
data |
A tibble with |
method |
Character. The detection method used. A length-one string;
defaults to |
change_in |
Character. What was detected (e.g. "mean", "var",
"meanvar"). A length-one string; defaults to |
penalty |
A list with |
fit |
The raw upstream object. Every wrapper stores one except
|
call |
The matched call. |
cp_convention |
Character. The convention for reporting changepoint
locations: |
runtime |
Numeric. Elapsed detection time in seconds, if measured.
Defaults to |
Value
An object of class ggcpt, holding exactly the
components passed in (documented one by one above) plus any of the
optional slots listed below. Nothing is validated or derived:
as_ggcpt() is the constructor that does both.
Optional slots
Beyond the components in the signature, a ggcpt may carry any of
these, each present only when something supplied it and each safe to test
for with is.null():
data_wideindex plus one column per coordinate, for a multivariate result.
index,index_labela time index (one value per observation) and its axis label; see the
indexargument ofcpt_detect().regionsa tibble of significance regions (
start,end, ...) for the interval-valued methods; seensp_wrapper()andgeom_cpt_region().diagnosticsa named list of engine internals rendered by
ggcpt_statistic(),ggcpt_solution_path()andggcpt_scale_space().registeredTRUEwhen the result came from a user-registered detector rather than a wired engine.
as_ggcpt() is the validating way to build one of these from
the outside; this constructor does not check its arguments.
See Also
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
print.ggcpt()
Examples
set.seed(2026)
new_ggcpt(
changepoints = tibble::tibble(cp = 50L, cp_value = 0.1),
data = tibble::tibble(index = 1:100,
value = c(rnorm(50), rnorm(50, 4))),
method = "manual", change_in = "mean")
NOT wrapper: Narrowest-Over-Threshold
Description
Wraps the not package for changepoint detection via the
Narrowest-Over-Threshold method. The contrast determines what change is
detected: piecewise-constant mean (default), mean and variance, or
(continuous or discontinuous) piecewise-linear trend.
Usage
not_wrapper(x, contrast = "pcwsConstMean", seed = NULL, ...)
Arguments
x |
A numeric vector. |
contrast |
Contrast type. One of |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
... |
Additional arguments passed to |
Value
A ggcpt object whose change_in reflects the
contrast: "mean", "meanvar", or "slope".
References
Baranowski R, Chen Y, Fryzlewicz P (2019). “Narrowest-Over-Threshold Detection of Multiple Change Points and Change-Point-Like Features.” Journal of the Royal Statistical Society Series B, 81(3), 649–672. doi:10.1111/rssb.12322.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
not_wrapper(c(rnorm(60), rnorm(60, 4)))$changepoints
# a change in slope, not in level: pick the contrast to match
trend <- c(1:60, 60 - 1:60) / 10 + rnorm(120)
not_wrapper(trend, contrast = "pcwsLinContMean")$changepoints
Nonparametric MOSUM wrapper (NP-MOJO)
Description
Wraps CptNonPar::np.mojo() (McGonigle and Cho, 2025): nonparametric
moving-sum detection of changes in the marginal or joint distribution of a
(possibly multivariate) time series, robust to serial dependence.
Usage
npmojo_wrapper(x, G = NULL, lag = 0, ...)
Arguments
x |
A numeric vector or matrix (rows are time points). |
G |
Moving-window bandwidth. Defaults to |
lag |
Time lag at which changes in the joint distribution are
examined; |
... |
Additional arguments passed to |
Value
A ggcpt object. Constant coordinates leave the kernel
statistics undefined, so they are dropped (with a warning) before
detection and an all-constant input returns an empty result. The
engine calibrates its detection threshold by bootstrap, so the value
recorded in the penalty descriptor varies between runs; call
set.seed() beforehand, or pass threshold = "manual" and
threshold.val through ..., for a reproducible one.
References
McGonigle ET, Cho H (2025). “Nonparametric data segmentation in multivariate time series via joint characteristic functions.” Biometrika, 112(2), asaf024.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
res <- npmojo_wrapper(c(rnorm(100), rnorm(100, 3)))
res$changepoints
NSP wrapper: Narrowest Significance Pursuit
Description
Wraps the nsp package (Fryzlewicz 2024). NSP inverts the usual
framing of post-selection inference: rather than estimating changepoint
locations and then asking whether they are real, it returns a set of
intervals, each of which contains at least one changepoint, with
the guarantee holding globally across all intervals simultaneously
at level alpha. The guarantee is exact and finite-sample, and the
self-normalised and autoregressive variants keep it under heavy tails,
heteroscedasticity and serial dependence.
Usage
nsp_wrapper(
x,
alpha = 0.1,
variant = c("poly", "selfnorm", "ar", "tvreg"),
change_in = c("mean", "slope"),
deg = NULL,
M = 1000,
covariates = NULL,
ord = 1,
seed = NULL,
...
)
Arguments
x |
A numeric vector. |
alpha |
Global significance level: with probability at least
|
variant |
Which NSP procedure to run:
|
change_in |
|
deg |
Degree of the piecewise polynomial. Derived from
|
M |
Number of intervals drawn. Defaults to |
covariates |
A design matrix for |
ord |
AR order for |
seed |
Optional seed. NSP draws random intervals, so a run is
reproducible only with one. The seed is scoped to this call:
|
... |
Additional arguments passed to the underlying nsp function. |
Value
A ggcpt object with a populated regions slot.
What cp means here, and what it does not
NSP produces no point estimates. This wrapper still fills the cp
column (with the midpoint of each interval) because every
downstream consumer in the package (augment(),
cpt_metrics(), cpt_consensus(),
autoplot()) is built on that column, and a result with an empty
cp would silently score as "found nothing". The midpoint is
not an estimate of the changepoint location and must not be
reported as one: the interval is the inferential object. The result
therefore
carries the intervals in a
regionsslot, read withcpt_regions();marks itself, so
print()says thecpcolumn is a midpoint andautoplot()shades the bands by default;adds a
cp_sourcecolumn reading"region_midpoint"to the changepoints tibble.
References
Fryzlewicz P (2024). “Narrowest significance pursuit: inference for multiple change-points in linear models.” Journal of the American Statistical Association, 119(546), 1633–1646. doi:10.1080/01621459.2023.2211733.
See Also
cpt_regions(), geom_cpt_region(),
cpt_confint().
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 4))
fit <- nsp_wrapper(x, M = 100, seed = 1)
cpt_regions(fit)
ggplot2::autoplot(fit)
ocd wrapper: online high-dimensional changepoint detection
Description
Wraps the ocd package (Chen, Wang and Samworth, 2022): online
multiscale detection of a mean change in a high-dimensional stream, with
worst-case detection-delay guarantees and per-observation cost independent
of history. The detector assumes standardised data with known pre-change
mean; this wrapper estimates the baseline mean and standard deviation
from an initial training window, then monitors the remainder of the
series, resetting after each declaration so multiple changes can be
found.
Usage
ocd_wrapper(
x,
train = NULL,
thresh = "MC",
patience = 5000,
beta = 1,
mc_reps = 100,
...
)
Arguments
x |
A numeric matrix or data frame with one row per time point and at
least two columns. The |
train |
Number of initial observations used to estimate the baseline
mean/sd (not monitored). Defaults to
|
thresh |
Threshold specification passed to
|
patience |
Target average run length to false alarm. Defaults to
|
beta |
Assumed lower bound on the squared Euclidean norm of the mean
change. Defaults to |
mc_reps |
Monte Carlo repetitions for threshold calibration.
Defaults to |
... |
Additional arguments passed to
|
Value
A ggcpt object. Because the detector is online, it
declares a change without estimating where it began. cp is the
declaration time minus one: the latest changepoint consistent
with the alarm in this package's convention (the last observation
before the change), and exact when the change is declared on the first
observation after it; a later declaration makes cp late by the
detection delay. The declared_at column holds the declaration
time itself. (Before 0.6.0 cp was the declaration time, one
position late even at zero delay, which the convention test found.)
Compare cpm_wrapper(), whose engine estimates the
location separately from its detection_time.
How long this takes
Nearly all of the run time is ocd's Monte Carlo threshold
calibration, which happens before a single observation is read. It is
linear in mc_reps and grows with the number of coordinates. Timed
on one Linux x86-64 machine at mc_reps = 5, construction took
about 10 s at p = 3, 22 s at p = 10 and 113 s at
p = 50; raising mc_reps scales it linearly, so at
p = 3 it was 38 s at mc_reps = 20 and 189 s at the default
mc_reps = 100. The practical reading is that the default costs
minutes rather than seconds even for a handful of coordinates,
and better than half an hour at p = 50. Another machine will give
different absolute numbers; the linearity in mc_reps is the part
to plan around. Monitoring the observations afterwards is cheap by
comparison: 0.37 s for a thousand of them at p = 3. Lower
mc_reps while exploring (the example below uses 2, which
measures 3.8 s), or pass thresh directly to skip
calibration entirely, which brings the same fit down to a tenth of a
second.
References
Chen Y, Wang T, Samworth RJ (2022). “High-dimensional, multiscale online changepoint detection.” Journal of the Royal Statistical Society: Series B, 84(1), 234–266.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- rbind(matrix(rnorm(60 * 3), 60), matrix(rnorm(40 * 3, 3), 40))
# `mc_reps = 2`, not the default 100 and not the 5 this example used to
# pass: the calibration is linear in `mc_reps` and is nearly all of the
# cost, so 5 measured 9.7 s here against CRAN's 5 s budget and 2
# measures 3.8 s for the same answer. Neither is a calibration you
# would trust (see the timing section above).
res <- ocd_wrapper(X, mc_reps = 2)
res$changepoints
Pilliat wrapper: high-dimensional detection by three complementary tests
Description
Wraps HDCD::Pilliat() (Pilliat, Carpentier and Verzelen, 2023): a
high-dimensional mean-change procedure combining a dense test, a
Berk-Jones test and a partial-sum test, so it is powerful across sparsity
regimes without estimating the sparsity level. A useful cross-check on
esac_wrapper(): the two adapt differently and disagreeing
answers are informative.
Usage
pilliat_wrapper(
x,
threshold_d_const = 4,
threshold_bj_const = 6,
threshold_partial_const = 4,
empirical = FALSE,
N = 100,
seed = NULL,
...
)
Arguments
x |
A numeric matrix or data frame with rows as time points and columns as coordinates. |
threshold_d_const, threshold_bj_const, threshold_partial_const |
Leading constants of the dense, Berk-Jones and partial-sum thresholds. |
empirical |
Calibrate the thresholds by Monte Carlo rather than using
the theoretical values? Slower but sharper; defaults to |
N |
Monte Carlo samples when |
seed |
Optional seed (used by the empirical calibration). The seed
is scoped to this call: |
... |
Additional arguments passed to |
Value
A ggcpt object.
Dimension precondition
HDCD 1.1's Pilliat() builds one fewer partial-sum threshold
than it uses whenever the number of coordinates is an exact power of two,
so the C routine reads past the end of that vector and the engine reports
a changepoint at every observation, on pure noise as readily as on
a real change. This wrapper refuses those dimensions rather than returning
the result, because it is wrong in a way that looks like a finding.
esac_wrapper() is unaffected at every dimension. Note that
constant coordinates are dropped before the count, so 9 coordinates one of
which is constant is 8 for this purpose.
The same reasoning makes this the one engine that errors on a
degenerate segmentation (a changepoint at more than 90% of
observations) where every other engine in the package warns and reports
what it found. That has a consequence for comparisons:
cpt_batch() and cpt_benchmark() record a
failure row for pilliat where the same output from pelt
gives a result plus a warning, so a benchmark table is not scoring the
two on equal terms in that case; read the error column
alongside the metrics.
References
Pilliat E, Carpentier A, Verzelen N (2023). “Optimal multiple change-point detection for high-dimensional data.” Electronic Journal of Statistics, 17(1), 1240–1315. doi:10.1214/23-EJS2126.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
X <- matrix(rnorm(100 * 20), nrow = 100)
X[51:100, 1:5] <- X[51:100, 1:5] + 3
pilliat_wrapper(X)
Forecast from a segment of a segmentation
Description
The point of detecting a regime change is usually that the earlier
regime should no longer inform what happens next. predict() on a
ggcpt forecasts from one segment only (by default the last), with
the segment's own model.
Usage
## S3 method for class 'ggcpt'
predict(
object,
newdata = NULL,
h = 1,
segment = "last",
models = NULL,
level = 0.95,
...
)
Arguments
object |
A |
newdata |
Optional data frame of covariates (for a formula fit, or a
segment model with covariates), or of |
h |
Forecast horizon, when |
segment |
Which segment to forecast from: |
models |
Optional |
level |
Level of the prediction interval. Defaults to |
... |
Further arguments for the model's |
Value
A tibble with time (when forecasting by horizon),
.pred, and .lower/.upper when the model supplies
a prediction interval.
See Also
Other segment models:
cpt_counterfactual(),
cpt_segment_models()
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(100), rnorm(100, 3)), method = "pelt")
predict(fit, h = 3)
Print a ggcpt object
Description
A compact header (method, what changed, how many changepoints, the
convention their locations follow, the penalty and the series length)
followed by the first ten changepoints. For the segment table and the
fitted parameters use summary(); for the changepoints
as data use tidy().
Usage
## S3 method for class 'ggcpt'
print(x, ...)
Arguments
x |
A |
... |
Additional arguments (ignored). |
Value
x, invisibly. Called for the side effect of printing.
See Also
summary.ggcpt(), tidy.ggcpt().
Other result class:
annotate_segments(),
as_cpt_series(),
as_ggcpt(),
as_json(),
cpt_annotations(),
cpt_export(),
cpt_verify(),
ggchangepoint-conditions,
is_ggcpt(),
new_ggcpt()
Examples
set.seed(2026)
print(cpt_detect(c(rnorm(40), rnorm(40, 4)), method = "pelt"))
Objects exported from other packages
Description
These objects are imported from other packages. Follow the links below to see their documentation.
Colour-vision-safe scales for changepoint methods
Description
The discrete palette used wherever this package colours by method, series or class. It is the Okabe-Ito qualitative palette, which stays distinguishable under deuteranopia, protanopia and tritanopia, extended by recycling with a linetype change so that colour is never the only channel carrying the distinction.
Usage
scale_colour_cpt(..., na.value = "grey70")
scale_color_cpt(..., na.value = "grey70")
scale_fill_cpt(..., na.value = "grey70")
scale_linetype_cpt(...)
Arguments
... |
Passed to |
na.value |
Colour for missing values. |
Value
A ggplot2 scale.
See Also
theme_ggcpt(),
scale_fill_cpt_label().
Other accessibility scales:
scale_fill_cpt_label(),
theme_ggcpt()
Examples
library(ggplot2)
ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) +
geom_point() + scale_colour_cpt() + theme_ggcpt()
Colour scales for changepoint labels and label errors
Description
A colour-vision-deficiency-safe fill scale covering both vocabularies the
supervised-detection displays use: the label's assertion
(change / no_change / one_change) and the outcome of
scoring a segmentation against it (correct / false_positive
/ false_negative). Unknown values fall back to grey rather than
erroring, so a partially-scored frame still plots.
Usage
scale_fill_cpt_label(..., na.value = "grey70")
scale_colour_cpt_label(..., na.value = "grey70")
Arguments
... |
Passed to |
na.value |
Fill for values outside the vocabulary. |
Value
A ggplot2 scale.
See Also
Other accessibility scales:
scale_colour_cpt(),
theme_ggcpt()
Examples
library(ggplot2)
labs <- cpt_labels(c(40, 70), c(60, 90), c("change", "no_change"))
ggplot(labs, aes(xmin = start, xmax = end, ymin = 0, ymax = 1,
fill = change)) +
geom_rect() + scale_fill_cpt_label()
# the same palette covers correct / false_positive / false_negative
class(scale_colour_cpt_label())
Broken-line regression wrapper (segmented)
Description
Wraps segmented::segmented() (Muggeo, 2003, 2008): maximum
likelihood estimation of continuous piecewise-linear
("broken-line") regressions, with standard errors and confidence
intervals for the breakpoint locations. Where the step-change engines
model jumps in the level, segmented models kinks in the trend, so
change_in is "slope" and the fitted broken line is stored in
the fitted column for autoplot(show_fit = TRUE).
Usage
segmented_wrapper(
x,
npsi = 1,
conf_level = 0.95,
seed = NULL,
data = NULL,
seg_z = NULL,
family = c("gaussian", "poisson", "binomial"),
...
)
Arguments
x |
A numeric vector (a line in time is segmented), or a model
formula (supply |
npsi |
Number of breakpoints to estimate. Defaults to |
conf_level |
Confidence level for breakpoint intervals. Defaults to
|
seed |
Optional seed (the estimator uses bootstrap restarting). The
seed is scoped to this call: |
data |
A data frame, for formula input. |
seg_z |
For formula input, the covariate whose relationship with
the response breaks: its name, or a one-sided formula ( |
family |
|
... |
Additional arguments passed to |
Details
Called with a numeric vector it segments a line in time. Called with a
formula and data it does what the engine exists for: breakpoints
in the relationship between the response and a covariate,
seg_z. The result is then ordered by that covariate, which
becomes its index, so tidy()'s cp_index and the plot speak
in the covariate's units, and psi, psi_lower and
psi_upper give the breakpoints on that scale exactly.
Value
A ggcpt object with ci_lower/ci_upper columns
and the fitted broken line in $data$fitted. Breakpoints are
rounded to the nearest index; for a continuous fit the reported location
is the kink itself. A constant series has no kink and returns an empty
result, rather than the arbitrary breakpoint a singular fit would give.
Formula input adds psi, psi_lower and psi_upper
(the breakpoints on the covariate's scale) and a $coefficients
table with the slope of seg_z in each segment.
References
Muggeo VM (2003). “Estimating regression models with unknown break-points.” Statistics in Medicine, 22(19), 3055–3071.
Muggeo VM (2008). “segmented: An R package to fit regression models with broken-line relationships.” R News, 8(1), 20–25.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
y <- cumsum(c(rep(0.5, 100), rep(-0.3, 100))) + rnorm(200)
res <- segmented_wrapper(y, npsi = 1)
res$changepoints
ggplot2::autoplot(res, show_fit = TRUE, show_ci = TRUE)
# A breakpoint in a dose-response relationship
d <- data.frame(dose = runif(150, 0, 10))
d$response <- 2 + 0.8 * pmin(d$dose, 6) + rnorm(150, 0, 0.4)
fit <- segmented_wrapper(response ~ dose, data = d)
fit$changepoints[, c("cp", "psi", "psi_lower", "psi_upper")]
Blocks test signal
Description
The classic Donoho-Johnstone blocks test signal with known changepoints.
Usage
signal_blocks(n = 2048, seed = NULL)
Arguments
n |
Length of the signal. Defaults to 2048. |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A tibble with columns index and value. The true_changepoints
attribute contains the known changepoint locations.
References
Donoho, D. L. and Johnstone, I. M. (1994). Ideal spatial adaptation by wavelet shrinkage. Biometrika, 81(3), 425-455.
See Also
Other test signals:
cpt_simulate(),
signal_fms(),
signal_mix(),
signal_stairs(),
signal_teeth()
Examples
x <- signal_blocks(seed = 2026)
attr(x, "true_changepoints")
# PELT recovers all eleven Donoho-Johnstone jumps
cpt_detect(x$value, method = "pelt")$changepoints$cp
FMS (Four-Metric-Segments) test signal
Description
A piecewise-constant test signal from the WBS/NOT literature.
Usage
signal_fms(n = 2000, seed = NULL)
Arguments
n |
Length of the signal. Defaults to 2000. |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A tibble with columns index and value.
See Also
Other test signals:
cpt_simulate(),
signal_blocks(),
signal_mix(),
signal_stairs(),
signal_teeth()
Examples
x <- signal_fms(seed = 2026)
cp <- cpt_detect(x$value, method = "pelt")$changepoints$cp
# the smallest jumps (0.5, against noise sd 0.5) are the ones missed
cpt_metrics(cp, attr(x, "true_changepoints"), n = nrow(x))$covering
Mix test signal
Description
A piecewise-constant/linear signal from the literature.
Usage
signal_mix(n = 2000, seed = NULL)
Arguments
n |
Length of the signal. Defaults to 2000. |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A tibble with columns index and value.
See Also
Other test signals:
cpt_simulate(),
signal_blocks(),
signal_fms(),
signal_stairs(),
signal_teeth()
Examples
x <- signal_mix(seed = 2026)
attr(x, "true_changepoints")
# the linear ramps are not level shifts, so a mean-change detector puts
# changepoints inside them rather than at the segment joins
cpt_detect(x$value, method = "pelt")$changepoints$cp
Stairs test signal
Description
A monotonically stepping signal (staircase).
Usage
signal_stairs(n = 2000, seed = NULL)
Arguments
n |
Length of the signal. Defaults to 2000. |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A tibble with columns index and value.
See Also
Other test signals:
cpt_simulate(),
signal_blocks(),
signal_fms(),
signal_mix(),
signal_teeth()
Examples
x <- signal_stairs(n = 500, seed = 2026)
attr(x, "true_changepoints") # ten steps, so nine changes
cpt_detect(x$value, method = "pelt")$changepoints$cp
Teeth test signal
Description
A piecewise-constant signal with regularly spaced changepoints.
Usage
signal_teeth(n = 2000, seed = NULL)
Arguments
n |
Length of the signal. Defaults to 2000. |
seed |
Optional seed. The seed is scoped to this call:
|
Value
A tibble with columns index and value.
See Also
Other test signals:
cpt_simulate(),
signal_blocks(),
signal_fms(),
signal_mix(),
signal_stairs()
Examples
x <- signal_teeth(n = 600, seed = 2026)
attr(x, "true_changepoints") # a change every 100 observations
cpt_detect(x$value, method = "pelt")$changepoints$cp
SMUCE / HSMUCE wrapper: multiscale changepoint inference
Description
Wraps stepR::stepFit() for the Simultaneous MUltiscale Changepoint
Estimator (SMUCE) of Frick, Munk and Sieling (2014) and its heterogeneous
extension HSMUCE (Pein, Sieling and Munk, 2017). SMUCE estimates a step
function subject to a simultaneous multiscale test at level alpha;
the level bounds the probability of over-estimating the number of
changepoints, and the fit delivers confidence intervals for every
changepoint location, which populate the ci_lower/ci_upper
columns of the result and render via autoplot(show_ci = TRUE) or
geom_cpt_ci().
Usage
smuce_wrapper(
x,
alpha = 0.5,
family = c("gauss", "hsmuce", "poisson", "binomial"),
...
)
Arguments
x |
A numeric vector. |
alpha |
Significance level of the multiscale test in |
family |
Noise model: |
... |
Additional arguments passed to |
Value
A ggcpt object. The changepoints tibble carries
ci_lower/ci_upper (confidence interval for each
changepoint location) and the data tibble carries the SMUCE step
fit in its fitted column.
References
Frick K, Munk A, Sieling H (2014). “Multiscale change point inference.” Journal of the Royal Statistical Society: Series B, 76(3), 495–580.
Pein F, Sieling H, Munk A (2017). “Heterogeneous change point inference.” Journal of the Royal Statistical Society: Series B, 79(4), 1207–1227.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(100), rnorm(100, 3))
res <- smuce_wrapper(x)
res$changepoints
ggplot2::autoplot(res, show_ci = TRUE)
Self-normalisation wrapper (SNSeg)
Description
Wraps SNSeg::SNSeg_Uni() (Zhao, Jiang and Shao, 2022):
self-normalised segmentation with nested local windows. Self-normalisation
avoids estimating the long-run variance, is robust to temporal dependence,
and detects changes in general parameters (mean, variance, quantiles,
autocorrelation, or bivariate correlation) within one framework.
Usage
sn_wrapper(
x,
parameter = c("mean", "variance", "acf", "bivcor"),
confidence = 0.9,
grid_size = NULL,
...
)
Arguments
x |
A numeric vector (or a two-column matrix for
|
parameter |
Which parameter to test for changes: |
confidence |
Confidence level of the self-normalised test, one of
0.9, 0.95, 0.99, 0.995 or 0.999. Defaults to |
grid_size |
Grid size controlling the local-window sweep; when
|
... |
Additional arguments passed to |
Value
A ggcpt object. About 20 observations are needed for the
nested local windows at the default grid_size; a constant series
returns an empty result rather than an engine error.
References
Zhao Z, Jiang F, Shao X (2022). “Segmenting time series via self-normalisation.” Journal of the Royal Statistical Society: Series B, 84(5), 1699–1725.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- sn_wrapper(c(rnorm(150), rnorm(150, 3)))
res$changepoints
Changepoint detection stat
Description
Runs changepoint detection inside the ggplot pipeline. Useful for
quick exploration: ggplot(df, aes(t, y)) + geom_line() +
stat_changepoint(method = "pelt"). Draws vertical lines at detected
changepoint locations.
Usage
stat_changepoint(
mapping = NULL,
data = NULL,
geom = "vline",
position = "identity",
...,
method = "pelt",
change_in = "mean",
na.rm = FALSE,
show.legend = NA
)
Arguments
mapping |
Aesthetic mappings. |
data |
A data frame. |
geom |
The geometric object to use (default: |
position |
Position adjustment. |
... |
Other arguments passed to the geom. |
method |
Detection method (passed to |
change_in |
What to detect change in (passed to |
na.rm |
If |
show.legend |
Whether to show legend. |
Value
A ggplot layer.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_cpt_region()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:100, y = c(rnorm(50), rnorm(50, 4)))
ggplot(d, aes(t, y)) + geom_line() +
stat_changepoint(method = "pelt", colour = "blue")
Significance regions computed in the layer
Description
The region twin of stat_changepoint(): runs detection on
the layer's own x/y and draws what the method returns as
an interval, so
ggplot(d, aes(t, y)) + geom_line() + stat_cpt_region() is the
whole plot. Narrowest Significance Pursuit (method = "nsp", the
default) returns regions, each containing a changepoint at a global
significance level; a method with location intervals ("smuce",
"strucchange", "segmented", ...) draws those instead.
Usage
stat_cpt_region(
mapping = NULL,
data = NULL,
geom = GeomCptRegion,
position = "identity",
...,
method = "nsp",
na.rm = FALSE,
show.legend = NA
)
Arguments
mapping |
Aesthetic mappings. |
data |
A data frame. |
geom |
The geom to draw with. Defaults to
|
position |
Position adjustment. |
... |
Further arguments: those the detector takes (for example
|
method |
Detection method: |
na.rm |
If |
show.legend |
Whether to show legend. |
Value
A ggplot layer.
See Also
Other ggplot2 layers:
geom_changepoint(),
geom_cpt_ci(),
geom_cpt_event(),
geom_cpt_label(),
geom_cpt_region(),
geom_cpt_segment(),
ggchangepoint-ggproto,
stat_changepoint()
Examples
library(ggplot2)
set.seed(2026)
d <- data.frame(t = 1:200, y = c(rnorm(100), rnorm(100, 2)))
ggplot(d, aes(t, y)) + stat_cpt_region(seed = 1) + geom_line()
Bai-Perron structural break wrapper (strucchange)
Description
Wraps strucchange::breakpoints() (Zeileis et al., 2002), the
dynamic-programming implementation of the Bai and Perron (1998, 2003)
multiple structural break estimator. Called with a bare numeric vector it
dates mean shifts (y ~ 1); called with a formula and data it dates
breaks in arbitrary regression coefficients. Break-date confidence
intervals from confint() populate ci_lower/ci_upper
and render via autoplot(show_ci = TRUE).
Usage
strucchange_wrapper(
x,
data = NULL,
breaks = NULL,
h = 0.15,
conf_level = 0.95,
...
)
Arguments
x |
A numeric vector (mean-shift mode), or a model formula
(regression mode; supply |
data |
Optional data frame for formula input. |
breaks |
Maximum number of breaks; when |
h |
Minimal segment size, as a fraction of the sample size (or an
integer count). Defaults to |
conf_level |
Confidence level for the break-date intervals. Defaults
to |
... |
Additional arguments passed to
|
Value
A ggcpt object with ci_lower/ci_upper columns
on the changepoints tibble.
Result size
$fit is the breakpoints object itself, and that object is
quadratic in the series length: it keeps RSS.triang, the triangular
table of segment residual sums of squares, which is what lets
strucchange return the optimal segmentation for any number
of breaks without refitting. Measured here, the whole result is about
1.7 MB at n = 200, 5.9 MB at n = 400 and 22.6 MB at
n = 800, roughly four times larger each time the series doubles,
and that one table outweighs everything else in the fit put together, by a
margin that widens as the series grows. A single fit is not a problem; a
few hundred of them are, so when running this engine over a panel with
cpt_batch() keep what you need
(res$changepoints) rather than the whole list of results. No other
engine here behaves this way: the median result across the others is
under ten times the size of the series it was given.
References
Bai J, Perron P (2003). “Computation and analysis of multiple structural change models.” Journal of Applied Econometrics, 18(1), 1–22.
Zeileis A, Leisch F, Hornik K, Kleiber C (2002). “strucchange: An R package for testing for structural change in linear regression models.” Journal of Statistical Software, 7(2), 1–38.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- strucchange_wrapper(c(rnorm(100), rnorm(100, 3)))
res$changepoints
Summary of a ggcpt object
Description
Provides a human-readable digest of a changepoint detection result,
including the segment table with levels and lengths (the level is the
segment mean whatever 'change_in' says; see new_ggcpt),
total cost,
penalty, and runtime.
Usage
## S3 method for class 'ggcpt'
summary(object, ...)
## S3 method for class 'summary.ggcpt'
print(x, ...)
Arguments
object |
A |
... |
Additional arguments (ignored). |
x |
A |
Value
A list with class summary.ggcpt containing the summary.
Examples
set.seed(2026)
summary(cpt_detect(c(rnorm(60), rnorm(60, 3)), method = "pelt"))
Taylor's change point analyzer
Description
Wraps ChangePointTaylor::change_point_analyzer(): the
bootstrap-and-recursion procedure of Wayne Taylor that the quality-control
and Six Sigma community uses as its default. Each candidate is scored by
the bootstrap probability that a change occurred there, which gives a
confidence level per changepoint and a confidence interval for its
location, both carried onto the result.
Usage
taylor_wrapper(
x,
n_bootstraps = 1000,
min_candidate_conf = 0.5,
min_conf = 0.9,
conf_level = 0.95,
seed = NULL
)
Arguments
x |
A numeric vector. |
n_bootstraps |
Bootstrap samples per candidate. Defaults to
|
min_candidate_conf |
Minimum confidence for a candidate to be
considered, between 0.3 and 1. Defaults to |
min_conf |
Minimum confidence for a changepoint to be reported,
between 0.5 and 1. Defaults to |
conf_level |
Confidence level of the reported location intervals,
between 0.9 and 0.999 (the engine's range). Defaults to |
seed |
Optional seed (the procedure is bootstrap-based). The seed is
scoped to this call: |
Value
A ggcpt object with ci_lower/ci_upper (so
autoplot(show_ci = TRUE) works) and a confidence column.
Series length, and why you cannot interrupt it
This engine is written for the series lengths quality control sees
(hundreds to low thousands), and it does not scale. At n = 10{,}000
with the default n_bootstraps = 1000 it runs for minutes, and
more importantly it runs where R cannot look: a setTimeLimit() of
45 seconds was still not honoured after 170, and one of 125 seconds after
200, so the call had to be killed from outside the session. R checks
elapsed-time limits and keyboard interrupts at the same points, which
means Ctrl-C will not stop it either.
So size the call before starting it rather than after. n_bootstraps
is the knob (the cost is roughly linear in it), and the
“Benchmarks” article lists the methods that do scale to long
series. That page is web-only, because the sweep behind it takes
over twenty minutes: it is published at
https://pursuitofdatascience.github.io/ggchangepoint/articles/benchmarks.html
rather than built into the package, so vignette() will not
find it.
References
Taylor WA (2000). Change-Point Analysis: A Powerful New Tool for Detecting Changes. Taylor Enterprises, Libertyville, Illinois.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
taylor_wrapper(c(rnorm(60), rnorm(60, 3)), n_bootstraps = 200, seed = 1)
TGUH wrapper
Description
Wraps the breakfast package for Tail-Greedy Unbalanced-Haar
detection, with information-criterion model selection.
Usage
tguh_wrapper(x, ...)
Arguments
x |
A numeric vector. |
... |
Additional arguments passed to |
Value
A ggcpt object.
References
Fryzlewicz P (2018). “Tail-Greedy Bottom-Up Data Decompositions and Fast Multiple Change-Point Detection.” The Annals of Statistics, 46(6B), 3390–3421.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- tguh_wrapper(c(rnorm(60), rnorm(60, 4)))
res$changepoints
res$penalty$type
ggchangepoint theme
Description
A minimal, publication-ready ggplot2 theme for changepoint plots.
Usage
theme_ggcpt(base_size = 11, base_family = "")
Arguments
base_size |
Base font size. Defaults to 11. |
base_family |
Base font family. Defaults to "". |
Value
A ggplot2 theme object.
See Also
Other accessibility scales:
scale_colour_cpt(),
scale_fill_cpt_label()
Examples
library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point() + theme_ggcpt()
Tidy a ggcpt object
Description
Returns the changepoints tibble (one row per changepoint), or the coefficients of every segment.
Usage
## S3 method for class 'ggcpt'
tidy(x, what = c("changepoints", "coefficients"), conf_level = 0.95, ...)
Arguments
x |
A |
what |
|
conf_level |
Confidence level for the coefficient intervals. |
... |
Additional arguments (ignored). |
Value
A tibble. For "changepoints": columns cp,
cp_value, and any method-specific columns. For
"coefficients": segment, start, end,
term, estimate, std_error, conf_low,
conf_high (plus coordinate for a multivariate result).
Examples
set.seed(1)
fit <- cpt_detect(c(rnorm(80), rnorm(80, 3)), method = "pelt")
tidy(fit)
tidy(fit, "coefficients")
Classical single-changepoint tests (Pettitt, Buishand, SNHT)
Description
Wraps the three single-change tests that hydrology and climatology use as
their standard vocabulary, from the trend package. All three test
H_0: no change against a single change in the mean, differing in how
they measure it:
"pettitt"a rank-based (Mann-Whitney) statistic, distribution-free and robust to outliers.
"buishand"the Buishand range test, based on rescaled adjusted partial sums; assumes normality.
"snht"the standard normal homogeneity test of Alexandersson, the reference method for detecting inhomogeneities in climate records.
Each reports a location and a p-value, and, unlike most engines here, that p-value is valid, because the location was not chosen from a larger model search.
Usage
trend_wrapper(x, test = c("pettitt", "buishand", "snht"), alpha = 0.05, ...)
Arguments
x |
A numeric vector. |
test |
Which test to run. Defaults to |
alpha |
Significance level below which the changepoint is reported.
Defaults to |
... |
Additional arguments passed to the trend function. |
Value
A ggcpt object with the test's p_value and
statistic on the changepoints tibble. The per-position test
statistic is available through cpt_statistic().
References
Pettitt AN (1979). “A non-parametric approach to the change-point problem.” Journal of the Royal Statistical Society: Series C, 28(2), 126–135. doi:10.2307/2346729.
Buishand TA (1982). “Some methods for testing the homogeneity of rainfall records.” Journal of Hydrology, 58(1–2), 11–27. doi:10.1016/0022-1694(82)90066-X.
Alexandersson H (1986). “A homogeneity test applied to precipitation data.” Journal of Climatology, 6(6), 661–675. doi:10.1002/joc.3370060607.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
x <- c(rnorm(60), rnorm(60, 2))
trend_wrapper(x, test = "pettitt")
trend_wrapper(x, test = "snht")
VAR(1) changepoints
Description
Wraps changepoints::CV.search.DP.VAR1() (Wang, Yu, Rinaldo and
Willett): dynamic programming with an \ell_0 penalty for changes in
the transition matrix of a vector autoregression, with the two tuning
parameters chosen by cross-validation. The change here is in the
dynamics (how the series predicts itself), not in the level, so it
is invisible to every mean-change engine in the package.
Usage
var_wrapper(x, gamma_set = NULL, lambda_set = NULL, delta = NULL, ...)
Arguments
x |
A numeric matrix or data frame, rows as time points. |
gamma_set |
Candidate values of the |
lambda_set |
Candidate lasso penalties. Defaults to
|
delta |
Minimum spacing. Defaults to |
... |
Additional arguments passed to the engine. |
Value
A ggcpt object with change_in = "regression". The
engine searches every other observation, so a location is resolved to
within two; each is reported as the last observation before the
change, the package convention, rather than the engine's own index,
which sits one or two earlier.
References
Wang D, Yu Y, Rinaldo A, Willett R (2019). “Localizing changes in high-dimensional vector autoregressive processes.” arXiv preprint arXiv:1909.06359. doi:10.48550/arXiv.1909.06359.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
p <- 3
step <- function(n, a) {
Y <- matrix(0, n, p)
for (i in 2:n) Y[i, ] <- a * Y[i - 1, ] + stats::rnorm(p)
Y
}
var_wrapper(rbind(step(50, 0.1), step(50, 0.8)),
gamma_set = c(1, 10), lambda_set = c(0.1, 1))
WBS2 wrapper: Wild Binary Segmentation 2
Description
Wraps the breakfast package's WBS2 solution path with
steepest-drop-to-low-levels (SDLL) model selection.
Usage
wbs2_wrapper(x, ...)
Arguments
x |
A numeric vector. |
... |
Additional arguments passed to |
Value
A ggcpt object.
Reproducibility
This engine is not reproducible call to call within an R
session, and no argument here can make it so. On a 200-point series with
one change at 100, repeated identical calls (same input,
set.seed() re-run beforehand so that .Random.seed is
byte-identical on entry) return a last changepoint of either 183 or
188, roughly evenly split. The variation is therefore not driven by R's
random number stream, which is why this wrapper has no seed
argument to offer: there is no stream to pin.
It is upstream, not in this package. Calling
breakfast::breakfast(x, solution.path = "wbs2",
model.selection = "sdll") directly (breakfast 2.5) reproduces it
exactly. A fresh R session is deterministic (five separate
sessions agreed), so what varies is state the engine carries between
calls.
In practice this is rare, and needs a series whose model selection sits
near a tie. Measured over eight other series with three identical calls
each, wbs2 was stable on all eight; the flip above reproduces
only on that one configuration. tguh, which uses the same
package, was stable throughout, as were the other 35 of the 50 wired
methods this experiment covered (the rest need an engine that was not
installed when it was run). If you need a segmentation you can reproduce
exactly, take the result of the first call in a session, or use an
engine with a seed argument (cpt_methods()
reports which wrappers have one).
References
Fryzlewicz P (2020). “Detecting Multiple Change-Point Features via Narrowest-Over-Threshold.” Journal of the Royal Statistical Society Series B, 82(5), 1377–1418.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- wbs2_wrapper(c(rnorm(60), rnorm(60, 4)))
res$changepoints
WBS wrapper: Wild Binary Segmentation
Description
Wraps the wbs package for randomised changepoint detection via
Wild Binary Segmentation.
Usage
wbs_wrapper(x, n_intervals = 5000, threshold = NULL, seed = NULL, ...)
Arguments
x |
A numeric vector. |
n_intervals |
Number of random intervals. Defaults to |
threshold |
Manual threshold for detection. If |
seed |
Optional seed for reproducibility. The seed is scoped to this
call: |
... |
Additional arguments passed to |
Value
A ggcpt object.
References
Fryzlewicz P (2014). “Wild Binary Segmentation for Multiple Change-Point Detection.” The Annals of Statistics, 42(6), 2243–2281. doi:10.1214/14-AOS1245.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbsts_wrapper()
Examples
set.seed(2026)
res <- wbs_wrapper(c(rnorm(60), rnorm(60, 4)), n_intervals = 200)
res$changepoints
res$penalty$type # sSIC selection, because `threshold` was not supplied
WBS for nonstationary time series
Description
Wraps wbsts::wbs.lsw() (Korkas and Fryzlewicz): wild binary
segmentation applied to the locally stationary wavelet spectrum, so it
detects changes in the second-order structure (variance and
autocovariance) of a nonstationary series. Where wbs looks for
jumps in the level, this looks for jumps in how the series behaves.
Usage
wbsts_wrapper(
x,
n_intervals = 0,
cstar = 0.75,
lambda = 0.75,
scales = NULL,
seed = NULL,
...
)
Arguments
x |
A numeric vector. |
n_intervals |
Number of random intervals ( |
cstar |
The unbalancedness parameter |
lambda |
How many wavelet scales are used when |
scales |
Wavelet scales to use: at least two different whole
numbers from 1 to |
seed |
Optional seed. The seed is scoped to this call:
|
... |
Additional arguments passed to |
Value
A ggcpt object with change_in = "var".
References
Korkas KK, Fryzlewicz P (2017). “Multiple change-point detection for non-stationary time series using wild binary segmentation.” Statistica Sinica, 27(1), 287–311. doi:10.5705/ss.202015.0262.
See Also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
capa_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
ocd_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper()
Examples
set.seed(2026)
y <- c(as.numeric(stats::arima.sim(list(ar = 0.1), 250)),
as.numeric(stats::arima.sim(list(ar = 0.9), 250)))
wbsts_wrapper(y)