--- title: "Non-wear detection from ActiGraph data" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Non-wear detection from ActiGraph data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, echo = FALSE} knitr::opts_chunk$set( echo = TRUE, warning = FALSE, message = FALSE, collapse = TRUE, comment = "#>", out.width = "75%", fig.asp = 1 / 1.6, fig.width = 5 ) pckg <- c("actigraph.sleepr", "dplyr", "lubridate", "ggplot2") inst <- suppressMessages(lapply(pckg, library, character.only = TRUE)) theme_set(theme_light()) ``` The `actigraph.sleepr` package implements two non-wear detection algorithms: Troiano (Troiano et al. 2008) and Choi (Choi et al. 2011). For illustration let's use one day of sample data recorded by a GT3X+ monitor. See the [sleep vignette](detect-sleep.html) for details on reading AGD files and collapsing epochs. ```{r } file_10s <- system.file("extdata", "ActiSleepPlus-RawData-Day01.agd", package = "actigraph.sleepr" ) agdb_60s <- read_agd(file_10s) %>% collapse_epochs(60) %>% mutate(date = lubridate::as_date(timestamp)) %>% select(date, timestamp, starts_with("axis")) %>% group_by(date) agdb_60s ``` Long stretches that consist almost entirely of zero counts (zero epochs) suggest that the device wasn't worn at all and therefore should be excluded from downstream analysis. ### Non-wear detection with the Troiano algorithm The Troiano algorithm for detecting periods of non-wear formalizes a technique used to analyze the 2003-2004 NHANES data; the original SAS source code can be found at https://riskfactor.cancer.gov/tools/nhanes_pam/. The method has some flexibility as a non-wear period can contain a few nonzero epochs of artifactual movement (spikes). `activity_threshold` : Highest activity level to be considered "zero"; an epoch with activity exceeding the threshold is considered a "spike". The default threshold is 0. `min_period_len` : Minimum number of consecutive zero epoch to start a non-wear period. The default is 60. `max_nonzero_count` : Epochs with activity greater than `max_nonzero_count` are labeled "zero". The default is `Inf`. `spike_tolerance` : Also known as artifactual movement interval. At most `spike_tolerance` "nonzero" epochs can occur in sequence during a non-wear period without interrupting it. The default is 2. `spike_stoplevel` : An activity spike that exceeds `spike_stoplevel` counts ends a non-wear period, even if the spike tolerance has not been reached. The default is 100. `use_magnitude` : If true, the magnitude of the vector (axis1, axis2, axis3) is used to measure activity; otherwise the axis1 value is used. The default is FALSE. `endat_nnz_seq` : If true, a non-wear period ends with a run of nonzero epochs that is longer than `spike_tolerance`. This corresponds to the option *"Require consecutive epochs outside of the activity threshold"* in ActiLife's Wear Time Validation menu. The default is TRUE. The Troiano algorithm specifies that a non-wear period starts with `min_length` consecutive epochs/minutes of zero activity and ends with more than `spike_tolerance` epochs/minutes of nonzero activity. ```{r } periods_nonwear <- agdb_60s %>% apply_troiano(min_period_len = 45) periods_nonwear ``` The parameter settings of the Troiano algorithm are stored as attributes. ```{r } tail(attributes(periods_nonwear), 8) ``` Once non-wear periods are detected, we can further screen those intervals. For example, we can ignore non-wear periods that are too short. ```{r } periods_nonwear %>% filter(length >= 60) ``` Or we can flag 24-hour day as invalid if the device was worn only for a short period of time. ```{r } # Find the periods during which the device was worn periods_wear <- complement_periods( periods_nonwear, agdb_60s, period_start, period_end ) periods_wear # Label each epoch with the period_id of the wear period it falls in # or with NA if the epoch falls outside a wear period agdb_wear <- combine_epochs_periods( agdb_60s, periods_wear, period_start, period_end ) agdb_wear # Once we add the wear/nonwear information, it is straightforward to # compute summary statistics or join with external minute-by-minute data agdb_wear %>% group_by(period_id, .add = TRUE) %>% summarise( time_worn = n(), ave_counts = mean(axis1), .groups = "drop_last" ) ``` ### Non-wear detection with the Choi algorithm The Choi algorithm extends the Troiano algorithm by requiring that short spikes of artifactual movement during a non-wear period are preceded and followed by \code{min_window_len} consecutive zero epochs. `min_period_len` : Minimum number of consecutive zero epoch to start a non-wear period. The default is 90. `min_window_len` : The minimum number of consecutive "zero" epochs immediately preceding and following a spike of artifactual movement. The default is 30. `spike_tolerance` : Also known as artifactual movement interval. At most `spike_tolerance` "nonzero" epochs can occur in sequence during a non-wear period without interrupting it. The default is 2. `use_magnitude` : If true, the magnitude of the vector (axis1, axis2, axis3) is used to measure activity; otherwise the axis1 value is used. The default is FALSE. ```{r } periods_nonwear <- agdb_60s %>% apply_choi( min_period_len = 45, min_window_len = 10 ) periods_nonwear ``` Again, the parameter settings are saved as attributes. ```{r } tail(attributes(periods_nonwear), 5) ``` ### References Troiano, Richard P, David Berrigan, Kevin W Dodd, Louise C Mâsse, Timothy Tilert, and Margaret McDowell. 2008. “Physical Activity in the United States Measured by Accelerometer.” *Medicine & Science in Sports & Exercise* 40 (1): 181–88. Choi, Leena, Zhouwen Liu, Charles E. Matthews, and Maciej S. Buchowski. 2011. “Validation of Accelerometer Wear and Nonwear Time Classification Algorithm.” *Medicine & Science in Sports & Exercise* 43 (2): 357–64.