## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----pulse, out.width = "250px", echo = FALSE, fig.align = "left"------------- knitr::include_graphics("images/pulse.jpg") ## ----packages----------------------------------------------------------------- # library(tidyverse) library(dplyr) library(stringr) library(tibble) library(ggplot2) library(heartbeatr) ## ----input_header------------------------------------------------------------- # pulse example allows quick access to test files fn <- pulse_example()[1] head <- read.csv(fn, nrows = 50, col.names = c("field", "value")) skip <- max(grep("----------------", head$field)) head[1:skip,] ## ----input_data, results = "hide"--------------------------------------------- read.csv(fn, skip = skip + 1) ## ----input_data_print, echo = FALSE------------------------------------------- read.csv(fn, skip = skip + 1, nrows = 5) ## ----workflow_read1----------------------------------------------------------- pulse_data <- pulse_read( paths = pulse_example(), msg = FALSE ) ## ----o------------------------------------------------------------------------ channels <- paste0("c", formatC(1:10, width = 2, flag = "0")) discard <- c("c01", "c02", "c05", "c07", "c08", "c09", "c10") pulse_data$data <- pulse_data$data[, c("time", setdiff(channels, discard))] pulse_data$data ## ----workflow_split1---------------------------------------------------------- pulse_data_split <- pulse_split( pulse_data = pulse_data, window_width_secs = 30, window_shift_secs = 60, msg = FALSE ) pulse_data_split ## ----workflow_split2---------------------------------------------------------- pulse_data_split$data[[1]] ## ----workflow_optimize1------------------------------------------------------- pulse_data_optimized <- pulse_optimize( pulse_data_split = pulse_data_split, interpolation_freq = 40, bandwidth = 0.75, raw_v_smoothed = FALSE, multi = TRUE ) ## ----workflow_optimize2------------------------------------------------------- pulse_data_split ## ----workflow_optimize3------------------------------------------------------- pulse_data_optimized ## ----workflow_optimize4, echo = FALSE, fig.height = 1, fig.width = 6---------- x <- bind_rows( pulse_data_split$data[[1]] |> tibble::add_column(opt = "raw") |> dplyr::select(t = time, opt, val = c04), pulse_data_optimized$data[[1]] |> tibble::add_column(opt = "opt") |> dplyr::select(t = time, opt, val = c04) ) |> dplyr::mutate(opt = factor(opt, levels = c("raw", "opt"))) ggplot(x) + geom_line(aes(t, val, col = opt)) + # facet_grid(rows = vars(opt)) + # scale_color_manual(values = c("raw" = "black", "opt" = "red"), guide = "none") + scale_color_manual(values = c("raw" = "grey20", "opt" = "red"), name = NULL) + theme_void() ## ----workflow_heart1---------------------------------------------------------- heart_rates <- pulse_heart( pulse_data_split = pulse_data_optimized, msg = FALSE ) heart_rates ## ----workflow_double1--------------------------------------------------------- heart_rates <- pulse_doublecheck( heart_rates = heart_rates ) heart_rates ## ----workflow_double3, echo = FALSE, fig.height = 1, fig.width = 6------------ heart_rates_double <- PULSE( pulse_example(), window_width_secs = 30, window_shift_secs = 60, bandwidth = 0.55, discard_channels = discard, raw_v_smoothed = FALSE, correct = FALSE) heart_rates_corr <- PULSE( pulse_example(), window_width_secs = 30, window_shift_secs = 60, bandwidth = 0.75, discard_channels = discard, raw_v_smoothed = FALSE, correct = TRUE) x <- bind_rows( heart_rates_double |> dplyr::filter(id == "c03", i == 9) |> dplyr::pull(data) |> dplyr::first() |> tibble::add_column(opt = "double peaks"), heart_rates_corr |> dplyr::filter(id == "c03", i == 9) |> dplyr::pull(data) |> dplyr::first() |> tibble::add_column(opt = "corrected") ) |> dplyr::mutate(opt = factor(opt, levels = c("double peaks", "corrected"))) pulse_plot_one(x) + ggplot2::facet_grid(rows = vars(opt)) + ggplot2::theme_void() ## ----workflow_keep1----------------------------------------------------------- heart_rates <- pulse_choose_keep( heart_rates = heart_rates ) heart_rates ## ----workflow_keep2----------------------------------------------------------- dplyr::filter(heart_rates, keep) ## ----simple1------------------------------------------------------------------ # the code below takes approximately 30 seconds # to run on a machine with the following specs: # - MacBook Air 2022 # - chip: Apple M2 # - memory: 16 GB RAM # - macOS: Sequoia 15.3.1 heart_rates_PULSE <- PULSE( paths = pulse_example(), window_width_secs = 30, window_shift_secs = 60, bandwidth = 0.75, raw_v_smoothed = FALSE, discard_channels = discard ) heart_rates_PULSE ## ----simple2------------------------------------------------------------------ identical(heart_rates_PULSE, heart_rates) ## ----plot_all1, fig.height = 4, fig.width = 6--------------------------------- pulse_plot(heart_rates) ## ----plot_all1b, fig.height = 4, fig.width = 6-------------------------------- pulse_plot(dplyr::filter(heart_rates, keep)) ## ----plot_all2, fig.height = 3, fig.width = 6--------------------------------- pulse_plot( dplyr::filter(heart_rates, keep), facets = FALSE, bpm = TRUE, smooth = FALSE, points = FALSE ) ## ----plot_all3, fig.height = 4, fig.width = 6--------------------------------- pulse_plot(filter(heart_rates, keep)) + ggplot2::geom_vline(ggplot2::aes(xintercept = mean(heart_rates$time))) + ggplot2::theme_bw() + ggplot2::ggtitle("example") ## ----plot_all4, fig.height = 3, fig.width = 6--------------------------------- pulse_plot(dplyr::filter(heart_rates, keep), ID = "c03") ## ----plot_raw1---------------------------------------------------------------- dplyr::filter(heart_rates, id == "c03") ## ----plot_raw2, fig.height = 3, fig.width = 6--------------------------------- pulse_plot_raw(heart_rates, ID = "c03", target_i = 7) ## ----plot_raw3, fig.height = 3, fig.width = 6--------------------------------- pulse_plot_raw(heart_rates, ID = "c03", target_time = "2024-10-01 10:58") ## ----plot_raw4, fig.height = 6, fig.width = 6--------------------------------- pulse_plot_raw(heart_rates, ID = "c03", target_time = "2024-10-01 10:58", range = 2) ## ----bw1---------------------------------------------------------------------- x_02 <- PULSE( paths = pulse_example(), bandwidth = 0.2, raw_v_smoothed = FALSE, discard_channels = paste0("c0", 1:9), subset = 10, subset_seed = 1, subset_reindex = TRUE, show_progress = FALSE) x_15 <- PULSE( paths = pulse_example(), bandwidth = 1.5, raw_v_smoothed = FALSE, discard_channels = paste0("c0", 1:9), subset = 10, subset_seed = 1, subset_reindex = TRUE, show_progress = FALSE) ## ----bw2, fig.height = 2, fig.width = 6--------------------------------------- # when bandwith = 0.2, too many peaks are identified pulse_plot_raw(x_02, ID = "c10", target_i = 1) # when bandwith = 0.5, only one peak is identified in each heartbeat, as it should pulse_plot_raw(x_15, ID = "c10", target_i = 1) ## ----plot_norm1--------------------------------------------------------------- heart_rates_norm <- pulse_normalize( dplyr::filter(heart_rates, keep), t0 = "2024-10-01 10:52", span_mins = 5 ) heart_rates_norm ## ----plot_norm2, fig.height = 3, fig.width = 6-------------------------------- pulse_plot(heart_rates_norm, normalized = FALSE, facets = FALSE) pulse_plot(heart_rates_norm, normalized = TRUE, facets = FALSE) ## ----plot_sum1---------------------------------------------------------------- heart_rates_sum <- pulse_summarise( heart_rates_norm, FUN = mean, span_mins = 5, min_data_points = 0) heart_rates_sum ## ----plot_sum2, fig.height = 3, fig.width = 6--------------------------------- pulse_plot(heart_rates_sum, normalized = FALSE, facets = FALSE)