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
for details on reading AGD files and collapsing epochs.
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
#> # A tibble: 1,440 × 5
#> # Groups: date [2]
#> date timestamp axis1 axis2 axis3
#> <date> <dttm> <int> <int> <int>
#> 1 2012-04-04 2012-04-04 13:29:00 600 1025 891
#> 2 2012-04-04 2012-04-04 13:30:00 88 367 74
#> 3 2012-04-04 2012-04-04 13:31:00 493 646 622
#> 4 2012-04-04 2012-04-04 13:32:00 358 284 174
#> 5 2012-04-04 2012-04-04 13:33:00 290 341 77
#> 6 2012-04-04 2012-04-04 13:34:00 57 166 23
#> 7 2012-04-04 2012-04-04 13:35:00 158 240 40
#> 8 2012-04-04 2012-04-04 13:36:00 68 214 102
#> 9 2012-04-04 2012-04-04 13:37:00 1500 1562 1252
#> 10 2012-04-04 2012-04-04 13:38:00 165 296 59
#> # ℹ 1,430 more rowsLong 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.
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_thresholdmin_period_lenmax_nonzero_countmax_nonzero_count are
labeled “zero”. The default is Inf.
spike_tolerancespike_tolerance “nonzero” epochs can occur in sequence
during a non-wear period without interrupting it. The default is 2.
spike_stoplevelspike_stoplevel counts ends
a non-wear period, even if the spike tolerance has not been reached. The
default is 100.
use_magnitudeendat_nnz_seqspike_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.
periods_nonwear <- agdb_60s %>% apply_troiano(min_period_len = 45)
periods_nonwear
#> # A tibble: 2 × 4
#> # Groups: date [1]
#> date period_start period_end length
#> <date> <dttm> <dttm> <int>
#> 1 2012-04-05 2012-04-05 02:56:00 2012-04-05 03:59:00 63
#> 2 2012-04-05 2012-04-05 04:54:00 2012-04-05 05:45:00 51The parameter settings of the Troiano algorithm are stored as attributes.
tail(attributes(periods_nonwear), 8)
#> $nonwear_algorithm
#> [1] "Troiano"
#>
#> $min_period_len
#> [1] 45
#>
#> $max_nonzero_count
#> [1] Inf
#>
#> $spike_tolerance
#> [1] 2
#>
#> $spike_stoplevel
#> [1] 100
#>
#> $activity_threshold
#> [1] 0
#>
#> $endat_nnz_seq
#> [1] TRUE
#>
#> $use_magnitude
#> [1] FALSEOnce non-wear periods are detected, we can further screen those intervals. For example, we can ignore non-wear periods that are too short.
periods_nonwear %>% filter(length >= 60)
#> # A tibble: 1 × 4
#> # Groups: date [1]
#> date period_start period_end length
#> <date> <dttm> <dttm> <int>
#> 1 2012-04-05 2012-04-05 02:56:00 2012-04-05 03:59:00 63Or we can flag 24-hour day as invalid if the device was worn only for a short period of time.
# Find the periods during which the device was worn
periods_wear <- complement_periods(
periods_nonwear, agdb_60s,
period_start, period_end
)
periods_wear
#> # A tibble: 4 × 4
#> # Groups: date [2]
#> date period_start period_end length
#> <date> <dttm> <dttm> <int>
#> 1 2012-04-04 2012-04-04 13:29:00 2012-04-04 23:59:00 631
#> 2 2012-04-05 2012-04-05 00:00:00 2012-04-05 02:55:00 176
#> 3 2012-04-05 2012-04-05 04:00:00 2012-04-05 04:53:00 54
#> 4 2012-04-05 2012-04-05 05:46:00 2012-04-05 13:28:00 463
# 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
#> # A tibble: 1,440 × 6
#> # Groups: date [2]
#> date timestamp axis1 axis2 axis3 period_id
#> <date> <dttm> <int> <int> <int> <int>
#> 1 2012-04-04 2012-04-04 13:29:00 600 1025 891 1
#> 2 2012-04-04 2012-04-04 13:30:00 88 367 74 1
#> 3 2012-04-04 2012-04-04 13:31:00 493 646 622 1
#> 4 2012-04-04 2012-04-04 13:32:00 358 284 174 1
#> 5 2012-04-04 2012-04-04 13:33:00 290 341 77 1
#> 6 2012-04-04 2012-04-04 13:34:00 57 166 23 1
#> 7 2012-04-04 2012-04-04 13:35:00 158 240 40 1
#> 8 2012-04-04 2012-04-04 13:36:00 68 214 102 1
#> 9 2012-04-04 2012-04-04 13:37:00 1500 1562 1252 1
#> 10 2012-04-04 2012-04-04 13:38:00 165 296 59 1
#> # ℹ 1,430 more rows
# 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"
)
#> # A tibble: 5 × 4
#> # Groups: date [2]
#> date period_id time_worn ave_counts
#> <date> <int> <int> <dbl>
#> 1 2012-04-04 1 631 1446.
#> 2 2012-04-05 1 176 75.9
#> 3 2012-04-05 2 54 31.5
#> 4 2012-04-05 3 463 1208.
#> 5 2012-04-05 NA 116 8.42The Choi algorithm extends the Troiano algorithm by requiring that short spikes of artifactual movement during a non-wear period are preceded and followed by consecutive zero epochs.
min_period_lenmin_window_lenspike_tolerancespike_tolerance “nonzero” epochs can occur in sequence
during a non-wear period without interrupting it. The default is 2.
use_magnitudeperiods_nonwear <- agdb_60s %>% apply_choi(
min_period_len = 45,
min_window_len = 10
)
periods_nonwear
#> # A tibble: 1 × 4
#> # Groups: date [1]
#> date period_start period_end length
#> <date> <dttm> <dttm> <int>
#> 1 2012-04-05 2012-04-05 03:03:00 2012-04-05 03:59:00 56Again, the parameter settings are saved as attributes.
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.