--- title: detectPVC User Guide output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{detectPVC User Guide} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8](inputenc) --- ```{r knitr_options, include=FALSE} library(knitr) opts_chunk$set(fig.width=9, fig.height=4.5, dev.args=list(pointsize=16)) ``` [![R-CMD-check](https://github.com/kbroman/detectPVC/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/kbroman/detectPVC/actions/workflows/R-CMD-check.yaml) [![r-universe badge](https://kbroman.r-universe.dev/detectPVC/badges/version)](https://kbroman.r-universe.dev/detectPVC) [![zenodo DOI](https://zenodo.org/badge/794298079.svg)](https://zenodo.org/doi/10.5281/zenodo.11174768) ### Introduction detectPVC logo [detectPVC](https://github.com/kbroman/detectPVC) is an R package to detect premature ventricular complexes (PVCs) in data from a [Polar H10](https://www.polar.com/us-en/sensors/h10-heart-rate-sensor) chest-strap heart rate sensor. We have used the [ECGLogger app](https://www.ecglogger.com/) on an iPhone to extract the Polar H10 data as a CSV file (or really a series of CSV files, in one hour blocks), and the [rsleep](https://rsleep.org/) package to detect R peaks in the ECG signal. ### Installation You can install the detectPVC package from [R-universe](https://kbroman.r-universe.dev/detectPVC). ```{r install_r-universe, eval=FALSE} install.packages("detectPVC", repos="https://kbroman.r-universe.dev") ``` Alternatively, install it from [GitHub](https://github.com/kbroman/detectPVC). You first need to install the [remotes](https://remotes.r-lib.org) package. ```{r install_remotes, eval=FALSE} install.packages("remotes") ``` Then use `remotes::install_github()`: ```{r, install_github, eval=FALSE} library(remotes) install_github("kbroman/detectPVC") ``` ### Usage The library comes with a 10-min sample data set, `polar_h10`. ```{r, load_package_and_data} library(detectPVC) data(polar_h10) ``` ```{r options, include=FALSE} knitr::opts_chunk$set(fig.width=11, fig.height=4, fig.path="figures/") ``` Convert the included times (which are time stamps from a Polar H10, in 1e-9 seconds) to standard date-time values. ```{r, convert_timestamps} polar_h10$datetime <- convert_timestamp(polar_h10$time) ``` First detect bad segments in the data, with either wild values or missing data points. ```{r, find_bad_segments} bad_segs <- find_bad_segments(polar_h10$datetime, polar_h10$ecg) ``` For this example, there is just one bad segment, covering about `r round(totlength(bad_segs, polar_h10$datetime))` sec. You can get the total covered length in seconds with `tot_length()`. ```{r length_bad_segments} totlength(bad_segs, polar_h10$datetime) ``` Use `detect_peaks()` to detect "R" peaks in the ECG trace. ```{r detect_peaks} peaks <- detect_peaks(polar_h10$datetime, polar_h10$ecg, omit_segments=bad_segs) ``` Plot the first 20 seconds of data, and add points above the peaks. The function `plot_ecg()` is a base-graphics-based plotting function with light gray grid lines. ```{r plot_data} v <- get_time_interval(polar_h10$datetime, start=polar_h10$datetime[1], length=20) plot_ecg(polar_h10$datetime[v], polar_h10$ecg[v]) points(polar_h10$datetime[peaks], polar_h10$ecg[peaks], pch=16, col="slateblue") ``` Use `calc_peak_stats()` to calculate some statistics about each peak. ```{r calc_peak_stats} peak_stats <- calc_peak_stats(polar_h10$datetime, polar_h10$ecg, peaks) ``` The simplest rule for classifying PVCs is to take `RStime > 50`. The statistic `RStime` is the time between the R and S peaks in milliseconds. ```{r classify_pvc} pvc <- (peak_stats$RStime > 50) ``` Label the inferred PVCs with pink dots, and the others with green dots. ```{r plot_data_with_pvc} plot_ecg(polar_h10$datetime[v], polar_h10$ecg[v]) points(polar_h10$datetime[peaks], polar_h10$ecg[peaks], pch=16, col=c("green3", "violetred")[pvc+1]) ``` In this `r round(totlength(rbind(range(v)), polar_h10$datetime))` second window, there are `r sum(peaks[pvc] %in% v)` PVCs in `r sum(peaks %in% v)` total beats. --- [![CC BY](https://i.creativecommons.org/l/by/3.0/88x31.png)](https://creativecommons.org/licenses/by/3.0/)     [Karl Broman](https://kbroman.org/)