knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file()) # Set WD to Root here::i_am("dev/hrv.Rmd") library(here)
Function
read_HRV_reports
: (USER) a wrapper
path-to-hrv-folder
parse_HRV_reports
(USER)
new_extract_HRV_field
(Internal): a constructor of extract_HRV_field
extract_HRV_field
(Internal ?)
Example
extract_HRV_field$Name()
Lookup
regex_hrv()
(internal): Function that return look up list for HRV regex.
HRV_vars_desc
: variable and description of HRV report.
HRV_vars_domain
: list containing variable names of time and frequency domain.
usethis::use_r("HRV_reports") rstudioapi::navigateToFile("tests/testthat/test-HRV_reports.R") # usethis::use_test("HRV_reports")
read_HRV_reports <- function(file, format_cols = TRUE, encoding = "UTF-16LE", ... ){ # Read Raw df_raw <- readtext::readtext(file = file, encoding = encoding, ... ) # Parse Character to HRV tibble df_hrv <- parse_HRV_reports(df_raw[["text"]], format_cols = format_cols) # Bind `doc_id` to HRV tibble df_out <- dplyr::bind_cols(doc_id = df_raw[["doc_id"]], df_hrv) df_out } read_HRV_reports(sipsANS_example("HRV"))
Testing bind columns
t_df <- tibble(a = 1:2, b = 3:4) c <- c(5:6) dplyr::bind_cols(t_df, data.frame(c = c)) cbind(t_df, c = c)
readtext::encoding(sipsANS_example("HRV"))
readtext::readtext(sipsANS_example("HRV"), encoding = "UTF-16LE")$text %>% parse_HRV_reports()
parse_HRV_reports <- function(x, format_cols = TRUE) { # Regex: Extract after equal sign after_equal_regex <- c("(?<== )([:digit:]|[:punct:])+") nm_self <- stats::setNames(names(regex_hrv()), names(regex_hrv())) report_df <- nm_self %>% # Step 1: Extract HRV fields into DF purrr::map_dfc( ~ extract_HRV_field[[.x]](x) ) %>% # Step 2: Some vars have to extract number after equal sign dplyr::mutate( dplyr::across( c("VLF", "LF", "HF", "LF_HF"), ~ stringr::str_extract(.x, after_equal_regex) ) ) ## Not format column if( !format_cols){ return(report_df) } ## Format column report_df %>% dplyr::mutate(dplyr::across(c(Channel, Gender), factor), dplyr::across(Age, as.integer), dplyr::across(c(Beats_tot,Rec_length, Discontinuities:Power_tot, VLF,LF, LF_nu, HF, HF_nu, LF_HF), as.numeric) ) %>% # Add pNN50 dplyr::mutate(NN50_percent = 100 * (NN50_count/Normals_count), .after = NN50_count) } parse_HRV_reports(hrv_sim_raw$text)
hrv_sim_raw$text %>% extract_HRV_field[["File_LabChart"]]()
2 steps extract
VLF
, LF
, HF
, LF_HF
after_equal <- c("(?<== )([:digit:]|[:punct:])+") names(extract_HRV_field) %>% setNames(names(extract_HRV_field)) %>% purrr::map_dfc( ~extract_HRV_field[[.x]](hrv_sim_raw$text) ) %>% mutate(across(c("VLF", "LF", "HF", "LF_HF"), ~stringr::str_extract(.x, after_equal)) )
usethis::use_r("HRV_field") usethis::use_test("HRV_field")
new_extract_HRV_field <- function() { extract_factory <- function(nm) { function(x) { trimws(stringr::str_extract(x, regex_hrv()[[nm]])) } } nm_self <- stats::setNames(names(regex_hrv()), names(regex_hrv())) f <- purrr::map(nm_self, extract_factory) f }
trimws(c(" a ", " b "))
extract_HRV_field <- new_extract_HRV_field() names(extract_HRV_field) extract_HRV_field$Date(c("Date: 122", "Date: 123")) extract_HRV_field$Channel(hrv1_chr_raw) #extract_HRV_field$after_equal("a = 12.3") extract_HRV_field$VLF("VLF (DC-0.04Hz) = 114.5 ms²") extract_HRV_field$VLF_freq("VLF (DC-0.04Hz) = 114.5 ms²")
## Extract after equal sign after_equal = c("(?<== )([:digit:]|[:punct:])+")
regex_hrv <- function() { list( # Line 1 File_LabChart = c("(?<=File: \").+(?=\")"), Channel = c("(?<=Channel: ).+(?=Date)"), Date = c("(?<=Date: ).+"), # Line 2 Start_time = c("(?<=Start time: ).+(?=End time)"), End_time = c("(?<=End time: ).+"), # Line 3 Name = c("(?<=Name: )[:graph:]+"), Gender = c("(?<=Gender: )[:alpha:]+"), Age = c("(?<=Age: )([:digit:]|[:punct:])+"), # Line 4 Beats_tot = c("(?<=Total number of beats = )([:digit:]|[:punct:])+"), Rec_length = c("(?<=Length of recording = )([:digit:]|[:punct:])+"), # Line 5 Class_bound = c("(?<=Classification boundaries: ).+"), # Line 6 Discontinuities = c("(?<=Discontinuities = )([:digit:]|[:punct:])+"), Beats_inserted = c("(?<=Manually inserted beats = )([:digit:]|[:punct:])+"), Beats_deleted = c("(?<=Manually deleted beats = )([:digit:]|[:punct:])+"), # Line 7 NN_max = c("(?<=Maximum NN = )([:digit:]|[:punct:])+"), NN_min = c("(?<=Minimum NN = )([:digit:]|[:punct:])+"), NN_range = c("(?<=Range = )([:digit:]|[:punct:])+"), # Line 8 NN_mean = c("(?<=Mean NN = )([:digit:]|[:punct:])+"), NN_median = c("(?<=Median NN = )([:digit:]|[:punct:])+"), HR_avg = c("(?<=Average heart rate = )([:digit:]|[:punct:])+"), # Line 9 SDNN = c("(?<=SDNN = )([:digit:]|[:punct:])+"), SD_del_NN = c("(?<=SD of delta NN = )([:digit:]|[:punct:])+"), RMSSD = c("(?<=RMSSD = )([:digit:]|[:punct:])+"), # Line 10 Normals_count = c("(?<=Normals = )([:digit:]|[:punct:])+"), Ectopics_count = c("(?<=Ectopics = )([:digit:]|[:punct:])+"), Artifacts_count = c("(?<=Artifacts = )([:digit:]|[:punct:])+"), NN50_count = c("(?<=NN50 = )([:digit:]|[:punct:])+"), # Line 11 Spec_intv = c("(?<=Spectrum intervals = )([:digit:]|[:punct:])+"), Spec_mean_NN = c("(?<=Mean spectrum NN = )([:digit:]|[:punct:])+"), # Line 12 Power_tot = c("(?<=Total power = )([:digit:]|[:punct:])+"), VLF_freq = c("(?<=VLF \\().+(?=\\))"), VLF = c("VLF \\(.+\\) = ([:digit:]|[:punct:])+"), # Last Line LF_freq = c("(?<=((?<!V)(LF) \\())[^\\)]+"), LF = c("(?<!V)(LF) \\(.+\\) = ([:digit:]|[:punct:])+"), LF_nu = c("(\\.|[:digit:])+(?=( nu\\)[:blank:]+HF))"), HF_freq = c("(?<=((HF) \\())[^\\)]+"), HF = c("(HF) \\(.+\\) = ([:digit:]|[:punct:])+"), HF_nu = c("(\\.|[:digit:])+(?=( nu\\)[:blank:]+LF/HF))"), LF_HF = c("(LF/HF) = ([:digit:]|[:punct:])+") ) }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.