The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

CardiacDP

CardiacDP (Cardiac Data Processing) can automatically read and collate heart rate data, and compute average heart rate per analysis interval (sequence). The analysis employs the autocorrelation function (ACF) with a genetic algorithm framework to identify periods of repeating waveforms within each sequence. These candidate heart rates of sub-sequences are then evaluated either by the autocorrelation value or a tracking index (TI), and finally weighted as the final output.

Package structure

Installation

install.packages("CardiacDP")

# Or from GitHub
devtools::install_github("Vicellken/CardiacDP")

# Or the source package from GitHub:
# Vector of package names
packages <- c("data.table", "doParallel", "dplyr", "foreach", "ggplot2", "purrr", "RColorBrewer", "stringr")

lapply(packages, function(pkg) {
  if (!require(pkg, character.only = TRUE)) {
    install.packages(pkg)
  }
})

# Install the source package
install.packages("CardiacDP_0.4.2.tar.gz", repos = NULL, type = "source")

Example

This is an example showing the complete analysis pipeline:

library(CardiacDP)

zip_path <- "~/rawfiles.zip" # PATH_TO_ZIP_FILE

# csv_path <- "" # PATH_TO_COLLATED_CSV

# run computeHR() for average heart rate analysis (no files are written by default)
output <- computeHR(
  file_path = csv_path, # collatedata() will automatically run if zip_path is directly provided here
  save_outputs = TRUE,
  output_dir = NULL, # PATH_TO_STORE_OUTPUTS
  verbose = TRUE)

The user can access the output by the channel name. finalsubseq is a list showing the positions and durations of the final periodic sub-sequences determined for each sequence. They are presented as data tables (s = start index of the sub-sequence; e = end index of the sub-sequence; p = which of the initial population the sub-sequence is derived from; and f = duration of the sub-sequence), the rows of which represent separate final sub-sequences.

# positions (in indices) and durations of the final sub-sequences
# NOTE: the results are not included here for simplicity. For more details please refer to Supplementary Information S4 of the publication / User guideline.pdf

# output[["finalsubseq"]][["Channel A"]]

The corresponding candidate heart rates per sub-sequences can be found in candidateHR (ACF = autocorrelation value; lag = time lag; and hr = heart rate).

# candidate heart rates of the final sub-sequences
# NOTE: the results are not included here for simplicity. For more details please refer to Supplementary Information S4 of the publication / User guideline.pdf

# output[["candidateHR"]][["Channel A"]]

The final results after evaluating the candidate heart rates, checking for resolution and weighting for durations can eventually be obtained from results_ACF and results_TI. These results referred to evaluating the candidate heart rates by merely autocorrelation values (i.e. the “ACF + GA” approach in the publication) or the tracking index (i.e. the “ACF + GA +TI” approach in the publication) respectively. Each of them consists of 1) the details of the sub-sequences (subseqHR); 2) the weighted heart rate per sequence (weightedHR); and 3) a plot of weighted heart rate against time (plot).

## results obtained from evaluating the candidate heart rates by autocorrelation values
# output[["results_ACF"]][["Channel A"]]

# results obtained from evaluating the candidate heart rates by the tracking index
# output[["results_TI"]][["Channel A"]]

Interpret results

Variable Content
finalsubseq A list of positions and durations of the final periodic sub-sequences
candidateHR A list of candidate heart rates extracted from ACF for each sub-sequence
results_ACF Results obtained from evaluating the candidate heart rates of each sub-sequence based on autocorrelation values (i.e. following the “ACF + GA” approach as described in the main manuscript). Consisted of three items: 1) subseqHR: a list of sub-sequences and the corresponding heart rates and durations; 2) weightedHR: a list of final heart rates per sequence after weighing; and 3) plot: a plot of final heart rates against time
results_TI Results obtained from evaluating the candidate heart rates of each sub-sequence using a tracking index (i.e. following the “ACF + GA + TI” approach as described in the main manuscript). Consisted of three items: 1) subseqHR: a list of sub-sequences and the corresponding heart rates and durations; 2) weightedHR: a list of final heart rates per sequence after weighing; and 3) plot: a plot of final heart rates against time

Automatically saved files

By default, computeHR() does not write any files. If you want CSV/PNG outputs, set save_outputs = TRUE and optionally provide output_dir (if output_dir is NULL, it defaults to tempdir()):

csv_path <- system.file("extdata", "example.csv", package = "CardiacDP")
output <- computeHR(
  file_path = csv_path,
  save_outputs = TRUE,
  output_dir = tempdir()
)

CSV Files

For each channel and method (ACF and TI), the following CSV files are saved:

Note: Channel names with spaces (e.g., “Channel A”) are converted to underscores (e.g., “Channel_A”) in filenames.

PNG Files

For each channel and method, heart rate plots are saved:

Column descriptions

weightedHR CSV files contain:

subseqHR CSV files contain:

Reproducing plots from saved CSV files

The saved CSV files contain all the data needed to reproduce the heart rate plots. Use the weightedHR CSV files for plotting:

library(ggplot2)
library(RColorBrewer)
library(data.table)

# Read the saved weighted heart rate data (example; assumes you ran computeHR(save_outputs=TRUE))
channel <- "Channel A"
data <- fread(paste0(gsub(" ","_",channel),"_TI_weightedHR.csv"))

# Create the plot (matching the package output)
palette <- brewer.pal(n = 11, name = "RdYlBu")
names(palette) <- seq(0, 10, 1) / 10

# analysis interval (by default 1 min)
an_in <- 1

ggplot() +
  geom_point(
    data = data,
    aes(x = ix * an_in, y = whr, fill = factor(floor(wACF * 10) / 10)),
    colour = "black", shape = 21, size = 4, alpha = 0.8
  ) +
  scale_fill_manual(
    name = "ACF", values = palette, na.value = NA,
    na.translate = FALSE, guide = "legend"
  ) +
  scale_y_continuous(
    name = "Heart rate (bpm)",
    breaks = seq(0, ceiling(max(data$whr, na.rm = TRUE) / 50) * 50, 50),
    limits = c(0, ceiling(max(data$whr, na.rm = TRUE) / 50) * 50),
    expand = c(0, 0)
  ) +
  scale_x_continuous(
    name = "Time (min)",
    breaks = seq(0, ceiling(max(data$Time_min, na.rm = TRUE) / 30) * 30, 30),
    limits = c(0, ceiling(max(data$Time_min, na.rm = TRUE) / 30) * 30),
    expand = c(0, 0)
  ) +
  theme_linedraw() +
  theme(
    text = element_text(size = 12, colour = "black"),
    panel.grid.minor = element_blank(),
    panel.border = element_rect(fill = NA, colour = "black", linewidth = 1)
  )

Key columns for plotting:

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.