| Title: | ECG Analysis Functions for PhysioExperiment Objects |
|---|---|
| Description: | Provides electrocardiography (ECG) analysis functions for PhysioExperiment objects. Includes R-peak detection (adaptive Pan-Tompkins), RR interval computation, HRV time-domain metrics (SDNN, RMSSD, pNN50), HRV frequency-domain analysis (VLF, LF, HF power), nonlinear HRV (Poincare, Sample Entropy, DFA), ECG morphology analysis (QRS boundaries, QT/QTc intervals), and signal quality assessment with ectopic beat correction. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.3 |
| Built: | 2026-10-03 13:42:32 UTC |
| Source: | https://github.com/x-biosignal/PhysioECG |
Estimates rate from complete inter-trough breath periods or from the dominant respiratory-band spectral peak.
breathingRate( x, channel = NULL, method = c("peaks", "spectral"), band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )breathingRate( x, channel = NULL, method = c("peaks", "spectral"), band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )
x, channel, band, min_period_sec, sr, assay_name
|
As in
|
method |
|
A data frame with one row per selected channel and columns
channel, method, rate_bpm, n_breaths, and sd_bpm.
sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) breathingRate(signal, sr = sr)sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) breathingRate(signal, sr = sr)
Finds where a rolling alpha1 trajectory crosses the two exercise-intensity markers of Gronwald & Rogers: AT1 (aerobic threshold, alpha1 = 0.75) and AT2 (anaerobic threshold, alpha1 = 0.5).
dfaThresholdCrossings(alpha1, at1 = 0.75, at2 = 0.5)dfaThresholdCrossings(alpha1, at1 = 0.75, at2 = 0.5)
alpha1 |
Numeric vector of rolling alpha1 values (e.g. the
|
at1, at2
|
Threshold values (defaults 0.75 and 0.5). |
A list with at1, at2 and integer vectors
at1_crossings / at2_crossings giving the indices immediately
before each crossing (either direction).
a1 <- seq(1.2, 0.3, length.out = 20) # descending intensity ramp dfaThresholdCrossings(a1)a1 <- seq(1.2, 0.3, length.out = 20) # descending intensity ramp dfaThresholdCrossings(a1)
Aggregates the full HRV panel – time-domain, frequency-domain (AR spectrum
with normalized units), geometric and nonlinear – together with a QTc
morphology summary into a single per-channel data.frame, from an object
produced by ecgProcess (after the neurokit2
ecg_analyze() pattern).
ecgAnalyze(processed)ecgAnalyze(processed)
processed |
A PhysioExperiment returned by |
A data.frame with one row per channel and columns for the time-domain
(sdnn, rmssd, pnn50, mean_hr), frequency-domain
(lf, hf, lf_hf_ratio, lf_nu, hf_nu,
total_power), geometric (HRV_triangular_index, TINN),
nonlinear (sd1, sd2, sample_entropy, alpha1,
alpha2) and morphology (qt_ms, qtc_bazett,
qrs_ms) metrics. Metrics that cannot be computed (e.g. DFA on a short
recording) are NA.
ecgProcess, ecgHRVtime,
ecgHRVfreq, ecgHRVgeometric,
ecgHRVnonlinear, ecgIntervals
pe <- make_ecg(n_time = 40000, sr = 500) ecgAnalyze(ecgProcess(pe))pe <- make_ecg(n_time = 40000, sr = 500) ecgAnalyze(ecgProcess(pe))
Removes low-frequency baseline drift from ECG data using either a high-pass moving-average subtraction or a running-median subtraction.
ecgBaselineCorrect( x, method = c("highpass", "median"), cutoff = 0.5, assay_name = NULL, output_assay = "baseline_corrected" )ecgBaselineCorrect( x, method = c("highpass", "median"), cutoff = 0.5, assay_name = NULL, output_assay = "baseline_corrected" )
x |
A PhysioExperiment object with ECG data. |
method |
Correction method: |
cutoff |
Approximate cutoff frequency in Hz (default: 0.5). Controls the window size of the moving average or median filter. |
assay_name |
Name of the input assay.
If |
output_assay |
Name of the assay in which to store the corrected
signal (default: |
A PhysioExperiment with the corrected signal stored in
output_assay.
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
ecgSignalQuality for signal quality assessment,
ecgDetectRpeaks for R-peak detection,
ecgQualityCheck for ectopic beat detection.
set.seed(1) pe <- make_ecg_noisy(n_time = 5000, sr = 500) pe <- ecgBaselineCorrect(pe, method = "highpass") SummarizedExperiment::assayNames(pe)set.seed(1) pe <- make_ecg_noisy(n_time = 5000, sr = 500) pe <- ecgBaselineCorrect(pe, method = "highpass") SummarizedExperiment::assayNames(pe)
Quantifies ECG quality per channel by the agreement between two independent QRS detectors. A clean signal makes both detectors agree on nearly every beat (bSQI near 1); noise makes them disagree (bSQI drops).
ecgBeatSQI( x, detector_a = "pan_tompkins", detector_b = "elgendi", match_window_ms = 150, threshold_factor = 0.6, refractory_ms = 200, beta = 0.08, assay_name = NULL )ecgBeatSQI( x, detector_a = "pan_tompkins", detector_b = "elgendi", match_window_ms = 150, threshold_factor = 0.6, refractory_ms = 200, beta = 0.08, assay_name = NULL )
x |
A PhysioExperiment object with ECG data. |
detector_a, detector_b
|
Detector methods to compare (see
|
match_window_ms |
Two beats match when within this window (default 150). |
threshold_factor, refractory_ms, beta
|
Passed to the detectors. |
assay_name |
Assay to use (default: the default assay). |
A data.frame with one row per channel: n_a, n_b
(beat counts), n_matched, and bSQI = matched / (n_a + n_b -
matched) (Jaccard agreement in [0, 1]; NA for a silent
channel).
Li, Q., Mark, R.G. & Clifford, G.D. (2008). Robust heart rate estimation from multiple asynchronous noisy sources. Physiological Measurement, 29(1), 15-32.
ecgDetectRpeaks, ecgBeatSQIgate
pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) ecgBeatSQI(pe)pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) ecgBeatSQI(pe)
Thin wrapper over ecgBeatSQI adding a logical accept
column for channels whose bSQI meets a threshold.
ecgBeatSQIgate(x, threshold = 0.8, ...)ecgBeatSQIgate(x, threshold = 0.8, ...)
x |
A PhysioExperiment object with ECG data. |
threshold |
Minimum bSQI to accept a channel (default 0.8). |
... |
Passed to |
The ecgBeatSQI data.frame with an added logical
accept column.
pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) ecgBeatSQIgate(pe, threshold = 0.8)pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) ecgBeatSQIgate(pe, threshold = 0.8)
For each detected R-peak, identifies QRS complex boundaries (onset and offset) and P-wave and T-wave peaks. QRS boundaries are detected using a gradient-based search from the R-peak, while P and T waves are found as local maxima in physiologically plausible time windows.
ecgDelineate(x, peaks, assay_name = NULL)ecgDelineate(x, peaks, assay_name = NULL)
x |
A PhysioExperiment object with ECG data. |
peaks |
A data.frame of detected R-peaks as returned by
|
assay_name |
Name of the assay to use. If |
A data.frame with one row per beat and the following columns:
Integer channel index (1-based).
Integer beat number within the channel (1-based).
Sample index of the R-peak.
Sample index of QRS complex onset.
Sample index of QRS complex offset (J-point).
QRS complex duration in milliseconds.
Sample index of P-wave peak, or NA if not found
in the search window (300–80 ms before R-peak).
Sample index of T-wave peak, or NA if not found
in the search window (80–500 ms after R-peak).
Sample index of T-wave end estimated by
tangent-intercept method, or NA if T-wave not found.
Returns a zero-row data.frame with the same column structure if no beats are delineated.
Goldberger, A.L., et al. (2000). "PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals." Circulation, 101(23), e215–e220. doi:10.1161/01.CIR.101.23.e215
ecgDetectRpeaks for R-peak detection,
ecgIntervals for computing clinical ECG intervals from
delineation results, ecgSignalQuality for signal quality
assessment.
set.seed(1) pe <- make_ecg_pqrst(n_time = 5000, sr = 500, heart_rate = 72)$pe peaks <- ecgDetectRpeaks(pe) delin <- ecgDelineate(pe, peaks) head(delin)set.seed(1) pe <- make_ecg_pqrst(n_time = 5000, sr = 500, heart_rate = 72)$pe peaks <- ecgDetectRpeaks(pe) delin <- ecgDelineate(pe, peaks) head(delin)
Classifies the cardiac rhythm of each channel as regular sinus, atrial
fibrillation (AF), or frequent ectopy from the irregularity of the RR
interval series. HRV metrics are physiologically undefined in AF, so this
gate is used to invalidate them (see rhythm_check in
ecgHRVtime, ecgHRVfreq and
ecgHRVnonlinear).
ecgDetectAF( rr, window_beats = NULL, ectopic_frac_max = 0.05, rmssd_ratio_af = 0.15, entropy_af = 0.7, n_bins = 16L, drr_range = c(-600, 600), threshold_ms = 300, min_beats = 20L )ecgDetectAF( rr, window_beats = NULL, ectopic_frac_max = 0.05, rmssd_ratio_af = 0.15, entropy_af = 0.7, n_bins = 16L, drr_range = c(-600, 600), threshold_ms = 300, min_beats = 20L )
rr |
A data.frame with columns |
window_beats |
If non-NULL, an integer window length (in beats): instead
of a single per-channel verdict, a continuous AF probability is returned for
each non-overlapping window of |
ectopic_frac_max |
Maximum ectopic fraction for a |
rmssd_ratio_af |
Minimum RMSSD/mean-RR ratio consistent with AF (default 0.15). |
entropy_af |
Minimum normalized dRR Shannon entropy consistent with AF (default 0.7, range 0-1). |
n_bins |
Number of histogram bins for the dRR entropy (default 16). |
drr_range |
Numeric length-2 dRR window (ms) for the entropy histogram (default c(-600, 600)). |
threshold_ms |
Deviation threshold (ms) passed to
|
min_beats |
Minimum RR intervals required to classify; fewer yields
|
Three descriptors are combined: the ectopic-beat fraction from
ecgQualityCheck, the RMSSD/mean-RR normalized irregularity
index, and the normalized Shannon entropy of the successive-difference (dRR)
histogram. AF requires both large beat-to-beat variability
(rmssd_ratio) and a broad, disordered dRR distribution
(drr_entropy); a large but concentrated irregularity (e.g. an ectopic
couplet) falls through to "frequent_ectopy".
With window_beats = NULL (default), a data.frame with one row
per channel and columns channel, rhythm ("sinus",
"AF" or "frequent_ectopy"), ectopic_frac,
rmssd_ratio, drr_entropy, af_prob (a continuous AF
probability in 0-1) and n_beats. With window_beats set, a
data.frame with one row per non-overlapping window and columns
channel, window, beat_start, n_beats,
af_prob and its components (rmssd_ratio, drr_entropy,
sample_entropy, sd1_sd2).
Tateno, K. & Glass, L. (2001). Automatic detection of atrial fibrillation using the coefficient of variation and density histograms of RR and dRR intervals. Medical & Biological Engineering & Computing, 39(6), 664-671. Sarkar, S., Ritscher, D. & Mehra, R. (2008). A detector for a chronic implantable atrial tachyarrhythmia monitor. IEEE Transactions on Biomedical Engineering, 55(3), 1219-1224.
set.seed(1) rr <- data.frame(channel = 1L, rr_ms = 800 + rnorm(100, sd = 20), time_sec = cumsum(rep(0.8, 100))) ecgDetectAF(rr)set.seed(1) rr <- data.frame(channel = 1L, rr_ms = 800 + rnorm(100, sd = 20), time_sec = cumsum(rep(0.8, 100))) ecgDetectAF(rr)
Flags ventricular ectopic beats from three classic features: an abnormal QRS morphology (low correlation with an average-beat template), prematurity of the preceding RR interval, and a full compensatory pause (the premature beat plus its following pause together span about two normal cycles). The compensatory pause is what distinguishes a PVC from a non-compensatory supraventricular ectopic beat or sinus arrhythmia.
ecgDetectPVC( x, peaks, rr, qrs_ms = 100, corr_threshold = 0.9, prematurity_max = 0.85, compensatory_min = 0.9, require_compensatory = FALSE, assay_name = NULL )ecgDetectPVC( x, peaks, rr, qrs_ms = 100, corr_threshold = 0.9, prematurity_max = 0.85, compensatory_min = 0.9, require_compensatory = FALSE, assay_name = NULL )
x |
A PhysioExperiment object with ECG data. |
peaks |
R-peak table from |
rr |
RR-interval table from |
qrs_ms |
QRS window half-width in ms for template matching (default 100). |
corr_threshold |
Template-correlation below which a beat is morphologically abnormal (default 0.9). |
prematurity_max |
Prematurity ratio (RR_pre / local median RR) below which a beat is premature (default 0.85). |
compensatory_min |
Minimum (RR_pre + RR_post) / (2 * local median RR) for a full compensatory pause (default 0.90). |
require_compensatory |
If TRUE, also require a compensatory pause for a PVC verdict (default FALSE). |
assay_name |
Input assay name (default: first assay). |
A data.frame with one row per beat: channel, beat,
sample, rr_pre_ms, rr_post_ms, prematurity,
compensatory, morph_corr and the logical is_pvc.
Petrenas, A., Marozas, V. & Sornmo, L. (2015). Low-complexity detection of atrial fibrillation in continuous long-term monitoring. Computers in Biology and Medicine, 65, 184-191.
ecgDetectRpeaks, ecgRRintervals,
ecgDetectAF
pe <- make_ecg_pqrst(n_time = 5000, sr = 500)$pe pk <- ecgDetectRpeaks(pe) rr <- ecgRRintervals(pe, pk) head(ecgDetectPVC(pe, pk, rr))pe <- make_ecg_pqrst(n_time = 5000, sr = 500)$pe pk <- ecgDetectRpeaks(pe) rr <- ecgRRintervals(pe, pk) head(ecgDetectPVC(pe, pk, rr))
Identifies R-peaks in ECG data using one of four QRS detectors. All share a
bandpass front end and automatic inverted-lead handling but differ in their
feature transform and threshold rule: "pan_tompkins" (5-15 Hz,
derivative-square-integrate, adaptive dual threshold), "hamilton"
(8-16 Hz, rectified derivative, 80 ms integration, running mean of the last
eight QRS/noise peaks), "elgendi" (8-20 Hz, squared, two moving
averages with an event-block threshold), and "christov" (9-30 Hz,
rectified derivative smoothed over 30 ms, adaptive steep-slope M-threshold
with decay).
ecgDetectRpeaks( x, method = c("pan_tompkins", "hamilton", "elgendi", "christov"), threshold_factor = 0.6, refractory_ms = 200, assay_name = NULL, beta = 0.08 )ecgDetectRpeaks( x, method = c("pan_tompkins", "hamilton", "elgendi", "christov"), threshold_factor = 0.6, refractory_ms = 200, assay_name = NULL, beta = 0.08 )
x |
A PhysioExperiment object with ECG data. |
method |
Detection method: one of |
threshold_factor |
Retained for backward compatibility; the Pan-Tompkins path uses its built-in fractional threshold (default: 0.6). |
refractory_ms |
Refractory period in milliseconds. No two peaks can be closer than this (default: 200). |
assay_name |
Name of the assay to use. If |
beta |
Offset factor for the Elgendi event threshold
|
A data.frame with one row per detected R-peak and the following columns:
Integer channel index (1-based).
Integer sample index of the R-peak within the assay matrix.
Time of the R-peak in seconds from signal onset.
Amplitude of the raw signal at the R-peak location (in original units, not inverted).
Returns a zero-row data.frame with the same column structure if no peaks are detected.
Pan, J. & Tompkins, W.J. (1985). "A real-time QRS detection algorithm." IEEE Transactions on Biomedical Engineering, 32(3), 230–236. doi:10.1109/TBME.1985.325532
Hamilton, P. (2002). "Open source ECG analysis." Computers in Cardiology, 29, 101–104.
Elgendi, M. (2013). "Fast QRS detection with an optimized knowledge-based method." PLoS ONE, 8(9), e73557. doi:10.1371/journal.pone.0073557
Christov, I. (2004). "Real time electrocardiogram QRS detection using combined adaptive threshold." BioMedical Engineering OnLine, 3, 28. doi:10.1186/1475-925X-3-28
ecgRRintervals for computing RR intervals from
detected peaks, ecgBeatSQI for detector-agreement quality,
ecgDelineate for full waveform morphology
analysis, ecgSignalQuality for signal quality assessment.
set.seed(1) pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) peaks <- ecgDetectRpeaks(pe) head(peaks)set.seed(1) pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) peaks <- ecgDetectRpeaks(pe) head(peaks)
Performs detrended fluctuation analysis (DFA) on RR interval data to characterize fractal scaling properties. Computes alpha1 (short-range correlations, 4–16 beats) and alpha2 (long-range correlations, 16–64 beats).
ecgDFA(rr, short_range = c(4, 16), long_range = c(16, 64))ecgDFA(rr, short_range = c(4, 16), long_range = c(16, 64))
rr |
A data.frame with columns |
short_range |
Numeric vector of length 2 defining the scale range (in beats) for alpha1 (default: c(4, 16)). |
long_range |
Numeric vector of length 2 defining the scale range (in beats) for alpha2 (default: c(16, 64)). |
A data.frame with one row per channel and the following columns:
Integer channel index.
Short-range scaling exponent. Values near 1.0 indicate
fractal-like (healthy) correlations; values near 0.5 indicate
uncorrelated (random) behavior; values near 1.5 suggest
Brownian noise. NA if the series is too short.
Long-range scaling exponent with the same interpretation
as alpha1 but over larger time scales. NA if the series is
too short.
Peng, C.-K., et al. (1994). "Mosaic organization of DNA nucleotides." Physical Review E, 49(2), 1685–1689. doi:10.1103/PhysRevE.49.1685
ecgHRVnonlinear for the combined nonlinear analysis
wrapper, ecgSampleEntropy for sample entropy,
ecgHRVpoincare for Poincare plot descriptors.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgDFA(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgDFA(rr)
Computes the short-range detrended-fluctuation scaling exponent (alpha1) over a sliding window of beats, yielding a time-resolved alpha1 trajectory. This is the basis of the DFA-a1 exercise-intensity thresholds of Gronwald & Rogers (2020).
ecgDFArolling(rr, window_beats = 300, step_beats = 30, short_range = c(4, 16))ecgDFArolling(rr, window_beats = 300, step_beats = 30, short_range = c(4, 16))
rr |
A data.frame with columns |
window_beats |
Window length in beats (default 300). |
step_beats |
Step between successive windows in beats (default 30). |
short_range |
Scale range (in beats) for alpha1 (default c(4, 16)). |
A data.frame with one row per window and columns channel,
beat_start, beat_end, beat_center and alpha1.
Peng, C.K. et al. (1995). Quantification of scaling exponents. Chaos, 5(1), 82-87. Gronwald, T. & Rogers, B. (2020). Fractal correlation properties of heart rate variability as a biomarker. Frontiers in Physiology, 11, 550572.
set.seed(1) rr <- data.frame(channel = 1L, rr_ms = 800 + cumsum(rnorm(1000, sd = 2))) traj <- ecgDFArolling(rr, window_beats = 200, step_beats = 50)set.seed(1) rr <- data.frame(channel = 1L, rr_ms = 800 + cumsum(rnorm(1000, sd = 2))) traj <- ecgDFArolling(rr, window_beats = 200, step_beats = 50)
Convenience summary of the ectopic-beat burden in an RR-interval data.frame
that has been passed through ecgQualityCheck.
ecgEctopicBurden(rr)ecgEctopicBurden(rr)
rr |
A data.frame with an |
A list with n_ectopic (count of ectopic beats),
n_total (total beats) and pct_ectopic (percent ectopic).
rr <- data.frame(channel = 1L, rr_ms = c(800, 810, 400, 805, 815), is_ectopic = c(FALSE, FALSE, TRUE, FALSE, FALSE)) ecgEctopicBurden(rr)rr <- data.frame(channel = 1L, rr_ms = c(800, 810, 400, 805, 815), is_ectopic = c(FALSE, FALSE, TRUE, FALSE, FALSE)) ecgEctopicBurden(rr)
Estimates a respiration surrogate from beat-to-beat modulation of the QRS complex (Moody et al. 1985). Respiration shifts the cardiac electrical axis, modulating R-wave amplitude, QRS area or upslope; the per-beat feature series is resampled to a uniform grid to form the EDR signal, and the respiratory rate is read from its spectral peak.
ecgEDR( x, peaks, method = c("amplitude", "area", "slope"), fs = 4, resp_band = c(0.1, 0.5), qrs_ms = 50, assay_name = NULL )ecgEDR( x, peaks, method = c("amplitude", "area", "slope"), fs = 4, resp_band = c(0.1, 0.5), qrs_ms = 50, assay_name = NULL )
x |
A PhysioExperiment object with ECG data. |
peaks |
R-peak table from |
method |
Beat feature: "amplitude" (R-wave amplitude, default), "area" (QRS area) or "slope" (maximum QRS upslope). |
fs |
Resampling rate (Hz) of the EDR signal (default 4). |
resp_band |
Respiratory frequency band (Hz) for the rate estimate
(default |
qrs_ms |
QRS half-window (ms) for the "area"/"slope" features (default 50). |
assay_name |
Input assay name (default: first assay). |
A list with:
The feature used.
A data.frame (channel, time_sec,
feature) of the per-beat feature.
A data.frame (channel, time_sec, edr) of
the uniform-resampled respiration surrogate.
A data.frame (channel, resp_rate_hz,
resp_rate_bpm) of the estimated respiratory rate.
Moody, G.B. et al. (1985). Derivation of respiratory signals from multi-lead ECGs. Computers in Cardiology, 12, 113-116.
pe <- make_ecg(n_time = 10000, sr = 250) pk <- ecgDetectRpeaks(pe) edr <- ecgEDR(pe, pk, method = "area") edr$resp_ratepe <- make_ecg(n_time = 10000, sr = 250) pk <- ecgDetectRpeaks(pe) edr <- ecgEDR(pe, pk, method = "area") edr$resp_rate
Computes post-exercise heart-rate recovery: the fall in heart rate from the exercise peak to fixed offsets into recovery (Cole et al. 1999; Imai et al. 1994), plus the recovery slope. Accepts either a heart-rate (bpm) or an RR (ms) series.
ecgHRR( rr_or_hr, time_sec = NULL, peak_time = NULL, recovery_offsets_sec = c(60, 120), input = c("auto", "hr", "rr"), abnormal_bpm = 12 )ecgHRR( rr_or_hr, time_sec = NULL, peak_time = NULL, recovery_offsets_sec = c(60, 120), input = c("auto", "hr", "rr"), abnormal_bpm = 12 )
rr_or_hr |
A numeric vector of heart rate (bpm) or RR intervals (ms), or
a data.frame with a |
time_sec |
Time of each sample in seconds (required for a vector input;
taken from the |
peak_time |
Time (seconds) of the exercise peak / start of recovery. If
|
recovery_offsets_sec |
Offsets (seconds) after the peak at which to
measure recovery (default |
input |
Interpretation of a vector input: "auto" (default; decided by magnitude – values above 250 are treated as RR in ms), "hr" or "rr". |
abnormal_bpm |
HRR at 1 minute below which recovery is flagged abnormal (default 12 bpm, per Cole et al. 1999). |
A list with:
Recovery start time (s) and peak HR (bpm).
A data.frame with columns offset_sec,
hr_at_offset and hrr_bpm (peak HR minus HR at the offset).
Convenience scalars for the first two offsets.
Slope of a linear fit of HR vs time over the recovery window (negative during recovery).
HRR at exactly 60 s (used for the abnormal flag).
TRUE if hrr_1min < abnormal_bpm.
Cole, C.R. et al. (1999). Heart-rate recovery immediately after exercise as a predictor of mortality. New England Journal of Medicine, 341(18), 1351-1357. Imai, K. et al. (1994). Vagally mediated heart rate recovery after exercise is accelerated in athletes but blunted in patients with chronic heart failure. Journal of the American College of Cardiology, 24(6), 1529-1535.
# HR decays linearly from 170 to 120 bpm over 120 s of recovery t <- seq(0, 120, by = 1) hr <- 170 - (170 - 120) * t / 120 res <- ecgHRR(hr, time_sec = t, peak_time = 0) res$hrr res$abnormal# HR decays linearly from 170 to 120 bpm over 120 s of recovery t <- seq(0, 120, by = 1) hr <- 170 - (170 - 120) * t / 120 res <- ecgHRR(hr, time_sec = t, peak_time = 0) res$hrr res$abnormal
Computes turbulence onset (TO) and turbulence slope (TS), the biphasic
sinus-rhythm response to a ventricular premature beat (Schmidt et al. 1999).
RR intervals are indexed by beat so that rr[i] is the interval between
beat i and beat i+1; for a PVC at beat p the coupling
interval is rr[p-1] and the compensatory pause rr[p], which are
excluded. The local tachograms of all usable PVCs are averaged before TO/TS.
ecgHRT(rr, pvc_index, n_post = 15L)ecgHRT(rr, pvc_index, n_post = 15L)
rr |
RR intervals (ms): a numeric vector or a data.frame with an
|
pvc_index |
Integer beat indices of the ventricular premature beats (e.g.
the |
n_post |
Number of post-PVC sinus intervals used for TS (default 15). |
A list with to (turbulence onset, percent; negative is normal),
ts (turbulence slope, ms per RR interval; positive is normal),
n_pvc (PVCs averaged) and tachogram (the averaged post-PVC
sinus RR series).
Schmidt, G. et al. (1999). Heart-rate turbulence after ventricular premature beats as a predictor of mortality after acute myocardial infarction. Lancet, 353(9162), 1390-1396.
# canonical post-PVC pattern: early acceleration then deceleration rr <- c(rep(800, 5), 500, 1100, 780, 785, 790 + 5 * (0:12)) ecgHRT(rr, pvc_index = 7)# canonical post-PVC pattern: early acceleration then deceleration rr <- c(rep(800, 5), 500, 1100, 780, 785, 790 + 5 * (0:12)) ecgHRT(rr, pvc_index = 7)
Computes heart-rate asymmetry (HRA) descriptors from RR interval data.
The Poincare plot is asymmetric about the line of identity because heart-rate
decelerations (prolongations of RR, points above the line, ) and accelerations (shortenings, points below the line)
contribute unequally to variability – a signature of vagal activity and of the
temporal irreversibility of heart-rate dynamics. Decelerations typically
dominate short-term variability while accelerations dominate long-term
variability (Piskorski & Guzik, 2011).
ecgHRVasymmetry(rr)ecgHRVasymmetry(rr)
rr |
A data.frame with columns |
A data.frame with one row per channel and the columns:
Channel identifier.
Guzik's Index (\ points from the line of identity divided by that of all points.
Slope Index (\ points divided by that of all points.
Area Index (\ points divided by that of all points.
Porta's Index (\ the number of points off the line of identity.
Contributions of decelerations / accelerations to
short-term HRV (c1d + c1a = 1).
Short-term variance components of decelerations / accelerations (ms).
Contributions of decelerations / accelerations to
long-term HRV (c2d + c2a = 1).
Long-term variance components (ms).
Total contributions of decelerations / accelerations to HRV.
Total variance components (ms).
A value indicating asymmetry is c1d > c1a (decelerations dominate
short-term variability). Columns are NA for channels with fewer than
three RR intervals.
Guzik, P., et al. (2006). "Heart rate asymmetry by Poincare plots of RR intervals." Biomedizinische Technik, 51(4), 272–275.
Piskorski, J., & Guzik, P. (2011). "Asymmetric properties of long-term and total heart rate variability." Medical & Biological Engineering & Computing, 49(11), 1289–1297. doi:10.1007/s11517-011-0834-z
Porta, A., et al. (2008). "Temporal asymmetries of short-term heart period variability are linked to autonomic regulation." American Journal of Physiology, 295(2), R550–R557.
ecgHRVpoincare for the symmetric Poincare descriptors
(SD1/SD2), ecgDFA for detrended fluctuation analysis.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVasymmetry(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVasymmetry(rr)
Computes the cardiac sympathetic and vagal indices (Toichi et al., 1997) from
RR interval data. The indices are read off the Poincare plot's SD
bounding box: the long axis and the short axis
.
csiCardiac Sympathetic Index, (= SD2/SD1); rises with
sympathetic predominance.
cviCardiac Vagal Index, ; rises with
parasympathetic (vagal) activity.
csi_modifiedModified CSI, , a more sensitive
sympathetic marker (Jeppesen et al., 2014) used in seizure detection.
Here SD1 is the universal beat-to-beat term () and SD2
is the geometric (paired-projection) long-term term, matching the convention in
which the Toichi indices are defined (as in NeuroKit2's hrv_nonlinear);
this SD2 differs by a small amount from the analytical closed-form
SD2 reported by ecgHRVpoincare.
ecgHRVautonomic(rr)ecgHRVautonomic(rr)
rr |
A data.frame with columns |
A data.frame with one row per channel and the columns channel,
csi, cvi, and csi_modified. Columns are NA for
channels with fewer than three RR intervals.
Toichi, M., Sugiura, T., Murai, T., & Sengoku, A. (1997). "A new method of assessing cardiac autonomic function and its comparison with spectral analysis and coefficient of variation of R-R interval." Journal of the Autonomic Nervous System, 62(1-2), 79–84.
Jeppesen, J., et al. (2014). "Using Lorenz plot and Cardiac Sympathetic Index of heart rate variability for detecting seizures for patients with epilepsy." IEEE EMBC, 4563–4566.
ecgHRVpoincare for SD1/SD2, ecgHRVasymmetry
for heart-rate asymmetry.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVautonomic(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVautonomic(rr)
Computes heart rate variability frequency-domain metrics from RR interval data using Welch's method or Lomb-Scargle periodogram.
ecgHRVfreq( rr, method = c("welch", "lomb", "ar"), vlf_band = c(0.003, 0.04), lf_band = c(0.04, 0.15), hf_band = c(0.15, 0.4), detrend = FALSE, detrend_lambda = 500, ar_order = NULL, rhythm_check = TRUE )ecgHRVfreq( rr, method = c("welch", "lomb", "ar"), vlf_band = c(0.003, 0.04), lf_band = c(0.04, 0.15), hf_band = c(0.15, 0.4), detrend = FALSE, detrend_lambda = 500, ar_order = NULL, rhythm_check = TRUE )
rr |
A data.frame with columns |
method |
Spectral estimation method: |
vlf_band |
Numeric vector of length 2 defining VLF band in Hz (default: c(0.003, 0.04)). |
lf_band |
Numeric vector of length 2 defining LF band in Hz (default: c(0.04, 0.15)). |
hf_band |
Numeric vector of length 2 defining HF band in Hz (default: c(0.15, 0.4)). |
detrend |
Logical; if |
detrend_lambda |
Smoothing parameter passed to
|
ar_order |
Integer AR model order for |
rhythm_check |
Logical; if |
A data.frame with one row per channel and the following columns:
Integer channel index.
Absolute power in the very-low-frequency band (ms^2).
Absolute power in the low-frequency band (ms^2), associated with sympathetic and parasympathetic modulation.
Absolute power in the high-frequency band (ms^2), associated with parasympathetic (vagal) modulation.
Ratio of LF to HF power, or NA if HF power
is zero.
Sum of VLF, LF, and HF power (ms^2).
LF and HF power in normalized units,
100 * LF/(LF+HF) and 100 * HF/(LF+HF); these sum to 100.
Frequency (Hz) of the spectral peak within the
LF and HF bands, or NA if the band is empty.
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
ecgRRintervals for computing RR intervals,
ecgHRVtime for time-domain HRV metrics,
ecgHRVnonlinear for nonlinear HRV analysis,
ecgRRcorrect for ectopic beat correction before analysis.
n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) rr <- data.frame(channel = rep(1L, n), rr_ms = rr_ms, time_sec = time_sec) result <- ecgHRVfreq(rr, method = "welch")n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) rr <- data.frame(channel = rep(1L, n), rr_ms = rr_ms, time_sec = time_sec) result <- ecgHRVfreq(rr, method = "welch")
Computes the geometric heart-rate-variability measures defined by the Task Force (1996) from a series of NN (normal-to-normal) intervals: the HRV triangular index and the triangular interpolation of the NN interval histogram (TINN).
ecgHRVgeometric(rr, bin_ms = 7.8125)ecgHRVgeometric(rr, bin_ms = 7.8125)
rr |
Numeric vector of NN/RR intervals in milliseconds, or a data frame
with an |
bin_ms |
Histogram bin width in milliseconds. Defaults to
|
A list with:
Total number of NN intervals divided by the height (modal count) of the NN histogram.
Baseline width, in milliseconds, of the triangle that best approximates the NN histogram in a least-squares sense.
Task Force of the ESC and NASPE (1996). Heart rate variability: standards of measurement. Circulation, 93(5), 1043-1065.
set.seed(1) rr <- 800 + rnorm(500, sd = 40) # NN intervals in ms ecgHRVgeometric(rr)set.seed(1) rr <- 800 + rnorm(500, sd = 40) # NN intervals in ms ecgHRVgeometric(rr)
Computes all nonlinear HRV metrics by calling ecgHRVpoincare,
ecgSampleEntropy, and ecgDFA, and merging
the results into a single data.frame.
ecgHRVnonlinear( rr, m = 2L, r_factor = 0.2, short_range = c(4, 16), long_range = c(16, 64), rhythm_check = TRUE )ecgHRVnonlinear( rr, m = 2L, r_factor = 0.2, short_range = c(4, 16), long_range = c(16, 64), rhythm_check = TRUE )
rr |
A data.frame with columns |
m |
Embedding dimension for sample entropy (default: 2). |
r_factor |
Tolerance factor for sample entropy (default: 0.2). |
short_range |
Scale range for DFA alpha1 (default: c(4, 16)). |
long_range |
Scale range for DFA alpha2 (default: c(16, 64)). |
rhythm_check |
Logical; if |
A data.frame with columns: channel, sd1, sd2, sd1_sd2_ratio, sample_entropy, m, r, alpha1, alpha2.
Shaffer, F. & Ginsberg, J.P. (2017). "An overview of heart rate variability metrics and norms." Frontiers in Public Health, 5, 258. doi:10.3389/fpubh.2017.00258
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
ecgHRVpoincare for Poincare plot descriptors,
ecgSampleEntropy for sample entropy,
ecgDFA for detrended fluctuation analysis,
ecgHRVtime for time-domain HRV metrics,
ecgHRVfreq for frequency-domain HRV analysis.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVnonlinear(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVnonlinear(rr)
Computes Poincare plot descriptors (SD1, SD2, SD1/SD2 ratio) from RR interval data. SD1 reflects short-term variability (perpendicular to the identity line), while SD2 reflects long-term variability (along the identity line).
ecgHRVpoincare(rr)ecgHRVpoincare(rr)
rr |
A data.frame with columns |
A data.frame with one row per channel and the following columns:
Integer channel index.
Standard deviation perpendicular to the identity line (ms), reflecting beat-to-beat (short-term) variability.
Standard deviation along the identity line (ms), reflecting long-term variability.
Ratio of SD1 to SD2, or NA if SD2 is
zero.
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
ecgHRVnonlinear for the combined nonlinear analysis
wrapper, ecgSampleEntropy for sample entropy,
ecgDFA for detrended fluctuation analysis.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVpoincare(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVpoincare(rr)
Splits an NN-interval series into consecutive fixed-duration segments (5 minutes by default) and returns the two Task Force (1996) long-term variability measures.
ecgHRVsegmented(rr, segment_sec = 300)ecgHRVsegmented(rr, segment_sec = 300)
rr |
Numeric vector of NN/RR intervals in milliseconds. |
segment_sec |
Segment length in seconds (default 300 = 5 minutes). |
A list with:
Standard deviation of the per-segment mean NN intervals (ms) - long-term variability.
Mean of the per-segment SDNN values (ms) - average short-term variability.
Number of segments used.
Task Force of the ESC and NASPE (1996). Circulation, 93(5), 1043-1065.
set.seed(1) rr <- 800 + rnorm(3000, sd = 40) ecgHRVsegmented(rr, segment_sec = 300)set.seed(1) rr <- 800 + rnorm(3000, sd = 40) ecgHRVsegmented(rr, segment_sec = 300)
Compute standard heart rate variability (HRV) time-domain metrics from RR interval data. Calculates SDNN, RMSSD, pNN50, mean RR interval, and mean heart rate for each channel.
ecgHRVtime(rr, rhythm_check = TRUE)ecgHRVtime(rr, rhythm_check = TRUE)
rr |
A data.frame with columns |
rhythm_check |
Logical; if |
A data.frame with one row per channel and the following columns:
Integer channel index.
Mean RR interval in milliseconds.
Standard deviation of all RR intervals (ms), reflecting overall HRV.
Root mean square of successive RR interval differences (ms), reflecting short-term vagal modulation.
Percentage of successive RR intervals differing by more than 50 ms.
Mean heart rate in beats per minute (60000 / mean_rr).
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
ecgRRintervals for computing RR intervals,
ecgHRVfreq for frequency-domain HRV analysis,
ecgHRVnonlinear for nonlinear HRV metrics,
ecgQualityCheck for ectopic beat detection before analysis.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVtime(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgHRVtime(rr)
Computes heart-rate-variability trajectories by sliding a time window over the
RR series and evaluating time-domain (SDNN, RMSSD) and frequency-domain
(LF, HF, LF/HF) metrics in each window, reusing ecgHRVtime and
ecgHRVfreq (Task Force 1996; Mainardi 2009).
ecgHRVtimevarying( rr, window_sec = 300, step_sec = 30, freq_method = c("ar", "welch", "lomb"), detrend = FALSE, detrend_lambda = 500, min_beats = 20L, rhythm_check = FALSE )ecgHRVtimevarying( rr, window_sec = 300, step_sec = 30, freq_method = c("ar", "welch", "lomb"), detrend = FALSE, detrend_lambda = 500, min_beats = 20L, rhythm_check = FALSE )
rr |
A data.frame with columns |
window_sec |
Analysis window length in seconds (default 300). |
step_sec |
Step between successive windows in seconds (default 30). |
freq_method |
Spectral method for |
detrend, detrend_lambda
|
Passed to |
min_beats |
Minimum RR intervals in a window to compute metrics; windows
with fewer beats yield |
rhythm_check |
Passed to the per-window HRV functions (default FALSE, so the trajectory is continuous and not gated by the AF detector). |
A data.frame with one row per window per channel and columns
channel, window, time_start, time_center,
n_beats, sdnn, rmssd, lf, hf and
lf_hf.
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). Heart rate variability: standards of measurement, physiological interpretation, and clinical use. Circulation, 93(5), 1043-1065. Mainardi, L.T. (2009). On the quantification of heart rate variability spectral parameters using time-frequency and time-varying methods. Philosophical Transactions of the Royal Society A, 367(1887), 255-275.
ecgHRVtime, ecgHRVfreq,
ecgRRintervals
set.seed(1) n <- 600 rr <- data.frame(channel = 1L, rr_ms = 800 + 25 * sin(2 * pi * 0.1 * cumsum(rep(0.8, n))) + rnorm(n, sd = 10)) rr$time_sec <- cumsum(rr$rr_ms) / 1000 traj <- ecgHRVtimevarying(rr, window_sec = 120, step_sec = 30) head(traj)set.seed(1) n <- 600 rr <- data.frame(channel = 1L, rr_ms = 800 + 25 * sin(2 * pi * 0.1 * cumsum(rep(0.8, n))) + rnorm(n, sd = 10)) rr$time_sec <- cumsum(rr$rr_ms) / 1000 traj <- ecgHRVtimevarying(rr, window_sec = 120, step_sec = 30) head(traj)
Calculates standard clinical ECG intervals from the waveform delineation
produced by ecgDelineate: PR interval, QT interval, QTc
(Bazett correction), QRS duration, and RR interval.
ecgIntervals(delineation, sr)ecgIntervals(delineation, sr)
delineation |
A data.frame as returned by |
sr |
Sampling rate in Hz. |
A data.frame with one row per beat and the following columns:
Integer channel index (1-based).
Integer beat number within the channel.
PR interval in milliseconds (P-wave peak to QRS onset),
or NA if the P wave was not detected.
QT interval in milliseconds (QRS onset to T-wave end),
or NA if the T wave was not detected.
Corrected QT interval using Bazett's formula
(QT / sqrt(RR_sec)), or NA if QT or RR is
unavailable. Kept as a backward-compatible alias of
qtc_bazett.
QT
corrected for heart rate by, respectively, Bazett
(QT / sqrt(RR)), Fridericia (QT / RR^(1/3)),
Framingham (QT + 154 * (1 - RR)) and Hodges
(QT + 1.75 * (HR - 60)); QT in ms, RR in seconds. All four
equal qt_ms at RR = 1 s.
QRS complex duration in milliseconds.
RR interval in milliseconds to the next beat, or
NA for the last beat in each channel.
Returns a zero-row data.frame with the same column structure if no beats are present.
Goldberger, A.L., et al. (2000). "PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals." Circulation, 101(23), e215–e220. doi:10.1161/01.CIR.101.23.e215
ecgDelineate for waveform delineation,
ecgDetectRpeaks for R-peak detection,
ecgRRintervals for RR interval computation.
set.seed(1) pe <- make_ecg_pqrst(n_time = 5000, sr = 500, heart_rate = 72)$pe peaks <- ecgDetectRpeaks(pe) delin <- ecgDelineate(pe, peaks) intervals <- ecgIntervals(delin, samplingRate(pe)) head(intervals)set.seed(1) pe <- make_ecg_pqrst(n_time = 5000, sr = 500, heart_rate = 72)$pe peaks <- ecgDetectRpeaks(pe) delin <- ecgDelineate(pe, peaks) intervals <- ecgIntervals(delin, samplingRate(pe)) head(intervals)
Runs the standard ECG preprocessing chain end to end – baseline correction,
R-peak detection, RR extraction, ectopic-beat correction and (optionally) a
bSQI signal-quality gate – and stores the peaks, RR series and provenance in
the object's metadata() (after the neurokit2 ecg_process()
pattern).
ecgProcess( x, detector = "pan_tompkins", correct = "cubic_spline", sqi_gate = TRUE, baseline = TRUE, assay_name = NULL )ecgProcess( x, detector = "pan_tompkins", correct = "cubic_spline", sqi_gate = TRUE, baseline = TRUE, assay_name = NULL )
x |
A PhysioExperiment object with ECG data. |
detector |
R-peak detector passed to |
correct |
Ectopic-beat correction passed to |
sqi_gate |
If TRUE (default), also compute the bSQI quality gate
( |
baseline |
If TRUE (default), baseline-correct with
|
assay_name |
Input assay name (default: first assay). |
The (baseline-corrected) PhysioExperiment with an ecg entry in
metadata() holding peaks, rr (with ectopic flags),
rr_corrected, bsqi and the detect-assay name, plus a
provenance record appended via withProvenance.
ecgAnalyze, ecgDetectRpeaks,
ecgRRcorrect, ecgBeatSQIgate
pe <- make_ecg(n_time = 20000, sr = 500) proc <- ecgProcess(pe) names(S4Vectors::metadata(proc)$ecg)pe <- make_ecg(n_time = 20000, sr = 500) proc <- ecgProcess(pe) names(S4Vectors::metadata(proc)$ecg)
Computes the deceleration capacity (DC) and acceleration capacity (AC) of the
RR series by phase-rectified signal averaging (Bauer et al. 2006). Anchors are
points where the RR level increases (DC) or decreases (AC); segments centered
on the anchors are averaged into a PRSA curve, and the capacity is a
Haar-wavelet coefficient of that curve at scale s.
ecgPRSA(rr, T = 1L, s = 2L, L = 15L)ecgPRSA(rr, T = 1L, s = 2L, L = 15L)
rr |
RR intervals (ms): a numeric vector or a data.frame with an
|
T |
Averaging window (beats) for anchor selection (default 1: an anchor is a single beat larger/smaller than the previous). |
s |
Wavelet scale for the DC/AC coefficient (default 2). |
L |
Half-length of the averaged PRSA segments (default 15; must be
|
A list with dc (deceleration capacity, ms; positive with
dominant decelerations), ac (acceleration capacity, ms; negative),
the PRSA curves prsa_dc/prsa_ac, the anchor counts
n_dc/n_ac, and the parameters T, s, L.
Bauer, A. et al. (2006). Deceleration capacity of heart rate as a predictor of mortality after myocardial infarction: cohort study. Lancet, 367(9523), 1674-1681.
set.seed(1) rr <- 800 + cumsum(rnorm(600, sd = 3)) # RR random walk prsa <- ecgPRSA(rr) c(DC = prsa$dc, AC = prsa$ac)set.seed(1) rr <- 800 + cumsum(rnorm(600, sd = 3)) # RR random walk prsa <- ecgPRSA(rr) c(DC = prsa$dc, AC = prsa$ac)
Identifies ectopic (abnormal) beats by comparing each RR interval to the local median computed over a sliding window of 5 beats. Beats with deviation exceeding the threshold are marked as ectopic.
ecgQualityCheck(rr, threshold_ms = 300)ecgQualityCheck(rr, threshold_ms = 300)
rr |
A data.frame with columns |
threshold_ms |
Maximum allowed deviation from local median in milliseconds (default: 300). |
The input data.frame with an additional logical column
is_ectopic.
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
ecgRRcorrect for correcting detected ectopic beats,
ecgRRintervals for computing RR intervals,
ecgHRVtime for time-domain HRV analysis,
ecgSignalQuality for signal quality assessment.
set.seed(1) n <- 200 rr_ms <- 800 + rnorm(n, sd = 20) rr_ms[100] <- 430 # a premature (ectopic) beat rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = cumsum(rr_ms) / 1000) qc <- ecgQualityCheck(rr) sum(qc$is_ectopic)set.seed(1) n <- 200 rr_ms <- 800 + rnorm(n, sd = 20) rr_ms[100] <- 430 # a premature (ectopic) beat rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = cumsum(rr_ms) / 1000) qc <- ecgQualityCheck(rr) sum(qc$is_ectopic)
Replaces or removes ectopic beats identified by
ecgQualityCheck. The "interpolate" method uses linear
interpolation from surrounding non-ectopic intervals, "cubic_spline"
uses natural cubic-spline interpolation (C1-smooth, following Kubios-style
automatic correction), and "remove" simply drops ectopic rows.
ecgRRcorrect(rr, method = c("interpolate", "cubic_spline", "remove"))ecgRRcorrect(rr, method = c("interpolate", "cubic_spline", "remove"))
rr |
A data.frame with an |
method |
Correction method: |
A data.frame with corrected RR intervals. The is_ectopic
column is removed from the output. The result carries the ectopic burden
as attributes n_ectopic (count) and pct_ectopic (percent of
beats flagged ectopic).
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
ecgQualityCheck for detecting ectopic beats,
ecgRRintervals for computing RR intervals,
ecgHRVtime for time-domain HRV analysis.
set.seed(1) n <- 200 rr_ms <- 800 + rnorm(n, sd = 20) rr_ms[100] <- 430 # a premature (ectopic) beat rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = cumsum(rr_ms) / 1000) qc <- ecgQualityCheck(rr) corrected <- ecgRRcorrect(qc, method = "interpolate") attr(corrected, "pct_ectopic")set.seed(1) n <- 200 rr_ms <- 800 + rnorm(n, sd = 20) rr_ms[100] <- 430 # a premature (ectopic) beat rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = cumsum(rr_ms) / 1000) qc <- ecgQualityCheck(rr) corrected <- ecgRRcorrect(qc, method = "interpolate") attr(corrected, "pct_ectopic")
Calculates the time intervals between consecutive R-peaks for each channel. The resulting RR interval series is the standard input for all HRV analysis functions in this package.
ecgRRintervals(x, peaks)ecgRRintervals(x, peaks)
x |
A PhysioExperiment object. |
peaks |
A data.frame of detected peaks as returned by
|
A data.frame with one row per consecutive beat pair and the following columns:
Integer channel index (1-based).
RR interval in milliseconds (time between successive R-peaks).
Time of the first beat in each pair (seconds from signal onset).
Returns a zero-row data.frame with the same column structure if fewer than two peaks are available.
Pan, J. & Tompkins, W.J. (1985). "A real-time QRS detection algorithm." IEEE Transactions on Biomedical Engineering, 32(3), 230–236. doi:10.1109/TBME.1985.325532
ecgDetectRpeaks for R-peak detection,
ecgHRVtime for time-domain HRV metrics,
ecgHRVfreq for frequency-domain HRV analysis,
ecgQualityCheck for ectopic beat detection.
set.seed(1) pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 60) peaks <- ecgDetectRpeaks(pe) rr <- ecgRRintervals(pe, peaks) head(rr)set.seed(1) pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 60) peaks <- ecgDetectRpeaks(pe) rr <- ecgRRintervals(pe, peaks) head(rr)
Quantifies respiratory sinus arrhythmia – the respiration-linked oscillation of the RR interval – by the peak-valley method (Grossman) or the Porges-Bohrer method (band-limited variance of the tachogram).
ecgRSA( rr, resp = NULL, method = c("peak_valley", "porges_bohrer"), fs = 4, resp_band = c(0.12, 0.4) )ecgRSA( rr, resp = NULL, method = c("peak_valley", "porges_bohrer"), fs = 4, resp_band = c(0.12, 0.4) )
rr |
A data.frame with columns |
resp |
Optional respiration surrogate (unused by the current methods, reserved for respiration-gated peak-valley). |
method |
"peak_valley" (mean band-filtered peak-to-valley RR amplitude, default) or "porges_bohrer" (natural log of the band-filtered RR variance). |
fs |
Resampling rate (Hz) of the tachogram (default 4). |
resp_band |
Respiratory band (Hz) for filtering (default
|
A list with method, rsa (the RSA magnitude: mean
peak-to-valley RR in ms, or ln(variance) for Porges-Bohrer), and,
for "peak_valley", n_cycles (number of respiratory half-cycles used).
Grossman, P., van Beek, J. & Wientjes, C. (1990). A comparison of three quantification methods for estimation of respiratory sinus arrhythmia. Psychophysiology, 27(6), 702-714. Lewis, G.F. et al. (2012). Statistical strategies to quantify RSA: are commonly used metrics equivalent? Biological Psychology, 89(2), 349-364.
set.seed(1) t <- cumsum(rep(0.8, 300)) rr <- data.frame(rr_ms = 800 + 40 * sin(2 * pi * 0.25 * t) + rnorm(300, 5), time_sec = t) ecgRSA(rr)$rsaset.seed(1) t <- cumsum(rep(0.8, 300)) rr <- data.frame(rr_ms = 800 + 40 * sin(2 * pi * 0.25 * t) + rnorm(300, 5), time_sec = t) ecgRSA(rr)$rsa
Computes sample entropy (SampEn) from RR interval data. Sample entropy measures the regularity or predictability of a time series. Lower values indicate more regular (predictable) signals, while higher values indicate more complex (irregular) signals.
ecgSampleEntropy(rr, m = 2L, r_factor = 0.2)ecgSampleEntropy(rr, m = 2L, r_factor = 0.2)
rr |
A data.frame with columns |
m |
Embedding dimension (default: 2). Length of template patterns to compare. |
r_factor |
Tolerance factor (default: 0.2). The tolerance |
A data.frame with one row per channel and the following columns:
Integer channel index.
Sample entropy value (nats). Lower values
indicate more regular signals; higher values indicate more complex
signals. NA if the series is too short or constant.
Embedding dimension used.
Tolerance threshold (ms) computed as r_factor * sd(rr_ms).
Richman, J.S. & Moorman, J.R. (2000). "Physiological time-series analysis using approximate entropy and sample entropy." American Journal of Physiology-Heart and Circulatory Physiology, 278(6), H2039–H2049. doi:10.1152/ajpheart.2000.278.6.H2039
ecgHRVnonlinear for the combined nonlinear analysis
wrapper, ecgHRVpoincare for Poincare plot descriptors,
ecgDFA for detrended fluctuation analysis.
set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgSampleEntropy(rr)set.seed(1) n <- 300 time_sec <- cumsum(rep(0.85, n)) rr_ms <- 850 + 30 * sin(2 * pi * 0.1 * time_sec) + rnorm(n, sd = 15) rr <- data.frame(channel = 1L, rr_ms = rr_ms, time_sec = time_sec) ecgSampleEntropy(rr)
Computes per-channel signal quality metrics for ECG data stored in a PhysioExperiment object. When detected R-peak locations are provided the signal-to-noise ratio is estimated from QRS vs.\ baseline power; otherwise a variance-based estimate is used.
ecgSignalQuality(x, peaks = NULL, assay_name = NULL)ecgSignalQuality(x, peaks = NULL, assay_name = NULL)
x |
A PhysioExperiment object with ECG data. |
peaks |
Optional data.frame of detected R-peaks as returned by
|
assay_name |
Name of the assay to use.
If |
A data.frame with one row per channel and columns:
Integer channel index.
Signal-to-noise ratio in decibels.
RMS amplitude of the low-frequency drift.
Fraction of samples within 1\ min or max.
Composite quality score in the range [0, 1], where 1 indicates excellent quality.
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
Shaffer, F. & Ginsberg, J.P. (2017). "An overview of heart rate variability metrics and norms." Frontiers in Public Health, 5, 258. doi:10.3389/fpubh.2017.00258
ecgDetectRpeaks for R-peak detection,
ecgBaselineCorrect for baseline wander correction,
ecgQualityCheck for ectopic beat detection.
set.seed(1) pe <- make_ecg_noisy(n_time = 5000, sr = 500) ecgSignalQuality(pe)set.seed(1) pe <- make_ecg_noisy(n_time = 5000, sr = 500) ecgSignalQuality(pe)
Generates a PhysioExperiment object containing synthetic ECG data with Gaussian-shaped R-peaks at regular intervals. The resulting object is suitable for testing R-peak detection, RR interval computation, and HRV analysis pipelines.
make_ecg(n_time = 5000, n_channels = 1, sr = 500, heart_rate = 72)make_ecg(n_time = 5000, n_channels = 1, sr = 500, heart_rate = 72)
n_time |
Number of time points (default: 5000). |
n_channels |
Number of ECG channels (default: 1). |
sr |
Sampling rate in Hz (default: 500). |
heart_rate |
Heart rate in beats per minute (default: 72). |
A PhysioExperiment object with a single "raw" assay
containing the simulated ECG signal.
Pan, J. & Tompkins, W.J. (1985). "A real-time QRS detection algorithm." IEEE Transactions on Biomedical Engineering, 32(3), 230–236. doi:10.1109/TBME.1985.325532
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
make_ecg_irregular for ECG with ectopic beats,
make_ecg_pqrst for ECG with full PQRST morphology,
make_ecg_noisy for ECG with noise artifacts,
ecgDetectRpeaks for R-peak detection.
pe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) pepe <- make_ecg(n_time = 5000, sr = 500, heart_rate = 72) pe
Generates a PhysioExperiment object containing synthetic ECG data with irregular beat timing. Every 5th beat is premature (60\ interval), followed by a compensatory pause (140\ Useful for testing ectopic beat detection and RR interval correction.
make_ecg_irregular(n_time = 5000, sr = 500, heart_rate = 72)make_ecg_irregular(n_time = 5000, sr = 500, heart_rate = 72)
n_time |
Number of time points (default: 5000). |
sr |
Sampling rate in Hz (default: 500). |
heart_rate |
Base heart rate in beats per minute (default: 72). |
A PhysioExperiment object with a single "raw" assay
containing the simulated ECG signal with irregular beats.
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
Task Force of the European Society of Cardiology and the North American Society of Pacing and Electrophysiology (1996). "Heart rate variability: Standards of measurement, physiological interpretation and clinical use." Circulation, 93(5), 1043–1065.
make_ecg for regular ECG data,
ecgQualityCheck for ectopic beat detection,
ecgRRcorrect for ectopic beat correction,
ecgRRintervals for RR interval computation.
pe <- make_ecg_irregular(n_time = 5000, sr = 500, heart_rate = 72) pepe <- make_ecg_irregular(n_time = 5000, sr = 500, heart_rate = 72) pe
Generates a PhysioExperiment object containing synthetic ECG data contaminated with multiple noise sources: baseline wander (0.3 Hz sinusoidal drift), powerline interference (50 Hz), and broadband Gaussian noise. Useful for testing signal quality assessment, baseline correction, and filtering pipelines.
make_ecg_noisy( n_time = 5000, n_channels = 1, sr = 500, heart_rate = 72, baseline_amp = 0.3, powerline_amp = 0.1, noise_sd = 0.15 )make_ecg_noisy( n_time = 5000, n_channels = 1, sr = 500, heart_rate = 72, baseline_amp = 0.3, powerline_amp = 0.1, noise_sd = 0.15 )
n_time |
Number of time points (default: 5000). |
n_channels |
Number of ECG channels (default: 1). |
sr |
Sampling rate in Hz (default: 500). |
heart_rate |
Heart rate in beats per minute (default: 72). |
baseline_amp |
Amplitude of baseline wander in arbitrary units (default: 0.3). |
powerline_amp |
Amplitude of 50 Hz powerline noise (default: 0.1). |
noise_sd |
Standard deviation of broadband Gaussian noise (default: 0.15). |
A PhysioExperiment object with a single "raw" assay
containing the noisy ECG signal.
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
Shaffer, F. & Ginsberg, J.P. (2017). "An overview of heart rate variability metrics and norms." Frontiers in Public Health, 5, 258. doi:10.3389/fpubh.2017.00258
make_ecg for clean ECG data,
ecgSignalQuality for signal quality assessment,
ecgBaselineCorrect for baseline wander removal,
ecgDetectRpeaks for R-peak detection.
pe <- make_ecg_noisy(n_time = 5000, sr = 500) pepe <- make_ecg_noisy(n_time = 5000, sr = 500) pe
Generates a PhysioExperiment object containing synthetic ECG data with physiologically realistic P, Q, R, S, and T wave components. Returns both the PhysioExperiment and a data.frame of known fiducial points for validation testing of waveform delineation algorithms.
make_ecg_pqrst( n_time = 10000, n_channels = 1, sr = 500, heart_rate = 72, noise_sd = 0.02 )make_ecg_pqrst( n_time = 10000, n_channels = 1, sr = 500, heart_rate = 72, noise_sd = 0.02 )
n_time |
Number of time points (default: 10000, i.e., 20 seconds at 500 Hz). |
n_channels |
Number of ECG channels (default: 1). |
sr |
Sampling rate in Hz (default: 500). |
heart_rate |
Heart rate in beats per minute (default: 72). |
noise_sd |
Standard deviation of baseline noise (default: 0.02). |
A list with two components:
PhysioExperiment object with the simulated ECG signal.
A data.frame with columns: beat, r_peak,
p_peak, q_point, s_point, t_peak,
qrs_onset, qrs_offset (all in sample indices).
Goldberger, A.L., et al. (2000). "PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals." Circulation, 101(23), e215–e220. doi:10.1161/01.CIR.101.23.e215
Clifford, G.D., Azuaje, F. & McSharry, P.E. (2006). Advanced Methods and Tools for ECG Data Analysis. Artech House.
make_ecg for basic ECG data,
ecgDelineate for PQRST waveform delineation,
ecgIntervals for computing clinical ECG intervals,
ecgDetectRpeaks for R-peak detection.
result <- make_ecg_pqrst(n_time = 10000, sr = 500, heart_rate = 72) pe <- result$pe fiducials <- result$fiducials head(fiducials)result <- make_ecg_pqrst(n_time = 10000, sr = 500, heart_rate = 72) pe <- result$pe fiducials <- result$fiducials head(fiducials)
Generates DC-offset PPG pulses from systolic and diastolic Gaussian waves plus a sharp foot dip, with optional respiratory amplitude modulation.
make_ppg( n_time = 15000, n_channels = 1, sr = 125, heart_rate = 72, dc = 2, sys_amp = 1, dia_amp = 0.4, crest_ms = 150, dia_offset_ms = 350, noise_sd = 0.02, foot_dip = 0.1, resp_freq = NULL, resp_depth = 0.3 )make_ppg( n_time = 15000, n_channels = 1, sr = 125, heart_rate = 72, dc = 2, sys_amp = 1, dia_amp = 0.4, crest_ms = 150, dia_offset_ms = 350, noise_sd = 0.02, foot_dip = 0.1, resp_freq = NULL, resp_depth = 0.3 )
n_time |
Number of samples. |
n_channels |
Number of PPG channels. |
sr |
Sampling rate in Hz. |
heart_rate |
Pulse rate in beats per minute. |
dc |
Non-pulsatile baseline level. |
sys_amp, dia_amp
|
Systolic and diastolic wave amplitudes. |
crest_ms |
Foot-to-systolic interval in milliseconds. |
dia_offset_ms |
Foot-to-diastolic interval in milliseconds. |
noise_sd |
Gaussian noise standard deviation. |
foot_dip |
Depth of the local foot minimum. |
resp_freq |
Optional respiratory amplitude-modulation frequency in Hz. |
resp_depth |
Fractional respiratory modulation depth. |
A list with pe, a PhysioExperiment, and truth, a fiducial
data frame (beat, foot, systolic, diastolic).
set.seed(1) simulation <- make_ppg(n_time = 3000) head(simulation$truth)set.seed(1) simulation <- make_ppg(n_time = 3000) head(simulation$truth)
Perfusion index is 100 times the pulsatile systolic-to-foot amplitude divided by the raw-signal DC level.
perfusionIndex(x, peaks = NULL, assay_name = NULL, agg = c("median", "mean"))perfusionIndex(x, peaks = NULL, assay_name = NULL, agg = c("median", "mean"))
x |
A raw, DC-preserving PPG |
peaks |
Optional systolic peak table from |
assay_name |
Optional raw PPG assay name. |
agg |
Aggregation of per-pulse AC amplitudes. |
A per-channel data frame containing AC, DC, perfusion index, and pulse count.
Charlton PH, Kyriacou PA, Mant J, et al. (2022). Wearable photoplethysmography for cardiovascular monitoring. Proceedings of the IEEE, 110:355-381. doi:10.1109/JPROC.2022.3149785
simulation <- make_ppg(n_time = 5000) perfusionIndex(simulation$pe)simulation <- make_ppg(n_time = 5000) perfusionIndex(simulation$pe)
Plots the ECG waveform with P, QRS and T fiducials from
ecgDelineate. The detected R-peak sample indices are attached as
the "peaks" attribute (a beat-editing hook); the delineation is
attached as "delineation".
plotEcgWave(x, peaks, channel = 1, window_sec = 10, assay_name = NULL)plotEcgWave(x, peaks, channel = 1, window_sec = 10, assay_name = NULL)
x |
A PhysioExperiment object with ECG data. |
peaks |
R-peak table from |
channel |
Channel to plot (default: 1). |
window_sec |
Seconds of signal to display from the start (default 10; NULL for the whole recording). |
assay_name |
Input assay name (default: first assay). |
A ggplot object with "peaks" and "delineation"
attributes.
Pan, J. & Tompkins, W.J. (1985). A real-time QRS detection algorithm. IEEE TBME, 32(3), 230-236.
pe <- make_ecg(5000, sr = 500) pk <- ecgDetectRpeaks(pe) plotEcgWave(pe, pk)pe <- make_ecg(5000, sr = 500) pk <- ecgDetectRpeaks(pe) plotEcgWave(pe, pk)
Plots the RR-interval power spectrum with the VLF, LF and HF bands shaded and
their integrated powers annotated. The PSD and band integration reuse the same
internals as ecgHRVfreq, so the shaded band areas equal the
ecgHRVfreq band powers. The band powers are attached as the
"band_power" attribute.
plotHRVpsd( rr, method = c("welch", "ar", "lomb"), detrend = FALSE, channel = NULL, vlf_band = c(0.003, 0.04), lf_band = c(0.04, 0.15), hf_band = c(0.15, 0.4) )plotHRVpsd( rr, method = c("welch", "ar", "lomb"), detrend = FALSE, channel = NULL, vlf_band = c(0.003, 0.04), lf_band = c(0.04, 0.15), hf_band = c(0.15, 0.4) )
rr |
An rr data.frame or an object from |
method |
Spectral method ("welch" default, "ar" or "lomb"), matching
|
detrend |
Smoothness-priors detrending, matching |
channel |
Channel to plot (default: first). |
vlf_band, lf_band, hf_band
|
Band edges (Hz). |
A ggplot object with a "band_power" attribute.
Task Force (1996). Heart rate variability. Circulation, 93(5), 1043-1065.
pe <- make_ecg(40000, sr = 500) rr <- ecgRRintervals(pe, ecgDetectRpeaks(pe)) plotHRVpsd(rr)pe <- make_ecg(40000, sr = 500) rr <- ecgRRintervals(pe, ecgDetectRpeaks(pe)) plotHRVpsd(rr)
Scatters each RR interval against the next ( vs ) and
overlays the Poincare SD1/SD2 dispersion ellipse from
ecgHRVpoincare. The SD1 and SD2 used for the ellipse are
attached as the "sd1"/"sd2" attributes of the returned plot.
plotPoincare(rr)plotPoincare(rr)
rr |
An rr data.frame or an object from |
A ggplot object with "sd1"/"sd2" attributes (per
channel).
Brennan, M., Palaniswami, M. & Kamen, P. (2001). Do existing measures of Poincare plot geometry reflect nonlinear features of heart rate variability? IEEE TBME, 48(11), 1342-1347.
ecgHRVpoincare, ecgHRVnonlinear
pe <- make_ecg(30000, sr = 500) rr <- ecgRRintervals(pe, ecgDetectRpeaks(pe)) plotPoincare(rr)pe <- make_ecg(30000, sr = 500) rr <- ecgRRintervals(pe, ecgDetectRpeaks(pe)) plotPoincare(rr)
Plots the RR interval series against time, marking ectopic beats when an
is_ectopic column is present.
plotTachogram(rr)plotTachogram(rr)
rr |
An rr data.frame (columns |
A ggplot object.
Task Force (1996). Heart rate variability. Circulation, 93(5), 1043-1065.
ecgRRintervals, ecgQualityCheck
pe <- make_ecg(20000, sr = 500) rr <- ecgQualityCheck(ecgRRintervals(pe, ecgDetectRpeaks(pe))) plotTachogram(rr)pe <- make_ecg(20000, sr = 500) rr <- ecgQualityCheck(ecgRRintervals(pe, ecgDetectRpeaks(pe))) plotTachogram(rr)
Implements the Elgendi two event-related moving-average (TERMA) detector. The shipped windowed-sinc FIR is used in place of the original Butterworth filter. Its linear-phase group delay is explicitly undone by snapping each event-block candidate to the corresponding raw-signal maximum.
ppgDetectPulses( x, w1_ms = 111, w2_ms = 667, beta = 0.02, low = 0.5, high = 8, order = 65, refractory_ms = 300, assay_name = NULL )ppgDetectPulses( x, w1_ms = 111, w2_ms = 667, beta = 0.02, low = 0.5, high = 8, order = 65, refractory_ms = 300, assay_name = NULL )
x |
A PPG |
w1_ms |
Systolic event window in milliseconds. |
w2_ms |
Beat window in milliseconds. |
beta |
Moving-average threshold offset. |
low, high
|
PPG band-pass cutoffs in Hz. |
order |
FIR order; even values are promoted to the next odd value. |
refractory_ms |
Minimum systolic-peak separation in milliseconds. |
assay_name |
Optional raw PPG assay name. |
This implementation uses the package's pure-R windowed-sinc FIR rather than
the Butterworth filter in the original method. A strong late dicrotic wave
may require increasing refractory_ms so that it is not counted as a second
systolic pulse.
A data frame with channel, sample, time_sec, and raw
amplitude.
Elgendi M, Norton I, Brearley M, Abbott D, Schuurmans D (2013). Systolic peak detection in acceleration photoplethysmograms measured from emergency responders in tropical conditions. PLoS ONE, 8:e76585. doi:10.1371/journal.pone.0076585
set.seed(1) simulation <- make_ppg(n_time = 3000) head(ppgDetectPulses(simulation$pe))set.seed(1) simulation <- make_ppg(n_time = 3000) head(ppgDetectPulses(simulation$pe))
Computes population skewness and raw kurtosis, either per channel or in non-overlapping windows.
ppgQuality(x, window_sec = NULL, skew_threshold = -0.3, assay_name = NULL)ppgQuality(x, window_sec = NULL, skew_threshold = -0.3, assay_name = NULL)
x |
A PPG |
window_sec |
Optional non-overlapping window duration in seconds. |
skew_threshold |
Minimum skewness SQI accepted as usable. |
assay_name |
Optional raw PPG assay name. |
A data frame with channel, segment, start time, skewness SQI, kurtosis SQI, and acceptance flag.
Elgendi M (2016). Optimal signal quality index for photoplethysmogram signals. Bioengineering, 3:21. doi:10.3390/bioengineering3040021
simulation <- make_ppg(n_time = 2000) ppgQuality(simulation$pe)simulation <- make_ppg(n_time = 2000) ppgQuality(simulation$pe)
Extracts amplitude modulation, baseline wander, or frequency modulation from successive PPG pulses, resamples the feature to a uniform grid, and estimates its respiratory-band spectral peak.
ppgRespiration( x, peaks = NULL, method = c("am", "bw", "fm"), fs = 4, resp_band = c(0.1, 0.5), assay_name = NULL )ppgRespiration( x, peaks = NULL, method = c("am", "bw", "fm"), fs = 4, resp_band = c(0.1, 0.5), assay_name = NULL )
x |
A raw PPG |
peaks |
Optional systolic peak table from |
method |
|
fs |
Uniform feature resampling rate in Hz. |
resp_band |
Two-element respiratory band in Hz. |
assay_name |
Optional raw PPG assay name. |
A list containing method, per-pulse features, uniformly resampled EDR-like traces, and respiratory rates.
Charlton PH, Bonnici T, Mainardi L, et al. (2016). An assessment of algorithms to estimate respiratory rate from the electrocardiogram and photoplethysmogram. Physiological Measurement, 37:610-626. doi:10.1088/0967-3334/37/4/610
set.seed(1) simulation <- make_ppg(n_time = 15000, resp_freq = 0.25) ppgRespiration(simulation$pe)set.seed(1) simulation <- make_ppg(n_time = 15000, resp_freq = 0.25) ppgRespiration(simulation$pe)
Converts detected PPG pulses to pulse-to-pulse intervals and delegates time-, frequency-, and optional nonlinear-domain metrics to the existing HRV engine with ECG rhythm gating disabled.
pulseRateVariability( x, peaks = NULL, freq = TRUE, nonlinear = FALSE, assay_name = NULL, ... )pulseRateVariability( x, peaks = NULL, freq = TRUE, nonlinear = FALSE, assay_name = NULL, ... )
x |
A PPG |
peaks |
Optional peak table from |
freq |
Logical; calculate frequency-domain PRV. |
nonlinear |
Logical; calculate nonlinear PRV. |
assay_name |
Optional raw PPG assay name. |
... |
Detection arguments passed to |
A named list containing ppi, time, freq, and nonlinear.
Schafer A, Vagedes J (2013). How accurate is pulse rate variability as an estimate of heart rate variability? International Journal of Cardiology, 166:15-29. doi:10.1016/j.ijcard.2012.03.119
simulation <- make_ppg(n_time = 15000) pulseRateVariability(simulation$pe, freq = FALSE)simulation <- make_ppg(n_time = 15000) pulseRateVariability(simulation$pe, freq = FALSE)
Measures foot-to-systolic rise time, pulse amplitude, dicrotic and diastolic fiducials, reflection and augmentation indices, pulse width, and optional ECG-to-PPG pulse transit time and pulse-wave velocity.
pulseWaveFeatures( x, peaks = NULL, ecg_peaks = NULL, distance_m = NULL, assay_name = NULL )pulseWaveFeatures( x, peaks = NULL, ecg_peaks = NULL, distance_m = NULL, assay_name = NULL )
x |
A raw PPG |
peaks |
Optional systolic peak table from |
ecg_peaks |
Optional ECG R-peak table containing |
distance_m |
Optional ECG-to-PPG path length in metres for PWV. |
assay_name |
Optional raw PPG assay name. |
A data frame with one row per pulse and waveform/PTT/PWV features.
Elgendi M (2012). On the analysis of fingertip photoplethysmogram signals. Current Cardiology Reviews, 8:14-25. doi:10.2174/157340312801215782
simulation <- make_ppg(n_time = 5000) head(pulseWaveFeatures(simulation$pe))simulation <- make_ppg(n_time = 5000) head(pulseWaveFeatures(simulation$pe))
Detects end-expiratory troughs in a zero-phase band-passed respiratory signal. Consecutive troughs delimit complete breaths, and the intervening maximum marks end inspiration.
respiratoryOnsets( x, channel = NULL, band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )respiratoryOnsets( x, channel = NULL, band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )
x |
A |
channel |
Optional channel index or label. |
band |
Two-element respiratory band in Hz. |
min_period_sec |
Minimum breath period in seconds. |
sr |
Sampling rate for a numeric vector. |
assay_name |
Optional assay name for a |
A data frame with one row per complete breath, containing sample and time coordinates for onset, peak, and offset plus inspiratory amplitude.
breathingRate(), tidalMetrics(), ripCalibrate()
sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) head(respiratoryOnsets(signal, sr = sr))sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) head(respiratoryOnsets(signal, sr = sr))
Fits the Konno-Mead two-degree-of-freedom volume model from ribcage and abdominal belt signals. Least-squares calibration uses a reference volume trace; qualitative diagnostic calibration (QDC) equalizes the variability of the two belt contributions.
ripCalibrate( rc, ab, reference = NULL, sr = NULL, method = c("qdc", "lsq"), band = c(0.1, 0.6), window = NULL, fit_intercept = FALSE, known_volume = NULL )ripCalibrate( rc, ab, reference = NULL, sr = NULL, method = c("qdc", "lsq"), band = c(0.1, 0.6), window = NULL, fit_intercept = FALSE, known_volume = NULL )
rc |
Ribcage signal as a numeric vector, or a |
ab |
Abdominal numeric vector, or a channel index/label when |
reference |
Optional reference volume signal, required for |
sr |
Sampling rate in Hz for numeric signals. A |
method |
Calibration method, |
band |
Two-element respiratory band in Hz. |
window |
Optional inclusive calibration sample range |
fit_intercept |
Logical; include an intercept in least squares. |
known_volume |
Optional known inspiratory volume used for absolute scaling. |
A rip_calibration object containing coefficients, calibration
diagnostics, and the calibrated volume-proportional signal.
Konno K, Mead J (1967). Measurement of the separate volume changes of rib cage and abdomen during breathing. Journal of Applied Physiology, 22:407-422.
Sackner MA, Watson H, Belsito AS, et al. (1989). Calibration of respiratory inductive plethysmograph during natural breathing. Journal of Applied Physiology, 66:410-420. doi:10.1152/jappl.1989.66.1.410
sr <- 10 time <- (0:599) / sr rc <- 2 * sin(2 * pi * 0.25 * time) ab <- sin(2 * pi * 0.25 * time) ripCalibrate(rc, ab, sr = sr)sr <- 10 time <- (0:599) / sr rc <- 2 * sin(2 * pi * 0.25 * time) ab <- sin(2 * pi * 0.25 * time) ripCalibrate(rc, ab, sr = sr)
Removes slow trends from a uniformly sampled series (e.g. an interpolated
RR tachogram) using the smoothness-priors method of Tarvainen et al. (2002).
The trend estimate is where
is the second-order difference operator, and the detrended
(stationary) component is . Larger lambda lowers the cutoff frequency,
removing more low-frequency content.
smoothnessPriorsDetrend(series, lambda = 500, fs = 4)smoothnessPriorsDetrend(series, lambda = 500, fs = 4)
series |
Numeric vector, uniformly sampled. |
lambda |
Smoothing parameter (regularisation). Higher values remove slower trends (lower cutoff). Default 500. |
fs |
Sampling rate of |
The detrended series (numeric vector, near-zero mean), carrying
attributes lambda and cutoff_hz (the approximate half-power
cutoff of the implied high-pass filter).
Tarvainen, M.P., Ranta-aho, P.O. & Karjalainen, P.A. (2002). An advanced detrending method with application to HRV analysis. IEEE Transactions on Biomedical Engineering, 49(2), 172-175.
t <- seq(0, 60, by = 0.25) x <- 0.01 * t + sin(2 * pi * 0.25 * t) # slow trend + HF oscillation xd <- smoothnessPriorsDetrend(x, lambda = 500, fs = 4) abs(mean(xd)) < 1e-6t <- seq(0, 60, by = 0.25) x <- 0.01 * t + sin(2 * pi * 0.25 * t) # slow trend + HF oscillation xd <- smoothnessPriorsDetrend(x, lambda = 500, fs = 4) abs(mean(xd)) < 1e-6
Derives inspiratory and expiratory timing, duty cycle, tidal amplitude, mean inspiratory flow, breathing rate, and minute ventilation.
tidalMetrics( x, onsets = NULL, channel = NULL, calibration = NULL, band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )tidalMetrics( x, onsets = NULL, channel = NULL, calibration = NULL, band = c(0.1, 0.6), min_period_sec = 1, sr = NULL, assay_name = NULL )
x |
A respiration signal source accepted by |
onsets |
Optional precomputed table from |
channel, band, min_period_sec, sr, assay_name
|
As in
|
calibration |
Optional |
A named list containing per-breath breaths and per-channel
summary data frames.
sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) tidalMetrics(signal, sr = sr)sr <- 10 signal <- sin(2 * pi * 0.25 * (0:599) / sr) tidalMetrics(signal, sr = sr)
VT1 is estimated by V-slope breakpoint regression of VCO2 on VO2. VT2 is estimated above VT1 from the breakpoint of VE on VCO2.
ventilatoryThreshold( vo2, vco2 = NULL, ve = NULL, time = NULL, average_n = 1L, min_segment = 3L )ventilatoryThreshold( vo2, vco2 = NULL, ve = NULL, time = NULL, average_n = 1L, min_segment = 3L )
vo2 |
Numeric VO2 vector, or a data frame containing |
vco2, ve
|
Numeric vectors matching |
time |
Optional time vector. For data-frame input, an existing |
average_n |
Positive integer number of ordered samples per block mean. |
min_segment |
Minimum number of observations fitted on each side of a breakpoint. |
A ventilatory_threshold object with VT1, VT2, and the data actually
fitted.
Beaver WL, Wasserman K, Whipp BJ (1986). A new method for detecting anaerobic threshold by gas exchange. Journal of Applied Physiology, 60:2020-2027. doi:10.1152/jappl.1986.60.6.2020
vo2 <- seq(1, 3, by = 0.05) vco2 <- ifelse(vo2 <= 2, 0.9 * vo2, 1.8 + 1.3 * (vo2 - 2)) ventilatoryThreshold(vo2, vco2, ve = 25 * vco2)vo2 <- seq(1, 3, by = 0.05) vco2 <- ifelse(vo2 <= 2, 0.9 * vo2, 1.8 + 1.3 * (vo2 - 2)) ventilatoryThreshold(vo2, vco2, ve = 25 * vco2)