@examples added or corrected across 16 help pages. Each runs
offline in seconds, writes nothing outside tempdir(), and is executed by
R CMD check; anything needing a device, a download or an optional backend is
fenced with the reason stated.ecgHRVgeometric() now also accepts an RR data frame (with an rr_ms column, as produced by the
RR-interval readers), not only a numeric vector — aligning its interface with ecgHRVtime(). Its HRV
triangular index (HTI) is cross-tool certified against NeuroKit2.hrv_time HRV_HTI (bit-for-bit) on
real Fantasia RR; TINN differs by a documented triangular-interpolation convention.ecgHRVautonomic() — cardiac autonomic indices (Toichi 1997) from the Poincare 4-SD box:
the Cardiac Sympathetic Index (CSI = L/T = SD2/SD1), the Cardiac Vagal Index
(CVI = log10(L*T)), and the Modified CSI (L^2/T; Jeppesen 2014, seizure detection). SD1 =
SDSD/sqrt(2) (universal), SD2 = geometric paired-projection. Reproduces NeuroKit2's
hrv_nonlinear CSI/CVI/CSI_Modified bit-for-bit.ecgHRVasymmetry() — heart-rate asymmetry (HRA) Poincare-plot asymmetry descriptors
(Guzik 2006; Piskorski & Guzik 2011): the Guzik/Slope/Area/Porta indices (GI/SI/AI/PI) and
the deceleration/acceleration contributions to short-term (C1d/C1a), long-term (C2d/C2a), and
total (Cd/Ca) HRV. Quantifies the temporal irreversibility of heart-rate dynamics —
decelerations (RR prolongations) and accelerations (shortenings) contribute unequally to
variability. Complements the symmetric ecgHRVpoincare() (SD1/SD2). Reproduces NeuroKit2's
hrv_nonlinear HRA indices bit-for-bit (max |diff| ~1e-14).ecgDFA() (and the internal .dfa_alpha1() used by ecgDFArolling()) now
generate logarithmically-spaced scales instead of linearly-spaced ones.
With linear spacing, a long RR series (where n/4 is far larger than 64) left
the short-range window [4, 16] with a single scale and the long-range window
[16, 64] empty, so the slope fits returned NA — ecgDFA() produced
alpha1 = alpha2 = NA on real overnight recordings (thousands of beats) even
though it worked on short (a few-hundred-beat) test series. DFA requires
log-spaced scales; both windows are now populated and alpha1/alpha2 are
computed correctly. Verified on synthetic signals with known exponents (white
noise → α ≈ 0.5, random walk → α ≈ 1.5) and against nolds.dfa. Added
regression tests covering a long (6000-beat) series and the known exponents.test-mitbih-validation.R, fixture tests/testthat/fixtures/mitbih-reference.rds,
generated by data-raw/ecg_mitbih_reference.{py,R}), replacing the synthetic-RR
substitute in the ECG "real data" path (VAL-05). ecgDetectRpeaks() is scored
against cardiologist beat annotations (AAMI EC57, +/-150 ms): F1 = 1.0 on the
clean record 100 and F1 = 0.97 on the noisiest record 203. ecgHRVtime()
reproduces the standard SDNN/RMSSD/pNN50 definitions exactly on a 5-minute real
RR series and agrees with RHRV to < 1%.make_ppg() for reproducible PPG examples with known pulse fiducials.Initial release of PhysioECG as a standalone package in the x-biosignal
ecosystem, split out from the PhysioExperiment monolith. Provides
electrocardiography (ECG) analysis for PhysioExperiment objects, spanning
R-peak detection, heart rate variability (HRV), waveform morphology, and
signal-quality assessment.
Multi-detector QRS / R-peak detection via ecgDetectRpeaks(), offering four
algorithms behind a common bandpass front end with automatic inverted-lead
handling: adaptive Pan-Tompkins (default), Hamilton, Elgendi, and Christov.
ecgRRintervals() derives the RR-interval series that feeds every HRV
routine.
Time-domain HRV via ecgHRVtime() (SDNN, RMSSD, pNN50, mean RR, mean HR),
with geometric indices (ecgHRVgeometric(); triangular index and TINN) and
long-term segmented indices (ecgHRVsegmented(); SDANN, SDNN index).
Frequency-domain HRV via ecgHRVfreq(), estimating VLF/LF/HF band power,
LF/HF ratio, normalized units, and in-band peak frequencies from a
Welch, Lomb-Scargle, or Burg autoregressive spectrum, with optional
smoothness-priors detrending of the resampled tachogram.
Nonlinear HRV:
ecgHRVpoincare() for Poincare descriptors (SD1, SD2, SD1/SD2).ecgSampleEntropy() for regularity of the RR series.ecgDFA() for detrended fluctuation analysis, plus ecgHRVnonlinear()
as a convenience wrapper combining the nonlinear metrics.ecgDFArolling() for a time-resolved DFA alpha1 trajectory and
dfaThresholdCrossings() for the Gronwald & Rogers exercise-intensity
thresholds (AT1 alpha1 = 0.75, AT2 alpha1 = 0.5).ECG waveform morphology via ecgDelineate() (QRS onset/offset, P- and
T-wave peaks per beat) and ecgIntervals(), which reports PR, QT, and QRS
durations with rate-corrected QT by Bazett, Fridericia, Framingham, and
Hodges formulas.
Rhythm gating via ecgDetectAF(), classifying each channel as sinus,
atrial fibrillation, or frequent ectopy from RR irregularity (ectopic
fraction, RMSSD/mean-RR ratio, and normalized dRR Shannon entropy). The
time-, frequency-, and nonlinear-domain HRV functions honor a
rhythm_check argument that invalidates HRV metrics for non-sinus channels,
where HRV is physiologically undefined.
Signal quality and cleaning:
ecgSignalQuality() for per-channel SNR, baseline wander, saturation,
and a composite quality score.ecgBeatSQI() and ecgBeatSQIgate() for a beat-level quality index from
the agreement between two independent QRS detectors.ecgQualityCheck(), ecgRRcorrect(), and ecgEctopicBurden() for
ectopic-beat detection, linear or cubic-spline correction, and burden
reporting.ecgBaselineCorrect() for baseline-wander removal and
smoothnessPriorsDetrend() for detrending a uniformly sampled series.Synthetic ECG generators for examples and testing: make_ecg(),
make_ecg_irregular(), make_ecg_pqrst(), and make_ecg_noisy().