The SleepCycles package
Package and main function
The SleepCycles package and its main function SleepCycles()
is
designed to detect sleep cycles and their respective NREM and REM parts
(called (N)REM periods) from data that has been sleep staged according
to AASM criteria. Additionally, each (N)REM part is split into
percentiles. The function results in a plot visualising the results and
creates a text file so the results can be used for further processing.
Detection of sleep cycles
Sleep cycles are largely detected according to the originally proposed criteria by Feinberg & Floyd (1979) and as described in Blume & Cajochen (2021) . NREM periods are periods starting with N1 (default) or N2 at the beginning of the night and W or another NREM stage following a REM period. NREMPs have a minimal duration minimal duration of 15min (can include W, up to <5min REM, except for the first REMP, for which there is no minimum duration criterion). REM following a NREM period always represents a potential REM period, however any REMP must be at least 5min long (except the first REMP, for which no minimum duration criterion is applied). If a NREMP exceeds 120min in duration (excl. wake), it can be split into 2 parts. The new cycle starts with the first N3 episode following a phase (>12min) with any other stage than N3, that is a lightening of sleep (cf. Rudzik et al., 2020; Jenni et al., 2004; Kurth et al., 2010). The function makes suggestions where splitting could be done according to these criteria and visualises the potential splitting points on top of a hypnogram. The user can then interactively choose where to split the NREMP. However, the code also offers the possibility to provide a numeric value for an epoch at which to split or you can also decide to not split at all. A combination of a NREMP and the following REMP represents one sleep cycle, except for the case when a NREMP is split. In this case, the first of the two resulting NREMPs represents a sleep cycle (without REM).
Requirements
The function requires any sleep staging results file with a column, in
which the sleep stages are coded in the usual numeric 0,1,2,3,5 (i.e.,
W, N1, N2, N3, REM) pattern (i.e., a numeric vector). The user can
define other integers to be handled as W or N3 (i.e. in the case
stagings were done according to the Rechtschaffen & Kales criteria
including S3 and S4). The presence of further columns, e.g. a ‘time’
column, is not an issue. Staging must be in 30s epochs. Besides text
files, the SleepCycles()
function can also handle csv and marker files
for the Brain Vision Analyzer. The input file type can be indicated with
the filetype
argument (filetype = "txt"
(default) or
filetype = "csv"
or filetype = "vmrk"
).
Details
Besides sleep cycles (NREM-REM), the result also splits the NREM and REM parts of each cycle in percentiles. In case the length of a period is not divisible by 10 (e.g., 203 epochs), one epoch is added to percentiles in a randomized fashion to reach the correct length of a period (here: 7 percentiles of 20 epochs, 3 of 21 epochs).
The code offers to choose whether incomplete periods should be removed
at the end of the night (argument rm_incomplete_period
, default =
FALSE). Incomplete periods are defined by periods that are followed by
<5min NREM or W (e.g. because a participant is woken up).
Although this is not encouraged, for some participants it may be necessary to decrease the minimum duration of REM from 5min to 4 or 4.5min as otherwise a seemingly ‘clear’ REM period is skipped. While the default length of REMPs is 10 segments, it can be decreased.
The user can either process all files in a given directory (default) or
specific files by specifying a vector of files (argument files
).
By default, the function produces and saves a plot for visual inspection
of the results (argument plot
, default = TRUE).
Arguments in SleepCycle function
p
character vector indicating the directory containing the sleep
staging files
sleepstart
character vector indicating whether the first NREMP at the
beginning of the night should start with N1 or N2. Default: N1 files
numeric vector indicating which files in ‘p’ to process. Default: NA
filetype
character indicating file type of the files containing the
sleep staging results. Can be “txt” (default) or “csv” or “vmrk” (i.e.,
marker files for Brain Vision Analyzer Software).
treat_as_W
numeric vector indicating which values should be treated as
‘wake’. Default: NA
treat_as_N3
numeric vector indicating which values should be treated
as ‘N3’. Default: NA
rm_incomplete_period
logical: should incomplete periods at the end of
the night be removed? Default: F.
plot
logical: should a plot for the result of the detection procedure
be generated and saved? Default: T.
REMP_length
numeric value specifying the minimum duration of a REM
period. Default is 10 segments (i.e. 5 minutes). Decreasing the min.
length is not encouraged and should only be done following careful
consideration
Worked example
First, we install and load the package if we haven’t done so.
## First, we save your current workspace
save.image(file=paste(tempdir(), "currsession.RData", sep = "/"))
## make sure you start with a clean session.
rm(list = ls(all = TRUE))
install.packages("SleepCycles", repos = "http://cran.us.r-project.org")
Then, we are ready to use the package on our data set. Note that in the
sleepstages2
data set, the first NREM period exceeds 120 minutes.
Thus, the code attempts to split this NREM period.
The text file has a header, thus, when asked whether it has a header
file, type y
. Columns are separated by comma, thus type ,
when
prompted. Of course, if we had several of these files in our directory,
they would all have to have the same pattern.
Create directory & save data file
First, we load the sleepstages2
file that comes with the package and
create a directory, where we save it.
library(SleepCycles)
data(sleepstages2)
## save current working directory so we can reset this later.
olddir <- getwd()
## create a new directory in the temporary directory (don't worry, it will automatically be deleted
## when you restart your computer)
newdir <- file.path(tempdir(),"SleepCycles_exmpl2")
dir.create(newdir, showWarnings = FALSE)
## write the sleepstages2 file to this new directory
write.table(sleepstages2, file = paste(newdir, "sleepstages2.txt", sep = "/"),
row.names=FALSE, col.names = TRUE, quote = FALSE, sep = ",")
Run the detection
Then, we apply the actual SleepCycles
function. The file contains
column names in a header and columns are separated with a comma. When we
are prompted, we have to decide where we want to split the data, either
at the first or the second suggested location. I would suggest selecting
the fist, so when prompted, we simply type 1
.
SleepCycles::SleepCycles(newdir, filetype = "txt")
## We again load the workspace image from before the code above was executed
save.image(file=paste(tempdir(), "currsession.RData", sep = "/"))
## we set the directory back to the one we were using before as we were just working in the
## temp directory.
setwd(olddir)