Package 'zeitR'

Title: Actigraphy Data Parsing and Analysis for R
Description: Provides tools for importing, parsing, and analysing raw actigraphy data from wrist-worn devices. Implements a full sleep analysis pipeline — off-wrist detection, main sleep period detection, nap detection, and WASO computation — validated epoch-for-epoch against the Condor circadiaBase Python reference pipeline using ActTrust hardware. Also computes standard non-parametric circadian rhythm variables (interdaily stability, intradaily variability, relative amplitude, L5, M10). Device-specific parameter presets can be swapped to adapt the pipeline to other actigraph models. Designed to complement slumbR in the Circadia Lab ecosystem.
Authors: Lucas França [aut, cre] (ORCID: <https://orcid.org/0000-0003-0853-1319>), Mario Leocadio-Miguel [aut] (ORCID: <https://orcid.org/0000-0002-7248-3529>), Julia Ribeiro da Silva Vallim [aut] (ORCID: <https://orcid.org/0000-0001-8708-8479>)
Maintainer: Lucas França <[email protected]>
License: MIT + file LICENSE
Version: 0.1.6
Built: 2026-07-16 12:50:39 UTC
Source: https://github.com/circadia-bio/zeitR

Help Index


Default state colour palette for actogram plots

Description

Returns a named character vector of hex colours keyed on the four state labels produced by label_states(). Pass the output to the colours argument of any actogram function to override individual colours.

Usage

actogram_colours()

Value

Named character vector with elements "wake", "sleep", "nap", and "off-wrist".

Examples

actogram_colours()
# wake        sleep        nap    off-wrist
# "#C25E2A" "#3B2F6B" "#F0A500" "#D9C8A0"

ActTrust device parameter preset

Description

Returns a named list of all device- and study-specific parameter values used by the zeitR pipeline when processing ActTrust recordings. Passing this list (or a modified copy) to run_pipeline() via the params argument fully controls which values each detector stage receives, without having to touch the individual function calls.

Usage

acttrust_params()

Details

The list is organised into four named sections that map directly to the four pipeline stages:

offwrist

Parameters for detect_offwrist_bimodal(). These values were validated against the Condor circadiaBase pipeline using ActTrust hardware. The refinement stage (.bimodal_refine_acttrust) is device-specific and currently only validated for ActTrust.

sleep

Parameters for detect_sleep_crespo(). sleep_quantile (0.365) is the ActTrust CSPD wrapper value; the original Crespo (2012) algorithm uses 1/3.

nap

Parameters for detect_naps_crespo(), passed as the params argument. Equivalent to .cspd_nap_params().

waso

Parameters for compute_waso().

To adapt the pipeline for a different device, copy the list, modify the relevant values, and pass it to run_pipeline():

p <- acttrust_params()
p$sleep$sleep_quantile <- 1/3   # use the original Crespo threshold
result <- run_pipeline("recording.txt", params = p)

Value

A named list with elements offwrist, sleep, nap, and waso.

See Also

run_pipeline() for the pipeline entry point.


Check actigraphy timestamps for consistency issues

Description

Scans a recording tibble for three classes of timestamp problem:

Usage

check_consistency(x, gap_s = 120, datetime_col = "datetime")

Arguments

x

A tibble as returned by read_acttrust() or prepare_actigraphy(), containing a datetime column.

gap_s

numeric(1). Gap threshold in seconds. Intervals longer than this are flagged. Default is 120 (2 minutes).

datetime_col

character(1). Name of the datetime column. Default is "datetime".

Details

  • Gaps — intervals between consecutive epochs longer than gap_s seconds.

  • Backward jumps — timestamps that go backwards in time.

  • Year artefacts — timestamps in the years 1970 or 2000, which typically indicate firmware epoch-counter rollover bugs.

Value

A tibble with one row per detected issue and columns:

row

integer — row index in x where the issue occurs.

datetime

POSIXct — timestamp at that row.

issue

character — one of "gap", "backward_jump", or "year_artefact".

detail

character — human-readable description.

Returns a zero-row tibble if no issues are found.

Examples

## Not run: 
rec    <- read_acttrust("recordings/P001.txt")
issues <- check_consistency(rec)
issues

## End(Not run)

Circular mean of clock times in decimal hours

Description

Computes the mean of times on the 0-24 h clock using the unit-circle method: convert each time to a unit-vector angle, average the sin and cos components, and back-project via atan2. This correctly handles midnight wrap (e.g. times at 23:30 and 00:30 average to 00:00, not 12:00).

Usage

circ_mean_h(x)

Arguments

x

numeric. Decimal hours in [0, 24). NA values are silently dropped.

Details

The older threshold approach (shift values >= 12 h by -24 h before averaging) produces badly biased estimates when times straddle noon – critically for sleep offset in late sleepers – and is superseded by this function (Fix 20 in the JRSV pipeline, ICC for sleep offset 0.502 -> 0.897 on N=404).

Value

A single numeric in [0, 24), or NA_real_ if x is empty after NA removal.

References

Pewsey, A., Neuhauser, M., & Ruxton, G. D. (2013). Circular Statistics in R. Oxford University Press.

Examples

circ_mean_h(c(23.5, 0.5))   # midnight wrap -> 0
circ_mean_h(c(23.0, 1.0))   # -> 0
circ_mean_h(c(7.0, 9.0))    # -> 8

Circular standard deviation of clock times in decimal hours

Description

Computes the circular SD using the mean resultant length formula: sqrt(-2 * log(R_bar)) * 24 / (2*pi), where R_bar is the mean resultant length of the unit-circle representation of the times. Linear SD inflates when times straddle midnight; this measure is invariant to the wrap point (Fix 24 in the JRSV pipeline).

Usage

circ_sd_h(x)

Arguments

x

numeric. Decimal hours in [0, 24). NA values are silently dropped. Returns NA_real_ for fewer than 2 values.

Value

A single non-negative numeric (hours), or NA_real_.

References

Mardia, K. V., & Jupp, P. E. (2000). Directional Statistics (2nd ed.). Wiley.

Examples

circ_sd_h(c(23.5, 0.5))   # small SD for times close to midnight
circ_sd_h(c(6.0, 18.0))   # large SD for times 12 h apart

Classify physical activity intensity directly from activity counts

Description

Convenience wrapper combining estimate_ee() and classify_pa_intensity() in one call: converts raw ActTrust(R)/GT3X+ activity counts straight to a PA intensity factor via the published "batista2026" (or future) equation set, without needing to handle the intermediate MET values.

Usage

classify_pa_counts(
  counts,
  device = c("ACTT", "GT3X+"),
  placement = c("hip", "wrist"),
  equation_set = "batista2026"
)

Arguments

counts

Numeric vector of activity counts (counts/min, over the same epoch length used by the source equation set – 1-minute for "batista2026"). Negative values are treated as 0 with a warning, since the underlying square-root transform is undefined below zero.

device

character(1). "ACTT" (default) or "GT3X+".

placement

character(1). "hip" (default) or "wrist".

equation_set

character(1), passed to pa_equations(). Default "batista2026".

Value

An ordered factor, same length as counts and same levels as classify_pa_intensity().

See Also

estimate_ee(), classify_pa_intensity(), pa_equations() for the coefficients and their generalisability caveats.

Examples

classify_pa_counts(c(0, 5000, 25000, 50000), device = "ACTT", placement = "hip")

Classify physical activity intensity from METs

Description

Bins metabolic equivalent (MET) values into the four PA intensity classes used throughout Batista et al. (2026) and consistent with WHO PA intensity conventions: light, moderate, vigorous, very vigorous.

Usage

classify_pa_intensity(mets)

Arguments

mets

Numeric vector of MET values, e.g. from estimate_ee() or measured directly (indirect calorimetry, published equations, etc.). MET-based, not device-specific – any source of METs can be classified.

Value

An ordered factor with levels c("light", "moderate", "vigorous", "very_vigorous"), same length as mets. Bands: ⁠[0,3)⁠ light, ⁠[3,6)⁠ moderate, ⁠[6,9)⁠ vigorous, ⁠[9,Inf)⁠ very vigorous.

See Also

estimate_ee(), pa_equations()

Examples

mets <- estimate_ee(c(0, 5000, 25000, 50000), device = "ACTT", placement = "hip")
classify_pa_intensity(mets)

Classify sleep episodes as main or secondary (native pipeline)

Description

Applies the JRSV classification rule set to a raw episode table from extract_sleep_episodes(), assigning each episode a sleep_type of "main" or "secondary". The execution order follows Fix 27:

Usage

classify_sleep_episodes(
  episodes,
  data,
  max_tib_h = 16,
  max_main_tib_h = 14,
  min_main_tib_h = 4,
  nocturnal_onset_start = 18,
  nocturnal_onset_end = 6,
  temp_thresh = 28,
  light_thresh_window = 5,
  light_thresh_recovery = 10,
  min_fragment_tib_h = 1,
  rolling_window_min = 15L,
  max_split_iterations = 3L,
  collision_gap_h = 4,
  verbose = FALSE
)

Arguments

episodes

A tibble as returned by extract_sleep_episodes().

data

A tibble as returned by detect_sleep_crespo(), containing at minimum datetime, state, activity. The ActTrust channels int_temp (wrist temperature) and light (ambient lux) must be present for Fix 26a/c; the function falls back to defaults when absent.

max_tib_h

numeric(1). Episodes with TBT > this value are excluded directly. Default 16.

max_main_tib_h

numeric(1). Episodes with TBT in ⁠(max_main_tib_h, max_tib_h]⁠ are split first. Default 14.

min_main_tib_h

numeric(1). Minimum TBT (hours) for a main episode. Default 4.

nocturnal_onset_start

numeric(1). Default nocturnal window start (decimal hours). Overridden by Fix 26a. Default 18.

nocturnal_onset_end

numeric(1). Default nocturnal window end. Overridden by Fix 26a. Default 6.

temp_thresh

numeric(1). Minimum wrist temperature (degC) for candidate episodes in Fix 26a/c. Default 28.

light_thresh_window

numeric(1). Maximum ambient light (lux) for the nocturnal window inference (Fix 26a). Default 5.

light_thresh_recovery

numeric(1). Maximum ambient light (lux) for gap merging in fragment recovery (Fix 26c). Default 10.

min_fragment_tib_h

numeric(1). Minimum TBT (hours) for each fragment produced by an episode split (Fix 29). Default 1.

rolling_window_min

integer(1). Smoothing window (epochs) for the activity signal used to locate episode split points. Default 15L.

max_split_iterations

integer(1). Maximum recursive splits per episode. Default 3L.

collision_gap_h

numeric(1). Minimum gap (hours) between two same-date main episodes to trigger sleep-date reassignment (Fix 26b). Default 4.

verbose

logical(1). Print step-by-step diagnostics. Default FALSE.

Details

  1. Fix 25 – exclude truncated episodes at the recording end.

  2. Fix 26a – infer adaptive nocturnal window from int_temp and light. Falls back to nocturnal_onset_start/nocturnal_onset_end if fewer than 2 candidate episodes pass the temperature and light filter.

  3. Fix 29 / Rule 1 – split TBT 14–16 h episodes at their activity peak (recursive, up to max_split_iterations). Fragments still exceeding max_main_tib_h after splitting are excluded.

  4. Rule 2 – exclude episodes with TBT > max_tib_h (16 h) directly, without attempting a split.

  5. Fix 26c – recover sleep nights missed by the scorer for dates with no classified main episode. Sleep and wake within the candidate window are determined by Cole-Kripke epoch scoring on ZCMn (not the period-level CSPD state). Adjacent sleep runs are merged when the intervening gap has wrist temperature >= temp_thresh and ambient light <= light_thresh_recovery.

  6. Rules 3–5 – classify each episode as "main" or "secondary" using the nocturnal window and min_main_tib_h.

  7. Fix 26b – resolve sleep-date collisions: when two main episodes share a noon-threshold sleep date and are separated by >= collision_gap_h hours, reassign the later one to the next calendar date.

  8. Rule 6 – keep the longest main episode per sleep date; demote all others to "secondary".

  9. Rule 7 – exclude all episodes (main and secondary) on dates that have no valid main sleep after Rule 6.

Value

A tibble with the same columns as episodes plus sleep_type ("main" or "secondary") and is_nap (logical, TRUE when sleep_type == "secondary", for backwards compatibility with the zeitr_result$nights schema).

See Also

extract_sleep_episodes(), run_pipeline_native()


Compute PIM, TAT, and ZCM activity counts from raw triaxial acceleration

Description

Reproduces the general wrist-actigraph processing chain – per-axis DC removal and band-pass filter, vector norm, epoch-level integration – that converts raw acceleration samples into the epoch-level activity metrics used throughout the rest of zeitR (e.g. read_acttrust()'s activity/ZCMn columns) and the wider PA-intensity literature (see pa_equations()).

Usage

compute_activity_counts(
  x,
  y,
  z,
  sampling_rate,
  epoch_sec = 60,
  filter_low = 0.5,
  filter_high = 2.7,
  zcm_threshold = 0.01,
  tat_threshold = 0.05,
  metrics = c("PIM", "TAT", "ZCM")
)

Arguments

x, y, z

Numeric vectors of raw triaxial acceleration samples (same units – typically g – and length, uniformly sampled at sampling_rate).

sampling_rate

numeric(1). Sampling rate of x/y/z in Hz.

epoch_sec

numeric(1). Epoch length in seconds. Default 60 (1-minute epochs, the ActTrust standard used elsewhere in zeitR).

filter_low, filter_high

numeric(1). Band-pass cutoffs in Hz, passed to mrpheus::bandpass_filter(). Default 0.5/2.7 (ActTrust-style, per Batista et al. 2026); use 0.25/2.5 for GT3X+-style processing instead.

zcm_threshold

numeric(1). Dead-band around zero (same units as x/y/z) a filtered axis must clear to register a zero crossing. Default 0.01.

tat_threshold

numeric(1). Amplitude threshold (same units) the filtered norm must exceed to count toward TAT. Default 0.05.

metrics

character(). Which metrics to compute. Default c("PIM", "TAT", "ZCM") (all three).

Value

A tibble with one row per epoch: epoch (integer index, 1-based) plus one column per requested metric.

What this is (and isn't)

Filtering reuses mrpheus::remove_dc() and mrpheus::bandpass_filter() – the same zero-phase Butterworth implementation already validated as part of mrpheus's YASA-parity PSG pipeline – rather than a new, unvalidated filter written from scratch. This makes mrpheus a required package for this function specifically (a Suggests dependency of zeitR, checked at runtime; the rest of zeitR does not need it).

Reusing a validated filter primitive does not make the whole function validated, though: the PIM/TAT/ZCM epoch-aggregation logic below (what happens after filtering) is still an original implementation with nothing to check it against – no raw-to-counts converter exists to compare it to, and Condor's/ActiGraph's exact onboard threshold constants are proprietary and unpublished. Built from the general processing description in Batista et al. (2026, PLoS ONE) and standard actigraphy literature. Treat its output as a reasonable approximation of device-computed counts, not a validated reproduction – and prefer device-computed counts (read_acttrust()) over this function whenever they're available.

Processing steps

  1. Each of x, y, z has its DC offset removed (mrpheus::remove_dc()) – important for the z-axis in particular, which typically carries a ~1 g gravity offset – then is independently band-pass filtered with a zero-phase (mrpheus::bandpass_filter()) Butterworth filter (filter_low-filter_high Hz).

  2. A vector norm is computed per sample: sqrt(x^2 + y^2 + z^2) on the filtered axes, matching the order described for ActTrust in Batista et al. (2026): filter first, then combine axes.

  3. Samples are grouped into non-overlapping epochs of epoch_sec * sampling_rate samples. Trailing samples that don't fill a complete final epoch are dropped, with a warning.

  4. Per epoch:

    • PIM (proportional integration mode) – sum of the absolute filtered norm across the epoch.

    • TAT (time above threshold) – seconds within the epoch where the absolute filtered norm exceeds tat_threshold.

    • ZCM (zero crossing mode) – number of sign changes beyond a zcm_threshold dead-band, summed across the three filtered axes, within the epoch.

zcm_threshold and tat_threshold have no published reference value – they are exposed as tunable parameters rather than given a false-precision default. The values shipped here are small, physically motivated starting points (see Arguments), not calibrated constants.

See Also

pa_equations(), estimate_ee(), classify_pa_counts() to go from PIM counts to METs and PA intensity bands; read_acttrust() for device-computed counts (preferred over this function when available); mrpheus::bandpass_filter(), mrpheus::remove_dc() for the underlying filter primitives.

Examples

set.seed(1)
n  <- 25 * 60 * 5  # 5 minutes at 25 Hz
x  <- rnorm(n, sd = 0.05)
y  <- rnorm(n, sd = 0.05)
z  <- rnorm(n, sd = 0.05) + 1  # gravity on the z-axis

## Not run: 
compute_activity_counts(x, y, z, sampling_rate = 25, epoch_sec = 60)

## End(Not run)

Compute CPD, MSF, MSW, MSFsc, SJL, and SJLa

Description

Calculates chronobiological phenotyping metrics from classified nightly sleep data. Mirrors compute_cpd_metrics() and nights_to_cpd_df() from Julia Ribeiro da Silva Vallim's pipeline_functions_fix27.py, with two updates to match the fix29 notebook:

  • MSF and MSW are computed with the circular mean to correctly handle mid-sleep times that wrap midnight.

  • Truncated episodes starting after noon on the last recording day are excluded before metric computation.

Usage

compute_cpd_metrics(x, ...)

## S3 method for class 'zeitr_result'
compute_cpd_metrics(
  x,
  min_tib_h = 3,
  min_tib_eve_h = 3,
  tz = "UTC",
  holidays = x$holidays,
  free_days = x$free_days,
  ...
)

## Default S3 method:
compute_cpd_metrics(
  x,
  min_tib_h = 3,
  min_tib_eve_h = 3,
  tz = "UTC",
  holidays = NULL,
  free_days = c("Saturday", "Sunday"),
  ...
)

Arguments

x

A zeitr_result object or a tibble of nightly sleep statistics as returned by run_pipeline_native() or run_pipeline().

...

Not used; reserved for forward compatibility with future methods.

min_tib_h

numeric(1). Minimum TBT (hours) for inclusion. Default is 3.0.

min_tib_eve_h

numeric(1). Minimum TBT (hours) for a night to qualify as a free-day-eve night. Default is 3.0.

tz

character(1). Time zone for extracting clock hours. Default is "UTC".

holidays

Holidays to treat as free days in addition to the days in free_days. Accepts three forms, which can be mixed in the same vector:

  • Date objects or "YYYY-MM-DD" strings for year-specific dates (e.g. as.Date("2019-03-04") for one Carnival day).

  • "DD-MM" strings for dates that recur every year (e.g. "25-12" for Christmas, "01-01" for New Year). Default is NULL. When x is a zeitr_result, defaults to x$holidays automatically. A warning is emitted when NULL; suppress with options(zeitR.no_holidays_warn = FALSE).

free_days

A character vector of day names ("Monday" through "Sunday", case-insensitive) or ISO integers (1 = Monday ... 7 = Sunday) identifying which days of the week are unconditionally treated as free days. Default is c("Saturday", "Sunday"). When x is a zeitr_result, defaults to x$free_days automatically.

Details

Dispatches on the class of x:

  • data.frame / tibble – treated as a nights table (same behaviour as the original function signature).

  • zeitr_result – extracts x$nights and inherits x$holidays and x$free_days automatically.

Mid-sleep is computed per night as:

MS=(SO+offsetonset2)mod24\text{MS} = \left(\text{SO} + \frac{\text{offset} - \text{onset}}{2}\right) \bmod 24

where onset = bts + SOL and offset = gts - SOI (both in decimal hours).

MSW and MSF use the circular mean of per-night mid-sleep values (values >= 12 h shifted by -24 before averaging, then wrapped to [0, 24)), matching calculate_msf() / calculate_msw() from the fix29 notebook. MSFsc adjusts MSF by the free-day-eve sleep onset and the weighted weekly mean sleep duration when free-day duration exceeds weekday duration. CPD is the RMS distance of each night's mid-sleep from MSFsc in the time x sequence plane.

Value

A named list with n_nights_cpd, n_free_days, n_workdays, msw_h, msw_hms, msf_h, msf_hms, msfsc_h, msfsc_hms, sjl_h, sjl_min, sjla_h, sjla_min, cpd_s, cpd_min, cpd_h.

See Also

compute_sleep_metrics(), run_pipeline_native()


Non-parametric circadian rhythm analysis (NPCRA)

Description

Computes the standard non-parametric circadian rhythm analysis variables from an actigraphy recording, following Gonçalves et al. (2014) and Van Someren et al. (1999). All variables are derived from the 24-hour average activity profile built from hourly means (p = 24).

Usage

compute_npcra(
  x,
  epoch_s = NULL,
  L5_hours = 5,
  M10_hours = 10,
  window_days = NULL,
  trim_to_d1 = TRUE
)

Arguments

x

A zeitr_recording as returned by read_actigraphy(), or a data frame / tibble with at least datetime and activity columns. If a state column is present, off-wrist epochs (state == 4) are excluded before computing all NPCRA variables.

epoch_s

numeric(1). Epoch duration in seconds. If NULL (default), estimated automatically from the median inter-epoch interval.

L5_hours

numeric(1). Width of the least-active window in hours. Default is 5.

M10_hours

numeric(1). Width of the most-active window in hours. Default is 10.

window_days

numeric(1) or NULL. If supplied, the recording is split into non-overlapping windows of this length (in days) and NPCRA variables are computed for each window. A window_start column is added to the output. Partial final windows (shorter than window_days) are included but flagged via a lower n_days value. Default NULL computes a single estimate over the full recording.

trim_to_d1

logical(1). If TRUE (default), the recording is trimmed to start at 00:00 of D+1 – the first full calendar day after recording onset – before any NPCRA variable is computed, matching the Python reference pipeline's convention (it always starts its NPCRA window at D+1 00:00 rather than spanning the raw, typically fractional, recording length). Set to FALSE for the full untrimmed recording (the pre-trim_to_d1 behaviour). If trimming would leave fewer than 2 epochs, a warning is emitted and the untrimmed recording is used instead. Off-wrist exclusion (state == 4) still applies either way; this does not replicate the Python pipeline's separate 30-min-threshold rule for the M10/L5 windows specifically – only the D+1 window start.

Details

The following variables are computed:

IS

Interdaily stability — consistency of the 24 h rest-activity pattern across days (range 0–1; higher = more stable).

IV

Intradaily variability — fragmentation of the rest-activity rhythm (>= 0; higher = more fragmented).

RA

Relative amplitude — contrast between the most active 10 h window (M10) and least active 5 h window (L5) (range 0–1).

L5

Mean activity during the least active 5 consecutive hours.

L5_onset

Clock time of the L5 window onset (hh:mm).

M10

Mean activity during the most active 10 consecutive hours.

M10_onset

Clock time of the M10 window onset (hh:mm).

Value

A tibble with columns participant_id, window_start (if window_days is set), IS, IV, RA, L5, L5_onset, M10, M10_onset, n_days, n_epochs.

References

Gonçalves, B. S. B., Adamowicz, T., Louzada, F. M., Moreno, C. R., & Araujo, J. F. (2014). A fresh look at the use of nonparametric analysis in actimetry. Sleep Medicine Reviews, 20, 84–91. doi:10.1016/j.smrv.2014.06.002

Van Someren, E. J. W., Swaab, D. F., Colenda, C. C., Cohen, W., McCall, W. V., & Rosenquist, P. B. (1999). Bright light therapy: Improved sensitivity to its effects on rest-activity rhythms in Alzheimer patients by application of nonparametric methods. Chronobiology International, 16(4), 505–518. doi:10.3109/07420529908998724

Examples

## Not run: 
rec   <- read_actigraphy("recordings/P001.txt")

# Single estimate over the full recording
compute_npcra(rec)

# Per-fortnight estimates
compute_npcra(rec, window_days = 14)

## End(Not run)

Compute sleep metrics split by day type

Description

Calculates mean sleep metrics separately for all nights, weekday nights, and weekend/holiday nights. Output column names and derived metrics mirror compute_sleep_metrics() from Julia Ribeiro da Silva Vallim's pipeline_functions_fix27.py.

Usage

compute_sleep_metrics(x, ...)

## S3 method for class 'zeitr_result'
compute_sleep_metrics(
  x,
  min_tib_h = 5,
  tz = "UTC",
  holidays = x$holidays,
  free_days = x$free_days,
  ...
)

## Default S3 method:
compute_sleep_metrics(
  x,
  min_tib_h = 5,
  tz = "UTC",
  holidays = NULL,
  free_days = c("Saturday", "Sunday"),
  ...
)

Arguments

x

A zeitr_result object or a tibble of nightly sleep statistics as returned by run_pipeline_native() or run_pipeline(). Must contain at minimum the columns is_nap, bed_time, get_up_time, tbt, tst, sol, soi, waso, eff.

...

Not used; reserved for forward compatibility with future methods.

min_tib_h

numeric(1). Minimum total in-bed time (hours) for a night to be included. Default is 5.0 (matching the Python reference).

tz

character(1). Time zone for extracting clock hours from timestamps. Default is "UTC".

holidays

Holidays to treat as free days in addition to the days in free_days. Accepts three forms, which can be mixed in the same vector:

  • Date objects or "YYYY-MM-DD" strings for year-specific dates (e.g. as.Date("2019-03-04") for one Carnival day).

  • "DD-MM" strings for dates that recur every year (e.g. "25-12" for Christmas, "01-01" for New Year). Default is NULL. When x is a zeitr_result, defaults to x$holidays automatically. A warning is emitted when NULL; suppress with options(zeitR.no_holidays_warn = FALSE).

free_days

A character vector of day names ("Monday" through "Sunday", case-insensitive) or ISO integers (1 = Monday ... 7 = Sunday) identifying which days of the week are unconditionally treated as free days. Default is c("Saturday", "Sunday"). When x is a zeitr_result, defaults to x$free_days automatically.

Details

Dispatches on the class of x:

  • data.frame / tibble – treated as a nights table (same behaviour as the original function signature).

  • zeitr_result – extracts x$nights and inherits x$holidays and x$free_days automatically.

A night is assigned to the free-day group when the get-up date falls on one of the days in free_days or matches an entry in holidays. Day-of-week is determined via the ISO 8601 weekday number (format(date, "%u")) rather than weekdays(), which is locale-dependent. All remaining nights are workday nights.

sleep_onset_h uses a circular mean (values >= 12 h are shifted by -24 h before averaging, then wrapped to [0, 24)). sleep_offset_h uses a plain arithmetic mean.

fps_h (free period sleep) equals fpr_tib_h - (latencia_min + inertia_min) / 60 – TBT net of sleep onset latency and sleep inertia.

dp_midsleep_min and dp_tst_min are standard deviations of per-night mid-sleep (minutes) and TST (minutes), respectively.

Value

A named list with metrics for three groups (overall, wd = workday, fd = free day):

n_overall, n_wd, n_fd

Night counts.

sleep_onset_h, sleep_offset_h

Circular mean onset and arithmetic mean offset in decimal hours.

fpr_tib_h

Mean TBT in hours.

fps_h

Mean free period sleep (TBT - SOL - SOI) in hours.

tst_h

Mean TST in hours.

latencia_min, inertia_min

Mean SOL and SOI in minutes.

waso_min

Mean WASO in minutes.

sleep_eff_pct

Mean sleep efficiency in percent (0-100).

tst_24h_h

Same as tst_h (24-h TST for main sleep only).

dp_midsleep_min, dp_tst_min

SD of mid-sleep and TST in minutes.

Workday and free-day metrics carry the suffix ⁠_wd⁠ and ⁠_fd⁠.

See Also

compute_cpd_metrics(), run_pipeline_native()

Examples

## Not run: 
# From a zeitr_result: holidays and free_days forwarded automatically
result <- run_pipeline_native("recordings/P001.txt",
                              tz        = "America/Sao_Paulo",
                              holidays  = my_holidays,
                              free_days = c("Saturday", "Sunday"))
sm <- compute_sleep_metrics(result, tz = "America/Sao_Paulo")

# Non-standard schedule: Friday + Saturday as free days
sm <- compute_sleep_metrics(result$nights,
                            tz        = "America/Sao_Paulo",
                            holidays  = my_holidays,
                            free_days = c("Friday", "Saturday"))

sm$tst_h            # mean TST in hours
sm$sleep_onset_h    # mean sleep onset (circular, decimal hours)
sm$dp_midsleep_min  # within-person SD of mid-sleep in minutes

## End(Not run)

Sleep Regularity Index (SRI)

Description

Computes the Sleep Regularity Index (Phillips et al. 2017): a measure of day-to-day consistency in the sleep/wake pattern, based on the probability that an epoch's sleep/wake state matches the state at the same clock time exactly 24 h later (or earlier), averaged across the whole recording. Ranges from -100 (perfectly inverted day-to-day) to +100 (perfectly regular); 0 corresponds to chance-level agreement.

Usage

compute_sri(x, epoch_s = NULL, max_gap_min = 30)

Arguments

x

A zeitr_recording/zeitr_result, or a data frame / tibble with at least datetime and state columns. state == 1 or state == 7 is treated as sleep, state == 4 as off-wrist (missing), and any other value as wake – matching the coding already used across zeitR's pipeline output (run_pipeline(), run_pipeline_native(), export_hypnogram()).

epoch_s

numeric(1). Epoch duration in seconds. If NULL (default), estimated automatically from the median inter-epoch interval.

max_gap_min

numeric(1). Off-wrist gaps of this many minutes or less are interpolated rather than excluded. Default 30, matching Fix 30 and Fix 14's 30-minute threshold elsewhere in the pipeline.

Details

Ported from Fix 30 of the Python reference pipeline (SRI_vallim): rather than deriving sleep/wake from a pyActigraphy scoring algorithm (Sadeh, Cole-Kripke, Roenneberg, Scripps – all of which showed substantially worse agreement with manual reference scoring in Julia's concordance analysis, ICC 0.19-0.67 vs 0.82 here), compute_sri() derives sleep/wake directly from the epoch-level state column already produced by zeitR's own pipelines (run_pipeline() / run_pipeline_native()) – the same classification compute_sleep_metrics() and compute_cpd_metrics() already treat as ground truth for this recording.

Off-wrist handling mirrors Fix 30 exactly: off-wrist epochs (state == 4) are treated as missing. Gaps of max_gap_min minutes or less are interpolated (forward-filled from the last valid epoch, or back-filled from the next valid epoch when the gap starts at the very beginning of the recording); longer gaps are left as missing and excluded from the day-to-day comparison entirely, rather than being counted as a non-match.

SRI=100+200×1MtΨ(t,t+24h)SRI = -100 + 200 \times \frac{1}{M}\sum_{t} \Psi(t, t + 24h)

where Ψ(t,t+24h)=1\Psi(t, t+24h) = 1 if the sleep/wake state at epoch tt matches the state 24 h later, 00 otherwise, and MM is the number of epoch pairs where both epochs have a valid (non-missing) state.

Value

A tibble with columns participant_id, sri, n_pairs (number of valid 24h-apart epoch comparisons used), and n_epochs (total epochs after off-wrist gap interpolation, before the 24h-pairing step). sri is NA if the recording is shorter than 24 h, or if no valid pairs remain after off-wrist exclusion.

References

Phillips, A. J. K., Clerx, W. M., O'Brien, C. S., Sano, A., Barger, L. K., Picard, R. W., Lockley, S. W., Klerman, E. B., & Czeisler, C. A. (2017). Irregular sleep/wake patterns are associated with poorer academic performance and delayed circadian and sleep/wake timing. Scientific Reports, 7, 3216. doi:10.1038/s41598-017-03171-4

See Also

compute_npcra(), compute_sleep_metrics(), run_pipeline_native()

Examples

## Not run: 
result <- run_pipeline_native("recordings/P001.txt", tz = "America/Sao_Paulo")
compute_sri(result)

## End(Not run)

Compute WASO and nightly sleep statistics

Description

Scores each epoch within detected sleep periods as wake or sleep using score_epochs_cole_kripke(), then computes per-night statistics. This is a faithful port of the Python condor_pipeline detect_waso: night boundaries are built by .nights_df() (the search_gap = FALSE path of the reference nights_df), each night's ZCM is scored with Cole-Kripke, and the epoch-level state is rebuilt from a zero (wake) base so that within-night WASO-wake epochs and all epochs outside detected nights are scored as wake.

Usage

compute_waso(x, wake_thresh = 60L, search_gap = FALSE)

Arguments

x

A tibble as returned by detect_naps_crespo() (or detect_sleep_crespo() if nap detection is skipped), containing columns datetime, ZCMn, and state.

wake_thresh

integer(1). Minimum duration in epochs of a wake bout required to delimit a new sleep period boundary. Default is 60.

search_gap

logical(1). Reserved for API compatibility with the reference pipeline. The reference detect_waso always builds boundaries with search_gap = FALSE, so this argument currently has no effect.

Details

The following metrics are computed for each detected night / nap:

Metric Definition
tbt Total Bed Time — epochs from bed time to get-up time
tst Total Sleep Time — tbt - waso - sol - soi
waso Wake After Sleep Onset — wake epochs between sleep onset and final wake
sol Sleep Onset Latency — epochs from bed time to first sleep epoch
soi Sleep Offset Inertia — trailing wake epochs at end of sleep period
nw Number of awakenings — count of wake-onset transitions
eff Sleep efficiency — tst / tbt

Value

A list with two elements:

nights

A tibble with one row per detected night/nap and columns night, is_nap, bed_time, get_up_time, tbt, tst, waso, sol, soi, nw, eff.

data

The input tibble x with state and sleep updated with epoch-level Cole-Kripke wake/sleep scores.

References

Cole, R. J., Kripke, D. F., Gruen, W., Mullaney, D. J., & Gillin, J. C. (1992). Automatic sleep/wake identification from wrist activity. Sleep, 15(5), 461–469. doi:10.1093/sleep/15.5.461

Examples

## Not run: 
rec    <- read_acttrust("recordings/P001.txt")
prep   <- prepare_actigraphy(rec)
prep   <- detect_offwrist_bimodal(prep)
prep   <- detect_sleep_crespo(prep)
prep   <- detect_naps_crespo(prep)
result <- compute_waso(prep)
result$nights

## End(Not run)

Detect secondary sleep periods (naps) using the Crespo nap algorithm

Description

Faithful port of the Python nap_wrapper: runs the full CSPD model in nap mode (detect_naps = TRUE) on the currently-awake epochs (state == 0) and merges the detected naps into the sleep state. Must be run after detect_sleep_crespo().

Usage

detect_naps_crespo(x, epoch_h = NULL, params = .cspd_nap_params())

Arguments

x

A tibble as returned by detect_sleep_crespo(), containing columns datetime, activity, and state. Nap detection runs on the wake (state == 0) subset only, mirroring the Python nap_bool mask.

epoch_h

numeric(1). Number of epochs per hour. If NULL (default), derived from the wake-subsequence epoch duration as 3600 / duration.

params

CSPD nap configuration list (default .cspd_nap_params()), the port of nap_wrapper's parameter set.

Details

Nap detection uses a nap-mode MSP (a high zero-proportion combined with a low adaptive-median activity, .crespo_nap_msp()) followed by the same bed-time / get-up-time refiners as the main sleep detection, with the nap parameter set (.cspd_nap_params()) and nap-specific minimum-length post-processing. Detected naps are written as state == 1 (merged into "sleep"), matching nap_wrapper, which assigns state[wake] = 1 - refined_output (i.e. naps are not a distinct state).

Value

The input tibble x with state and sleep columns updated. Nap epochs become state == 1 and sleep == 1; off-wrist (state == 4) and existing main-sleep epochs are preserved.

References

Crespo, C., Aboy, M., Fernández, J. R., & Mojón, A. (2012). Automatic identification of activity-rest periods based on actigraphy. Journal of Medical and Biological Engineering, 32(4), 249–256. doi:10.5405/jmbe.1033

See Also

detect_sleep_crespo() for main sleep period detection.

Examples

## Not run: 
rec  <- read_acttrust("recordings/P001.txt")
prep <- prepare_actigraphy(rec)
prep <- detect_offwrist_bimodal(prep)
prep <- detect_sleep_crespo(prep)
prep <- detect_naps_crespo(prep)

## End(Not run)

Off-wrist detection using the Condor bimodal activity/temperature model

Description

Detects periods where the actigraph was not worn using the bimodal algorithm developed by Condor Instruments. The algorithm proceeds in three stages:

Usage

detect_offwrist_bimodal(
  x,
  hws = 10L,
  activity_quantile = 0.15,
  min_norm_activity = 0.015,
  nbins = 100L,
  min_offwrist_length = 10L,
  min_temp_threshold = 0.35
)

Arguments

x

A tibble as returned by prepare_actigraphy(), containing columns datetime, activity (PIM), int_temp, ext_temp, state, and offwrist.

hws

integer(1). Half-window size (in epochs) for rolling feature extraction. Default is 10 (matching the Python pipeline).

activity_quantile

numeric(1). Quantile used to define "low activity". Default is 0.15.

min_norm_activity

numeric(1). Minimum normalised activity threshold below which the low-activity cutoff is clamped. Default is 0.015.

nbins

integer(1). Number of histogram bins used when fitting the GMM threshold. Default is 100.

min_offwrist_length

integer(1). Minimum number of consecutive off-wrist epochs required to retain a detected period. Shorter runs are discarded. Default is 10.

min_temp_threshold

numeric(1). Minimum normalised temperature threshold; the fitted GMM threshold is clamped to this value if it falls below it. Default is 0.35.

Details

  1. Feature extraction — rolling median of PIM activity and rolling signal/variance of internal temperature are computed over a symmetric window of half-width hws epochs.

  2. Bimodal temperature threshold — among epochs with low activity median (below the activity_quantile quantile of normalised activity), a 2-component Gaussian Mixture Model is fitted to the normalised temperature distribution. The threshold between the two components is taken as the minimum of the GMM density between the two means (or the minimum of the smoothed histogram if that is lower). Ashman's D is computed as a bimodality quality metric.

  3. Initial classification & refinement — epochs simultaneously exhibiting low activity median AND low temperature are marked as off-wrist. Short spurious off-wrist runs shorter than min_offwrist_length epochs are removed.

Off-wrist epochs are encoded as state == 4 (matching the Python pipeline convention). The offwrist column is set to 0.25 for off-wrist epochs for actogram overlay plotting.

Value

The input tibble x with state and offwrist columns updated. Off-wrist epochs have state == 4 and offwrist == 0.25.

References

The bimodal off-wrist algorithm was developed by Julius A. P. P. de Paula at Condor Instruments (2023). It is not published in peer-reviewed literature but the source code is available in the circadiaBase pipeline repository. The Ashman D statistic is described in:

Ashman, K. M., Bird, C. M., & Zepf, S. E. (1994). Detecting bimodality in astronomical datasets. The Astronomical Journal, 108, 2348. doi:10.1086/117248

Examples

## Not run: 
rec  <- read_acttrust("recordings/P001.txt")
prep <- prepare_actigraphy(rec)
prep <- detect_offwrist_bimodal(prep)
sum(prep$state == 4)  # number of off-wrist epochs

## End(Not run)

Detect main sleep periods using the Crespo algorithm

Description

Identifies the main sleep period(s) in an actigraphy recording using the algorithm described in Crespo et al. (2012). The method applies an adaptive median filter to the activity signal, mitigates spuriously long zero runs, and thresholds the result at a quantile of the filtered signal. Morphological closing and opening operations are then used to smooth the binary sleep/wake estimate.

Usage

detect_sleep_crespo(
  x,
  epoch_h = NULL,
  median_filter_h = 8,
  pad_h = 1,
  sleep_quantile = 0.365,
  morph_size = 61L,
  consec_zeros_thr = 15L,
  awake_zeros_thr = 2L,
  sleep_zeros_thr = 30L,
  zero_mitigation_q = 0.33,
  min_short_window_thr = 1,
  refine = TRUE,
  condition = 0L
)

Arguments

x

A tibble as returned by detect_offwrist_bimodal() (or prepare_actigraphy() if off-wrist detection is skipped), containing columns datetime, activity, and state. The detector runs on the on-wrist subset (state != 4) only, mirroring the Python cspd_wrapper.

epoch_h

numeric(1). Number of epochs per hour. If NULL (default), derived from the epoch duration (the mode of the on-wrist inter-epoch interval), as 3600 / duration.

median_filter_h

numeric(1). Length of the preprocessing median filter window in hours. Default is 8.

pad_h

numeric(1). Padding length in hours added before the adaptive median filter. Default is 1.

sleep_quantile

numeric(1). Quantile of the filtered activity used as the MSP sleep/wake threshold. Default is 0.365 (the ActTrust CSPD value used by cspd_wrapper; the standalone Crespo algorithm uses 1/3).

morph_size

integer(1). Size of the structuring element used in morphological closing/opening. Default is 61 epochs.

consec_zeros_thr

integer(1). Runs of zeros longer than this threshold are treated as invalid (zero mitigation). Default is 15.

awake_zeros_thr

integer(1). Threshold for consecutive zeros within wake periods. Default is 2.

sleep_zeros_thr

integer(1). Threshold for consecutive zeros within sleep periods. Default is 30.

zero_mitigation_q

numeric(1). Quantile of activity used to determine the mitigation level for invalid zero runs. Default is 0.33.

min_short_window_thr

numeric(1). Minimum value of the adaptive median threshold; if the fitted quantile falls below this, the threshold is clamped here. Default is 1.0.

refine

logical(1). If TRUE (default), the MSP detection is refined into final sleep periods by the CSPD bed-time / get-up-time refiners (.cspd_refine_periods), reproducing the Python refined_output. If FALSE, the raw MSP detection is used directly.

condition

integer(1). Initial condition flag (default 0). The MSP stage bumps it to 2 when its activity-median threshold clamps to min_short_window_thr; the refiner uses that effective condition. Affects only refine = TRUE.

Value

The input tibble x with state and sleep columns updated. Sleep epochs have state == 1 and sleep == 1; off-wrist epochs (state == 4) are preserved and excluded from the sleep column. With refine = TRUE the sleep epochs delimit the refined sleep PERIODS (the Python refined_output); per-epoch wake/sleep within them is scored later by compute_waso().

References

Crespo, C., Aboy, M., Fernández, J. R., & Mojón, A. (2012). Automatic identification of activity-rest periods based on actigraphy. Journal of Medical and Biological Engineering, 32(4), 249–256. doi:10.5405/jmbe.1033

See Also

detect_naps_crespo() for secondary sleep period (nap) detection.

Examples

## Not run: 
rec  <- read_acttrust("recordings/P001.txt")
prep <- prepare_actigraphy(rec)
prep <- detect_offwrist_bimodal(prep)
prep <- detect_sleep_crespo(prep)

## End(Not run)

Estimate energy expenditure (METs) from activity counts

Description

Applies the published ActTrust(R)/GT3X+ regression equation (sqrt(MET) = b0 + b1 * sqrt(activity_counts)) from pa_equations() to convert raw activity counts into estimated metabolic equivalents (METs).

Usage

estimate_ee(
  counts,
  device = c("ACTT", "GT3X+"),
  placement = c("hip", "wrist"),
  equation_set = "batista2026"
)

Arguments

counts

Numeric vector of activity counts (counts/min, over the same epoch length used by the source equation set – 1-minute for "batista2026"). Negative values are treated as 0 with a warning, since the underlying square-root transform is undefined below zero.

device

character(1). "ACTT" (default) or "GT3X+".

placement

character(1). "hip" (default) or "wrist".

equation_set

character(1), passed to pa_equations(). Default "batista2026".

Value

Numeric vector of estimated METs, same length as counts.

See Also

pa_equations() for the underlying coefficients and their limitations, classify_pa_intensity() to convert METs into intensity bands.

Examples

estimate_ee(c(0, 5000, 25000, 50000), device = "ACTT", placement = "hip")

Export a zeitR pipeline result as a hypnoR-compatible hypnogram

Description

Converts the epoch-level data tibble from run_pipeline() or run_pipeline_native() into the tidy hypnogram format expected by hypnoR metric functions.

Usage

export_hypnogram(
  result,
  subject_id = NULL,
  source = "zeitR",
  drop_offwrist = FALSE,
  epoch_sec = NULL
)

Arguments

result

A zeitr_result list as returned by run_pipeline() or run_pipeline_native(), or a tibble with at minimum the columns datetime and state.

subject_id

character(1) or NULL. Written to the subject_id column and always takes precedence. When NULL (default), result$subject_id is used if present; the column is omitted entirely when no ID is available from either source.

source

character(1). Label written to the source column. Default "zeitR".

drop_offwrist

logical(1). Remove off-wrist epochs (state == 4) from the output and re-index epochs. Default FALSE.

epoch_sec

numeric(1). When supplied, warns if the observed epoch duration differs from this value. Default NULL.

Details

The coarse (3-state) stage mapping used by zeitR is:

state ZCMn Stage
0 any "W"
1, 7 ⁠> 0⁠ "Sleep"
1, 7 ⁠== 0⁠ "Quiet sleep"
4 any "W"

Zero-count epochs within sleep (ZCMn == 0) are mapped to "Quiet sleep" as the standard actigraphy proxy for quiet/deep sleep. When ZCMn is not present in the data, all sleep epochs are mapped to "Sleep".

The stage column is an ordered factor with levels c("W", "Sleep", "Quiet sleep"), matching hypnoR's coarse resolution contract. "Quiet sleep" is not produced by actigraphy but the level is present so downstream hypnoR functions do not throw factor-level errors.

subject_id is taken from result$subject_id when not explicitly supplied. Both run_pipeline() and run_pipeline_native() derive this from the input filename stem automatically, so in most cases no manual override is needed.

Value

A tibble with columns:

epoch

Integer epoch index, 1-based.

time

POSIXct timestamp for the start of each epoch.

stage

Ordered factor: c("W", "Sleep", "Quiet sleep").

subject_id

Character subject identifier (omitted when not available).

source

Character scorer label.

See Also

run_pipeline(), run_pipeline_native(), label_states()

Examples

## Not run: 
result <- run_pipeline("recordings/P001.txt", tz = "America/Sao_Paulo")

# subject_id inferred from filename automatically
hyp <- export_hypnogram(result)
hyp$subject_id  # "P001"

# Override when filename does not match study code
hyp <- export_hypnogram(result, subject_id = "STUDY_001")

# Batch: subject_id inferred for every file automatically
results <- run_pipeline_batch("recordings/", tz = "America/Sao_Paulo")
hyps    <- lapply(results, export_hypnogram)

# Drop off-wrist epochs
hyp_clean <- export_hypnogram(result, drop_offwrist = TRUE)

## End(Not run)

Extract sleep episodes from a CSPD-scored epoch table

Description

Converts the epoch-level state vector produced by detect_sleep_crespo() into a per-episode tibble analogous to the Python SleepPipeline's results.nights. Contiguous on-wrist sleep periods are delimited by .nights_df(); per-epoch wake/sleep within each period is scored by score_epochs_cole_kripke() to derive WASO, SOL, SOI, TST, EFF, and NW. All time metrics are returned in minutes.

Usage

extract_sleep_episodes(data, wake_thresh = 60L)

Arguments

data

A tibble as returned by detect_sleep_crespo(), containing columns datetime, ZCMn, and state.

wake_thresh

integer(1). Minimum wake-bout length (epochs) used by .nights_df() to separate episode boundaries. Default 60L.

Value

A tibble with one row per detected episode and columns bts (POSIXct), gts (POSIXct), tbt, tst, sol, soi, waso (minutes), nw (integer), eff (0-1), nap (logical, always FALSE – classification into main/secondary happens in classify_sleep_episodes()).

See Also

classify_sleep_episodes(), run_pipeline_native()


Convert integer epoch states to a labelled factor

Description

Converts the integer state column produced by the zeitR pipeline into a human-readable factor. Useful for display, plotting, and export — the internal state column always stays integer to preserve Python reference parity.

Usage

label_states(x)

Arguments

x

integer (or numeric) vector of epoch states, as found in result$data$state.

Details

Integer Label
0 "wake"
1 "sleep"
4 "off-wrist"
7 "nap"

Any value not in the table above is silently converted to NA.

Value

An ordered factor with levels c("wake", "sleep", "nap", "off-wrist"), the same length as x.

Examples

label_states(c(0L, 1L, 0L, 4L, 1L, 7L))
# [1] wake  sleep wake  off-wrist sleep nap
# Levels: wake < sleep < nap < off-wrist

## Not run: 
result <- run_pipeline("recordings/P001.txt")
result$data$state_label <- label_states(result$data$state)

## End(Not run)

Published activity-count equations for estimating METs and PA intensity

Description

Returns the regression coefficients and count-based cut-points for estimating energy expenditure (METs) and classifying physical activity (PA) intensity from ActTrust(R) (Condor Instruments) or ActiGraph(R) GT3X+ activity counts, hip or wrist placement.

Usage

pa_equations(equation_set = "batista2026")

Arguments

equation_set

character(1). Currently only "batista2026" is available.

Value

A tibble with one row per device x placement combination and columns:

device

"ACTT" or "GT3X+".

placement

"hip" or "wrist".

b0, b1

Intercept and slope of sqrt(MET) = b0 + b1 * sqrt(activity_counts).

cut3, cut6, cut9

Published count/min cut-points (95% CI midpoints) at the 3, 6, and 9 MET thresholds – i.e. the count value at which the fitted equation crosses that MET level. Provided for reference; classify_pa_intensity() classifies on estimated METs directly rather than re-deriving these.

Important caveats

These equations come from a single controlled-laboratory validation study (Batista et al. 2026; N = 56 healthy adults aged 18-35; treadmill walking/running at 3-9 km/h only). Treat them as one available equation set, not a universal standard:

  • The paper's own Discussion section compares its GT3X+ (hip) cut-points against two other published GT3X+ studies (Sasaki et al. 2011; Santos-Lozano et al. 2013) and finds differences of 2-65% depending on the MET threshold – and those two reference studies differ from each other by 16-39%. The paper attributes that spread mainly to sample-level characteristics rather than device or methodological artefacts, but that reading applies to the comparison between Sasaki and Santos-Lozano – it doesn't fully carry over to comparisons against this paper's own equations, since all three studies used different modelling approaches (Sasaki et al.: ActiGraph's two-regression model; Santos-Lozano et al.: an artificial neural network; this paper: a simple sqrt-transformed linear model with a device x placement interaction). Cross-study cut-point differences therefore reflect model choice as well as sample, not sample alone – and that's checkable to different degrees: this paper's linear coefficients (b0/b1 below) are transparent enough to compare term-by-term against Sasaki et al.'s two-regression model, so a discrepancy there is at least diagnosable. Santos-Lozano et al.'s cut-points come from an ANN, which has no inspectable coefficients – there is no way to say why it disagrees with the equations here, only that it does.

  • The ACTT (hip)/ACTT (wrist) equations are the first published cut-points for ActTrust(R) at all, so there is nothing yet to cross-check them against.

  • Validated only for laboratory treadmill walking/running in healthy young adults. Applying these equations to free-living data, other age groups (children, older adults), clinical populations, or other activity types is an extrapolation the source study explicitly flags as untested.

equation_set is exposed as an explicit argument (rather than hard-coding a single table) so a future validation study covering a different population or device can be added as an alternative set without changing the estimate_ee() / classify_pa_intensity() API.

See Also

estimate_ee(), classify_pa_intensity()

Examples

pa_equations()

Plot a single-column actogram

Description

Renders epoch-level sleep/wake states as a raster with one row per calendar day and time-of-day (00:00 to 24:00) on the x-axis. The oldest day is at the top, following standard chronobiology convention.

Usage

plot_actogram(
  result,
  tz = NULL,
  title = NULL,
  colours = NULL,
  date_label_every = 7L,
  epoch_min = 1,
  base_size = 13
)

Arguments

result

A zeitr_result list (from run_pipeline() or run_pipeline_native()), or a tibble with at least datetime and state columns.

tz

character(1) or NULL. Timezone for date and time-of-day extraction. NULL (default) auto-detects from the timezone attribute embedded in the datetime POSIXct column; falls back to "UTC" when absent.

title

character(1) or NULL. Plot title. NULL constructs "Actogram \u2014 <subject_id>" from result$subject_id when available.

colours

Named character vector mapping state labels ("wake", "sleep", "nap", "off-wrist") to hex colours. NULL uses actogram_colours().

date_label_every

integer(1). Label every Nth row on the y-axis. Default 7 (weekly ticks).

epoch_min

numeric(1). Epoch duration in minutes. Used as the tile width in ggplot2::geom_tile(). Default 1 (ActTrust standard).

base_size

numeric(1). Base font size passed to ggplot2::theme_minimal(). Default 13.

Value

A ggplot object.

See Also

plot_actogram_double(), plot_actogram_activity(), actogram_colours(), label_states()

Examples

## Not run: 
result <- run_pipeline("recordings/P001.txt", tz = "America/Sao_Paulo")

# Default colours
plot_actogram(result)

# Custom colours
plot_actogram(result, colours = c(wake = "#E8D5B0", sleep = "#1C1A2E",
                                  nap = "#F0A500", "off-wrist" = "#C25E2A"))

# Label every 14 days
plot_actogram(result, date_label_every = 14L)

## End(Not run)

Plot a double-plotted actogram with activity bars

Description

Same double-plot layout as plot_actogram_double() — each day appears in both the left and right column of adjacent rows — but each epoch is rendered as a vertical bar whose height is proportional to the raw activity count (default: ZCMn, the zero-crossing mean from ActTrust). Bars are coloured by sleep/wake state, so the plot simultaneously conveys activity intensity and state classification.

Usage

plot_actogram_activity(
  result,
  tz = NULL,
  title = NULL,
  colours = NULL,
  activity_col = "ZCMn",
  activity_cap_quantile = 0.99,
  log_scale = FALSE,
  date_label_every = 7L,
  epoch_min = 1,
  base_size = 13
)

Arguments

result

A zeitr_result list (from run_pipeline() or run_pipeline_native()), or a tibble with at least datetime and state columns.

tz

character(1) or NULL. Timezone for date and time-of-day extraction. NULL (default) auto-detects from the timezone attribute embedded in the datetime POSIXct column; falls back to "UTC" when absent.

title

character(1) or NULL. Plot title. NULL constructs "Actogram \u2014 <subject_id>" from result$subject_id when available.

colours

Named character vector mapping state labels ("wake", "sleep", "nap", "off-wrist") to hex colours. NULL uses actogram_colours().

activity_col

character(1). Name of the column in result$data to use as the activity signal. Default "ZCMn" (zero-crossing mean; present in all ActTrust recordings processed by zeitR).

activity_cap_quantile

numeric(1) in (0, 1]. Quantile of non-zero activity values used to cap bar heights before normalising. Default 0.99 (top 1 % of active epochs are clipped to full bar height).

log_scale

logical(1). If TRUE, applies a log1p() transform to the activity signal before capping and normalising, compressing the dynamic range so lower-activity variation is easier to see. Default FALSE (linear scale).

date_label_every

integer(1). Label every Nth row on the y-axis. Default 7 (weekly ticks).

epoch_min

numeric(1). Epoch duration in minutes. Used as the tile width in ggplot2::geom_tile(). Default 1 (ActTrust standard).

base_size

numeric(1). Base font size passed to ggplot2::theme_minimal(). Default 13.

Details

Bar heights are capped at the activity_cap_quantile quantile of non-zero epochs to prevent outlier activity bursts from compressing the visible range for the rest of the recording. A thin baseline stub (2 % of row height) is drawn for zero-activity epochs so that sleep periods and off-wrist blocks remain faintly visible.

Actigraphy activity counts are typically right-skewed, with occasional bursts far above the typical waking level. On the default linear scale this compresses most of the meaningful variation among low-to-moderate activity epochs into a thin sliver near the baseline. Set log_scale = TRUE to apply a log1p() transform (log(1 + x), so zero-activity epochs map to 0 rather than -Inf) before capping and normalising – this expands the low-activity range at the cost of visually compressing the difference between already-high activity bursts.

Value

A ggplot object.

See Also

plot_actogram(), plot_actogram_double(), actogram_colours()

Examples

## Not run: 
result <- run_pipeline("recordings/P001.txt", tz = "America/Sao_Paulo")
plot_actogram_activity(result)

# Cap at 95th percentile to highlight moderate activity
plot_actogram_activity(result, activity_cap_quantile = 0.95)

# Log scale: reveals structure among low-activity epochs that a linear
# scale would otherwise compress near the baseline
plot_actogram_activity(result, log_scale = TRUE)

## End(Not run)

Plot a double-plotted actogram

Description

The classic chronobiology double-plot format. Each recording day is drawn twice: in the left column of its own row (x = 00:00 to 24:00) and in the right column of the row above (x = 24:00 to 48:00). This means consecutive pairs of days share a row, making circadian phase drift visible as a diagonal band across rows.

Usage

plot_actogram_double(
  result,
  tz = NULL,
  title = NULL,
  colours = NULL,
  date_label_every = 7L,
  epoch_min = 1,
  base_size = 13
)

Arguments

result

A zeitr_result list (from run_pipeline() or run_pipeline_native()), or a tibble with at least datetime and state columns.

tz

character(1) or NULL. Timezone for date and time-of-day extraction. NULL (default) auto-detects from the timezone attribute embedded in the datetime POSIXct column; falls back to "UTC" when absent.

title

character(1) or NULL. Plot title. NULL constructs "Actogram \u2014 <subject_id>" from result$subject_id when available.

colours

Named character vector mapping state labels ("wake", "sleep", "nap", "off-wrist") to hex colours. NULL uses actogram_colours().

date_label_every

integer(1). Label every Nth row on the y-axis. Default 7 (weekly ticks).

epoch_min

numeric(1). Epoch duration in minutes. Used as the tile width in ggplot2::geom_tile(). Default 1 (ActTrust standard).

base_size

numeric(1). Base font size passed to ggplot2::theme_minimal(). Default 13.

Details

Row ii shows day ii on the left and day i+1i+1 on the right. Every day therefore appears twice in the plot (except the first, which has no left-column predecessor, and the last, which has no right-column successor). A dashed vertical line marks the 24 h boundary between the two columns.

Value

A ggplot object.

See Also

plot_actogram(), plot_actogram_activity(), actogram_colours()

Examples

## Not run: 
result <- run_pipeline("recordings/P001.txt", tz = "America/Sao_Paulo")
plot_actogram_double(result)

## End(Not run)

Prepare a raw actigraphy tibble for analysis

Description

Transforms the output of read_acttrust() (or any reader that returns a compatible tibble) into the working data frame expected by all detection functions. Specifically:

Usage

prepare_actigraphy(x)

Arguments

x

A tibble as returned by read_acttrust(), containing at minimum int_temp and ext_temp columns.

Details

  1. Clamps int_temp and ext_temp to the physiological range [0, 42] °C.

  2. Adds min-max scaled temperature columns int_temp_ and ext_temp_ (range [0, 1]) for plotting.

  3. Ensures state, offwrist, and sleep columns are present and initialised to 0.

The original tibble is never modified; a copy is returned.

Value

A tibble of the same dimensions as x with additional or updated columns: state, offwrist, sleep, int_temp_, ext_temp_.

Examples

## Not run: 
rec  <- read_acttrust("recordings/P001.txt")
prep <- prepare_actigraphy(rec)

## End(Not run)

Read an actigraphy file into a zeitr_recording object

Description

A device-agnostic wrapper that reads a raw actigraphy file and returns a zeitr_recording object with ⁠$epochs⁠ (a tidy tibble) and ⁠$metadata⁠ (a named list of device and recording information).

Usage

read_actigraphy(path, device = "acttrust", tz = "UTC", ...)

Arguments

path

character(1). Path to the raw actigraphy file.

device

character(1). Device type. One of "acttrust" (default) or "axivity". Additional devices will be added in future versions.

tz

character(1). Recording time zone passed to the underlying reader. Default is "UTC".

...

Additional arguments forwarded to the device-specific reader (e.g. encoding for read_acttrust()).

Details

Currently supported devices:

  • "acttrust" — Condor Instruments ActTrust / ActTrust2 (.txt)

  • "axivity" — Axivity AX3/AX6 (.cwa), via read_axivity() (requires the axR package; converts raw acceleration to epoch-level counts with compute_activity_counts() – see read_axivity()'s Details for validation caveats)

Value

A zeitr_recording S3 object — a named list with:

⁠$epochs⁠

A tibble with one row per epoch and columns datetime, activity, int_temp, ext_temp, ZCMn, state, offwrist, sleep.

⁠$metadata⁠

A named list with subject, device_id, device_model, firmware_version, interval_s, source_file, and participant_id (derived from the filename stem).

See Also

read_actigraphy_dir() to read a whole directory at once.

Examples

## Not run: 
rec <- read_actigraphy("recordings/P001.txt")
rec$epochs
rec$metadata

## End(Not run)

Read all actigraphy files in a directory

Description

Applies read_actigraphy() to every file matching pattern in folder. Returns a zeitr_study object — a named list of zeitr_recording objects, one per file. Files that fail to parse are skipped with a warning.

Usage

read_actigraphy_dir(
  folder,
  device = "acttrust",
  pattern = "*.txt",
  tz = "UTC",
  ...
)

Arguments

folder

character(1). Path to a directory containing actigraphy files.

device

character(1). Device type passed to read_actigraphy(). Default is "acttrust".

pattern

character(1). Glob pattern for file discovery. Default is "*.txt".

tz

character(1). Recording time zone. Default is "UTC".

...

Additional arguments forwarded to read_actigraphy().

Value

A zeitr_study S3 object — a named list of zeitr_recording objects. Names are participant IDs (filename stems).

See Also

study_summary() to summarise a zeitr_study.

Examples

## Not run: 
study <- read_actigraphy_dir("recordings/", tz = "America/Sao_Paulo")
study_summary(study)

## End(Not run)

Read a Condor Instruments ActTrust actigraphy file

Description

Parses a Condor ActTrust .txt export into a tidy tibble. The file format consists of a variable-length key-value header block followed by semicolon-delimited epoch rows. The header ends at the line beginning with DATE/TIME.

Usage

read_acttrust(path, tz = "UTC", encoding = "latin1")

Arguments

path

character(1) or fs::path. Path to the ActTrust .txt file.

tz

character(1). Time zone string passed to lubridate::parse_date_time(). Defaults to "UTC". Set to the local recording time zone for correct circadian alignment.

encoding

character(1). File encoding. Defaults to "latin1", which matches Condor's default export encoding.

Value

A tibble with one row per epoch and the following columns:

datetime

POSIXct — epoch timestamp.

activity

double — PIM activity count.

int_temp

double — internal (on-body) temperature, degC.

ext_temp

double — external (ambient) temperature, degC. NA if unavailable.

ZCMn

double — normalised zero-crossing mode count. NA if unavailable.

light

double — total light intensity (lux). NA if unavailable.

state

double — state column, initialised to 0.

offwrist

double — off-wrist indicator, initialised to 0.

sleep

double — sleep indicator, initialised to 0.

The tibble carries a "zeitr_acttrust" class and a metadata attribute (a named list with subject, device_id, device_model, firmware_version, interval_s, source_file).

Examples

## Not run: 
rec <- read_acttrust("recordings/P001.txt")
rec
attr(rec, "metadata")

## End(Not run)

Read an Axivity AX3/AX6 .cwa file into a zeitR-standard epoch tibble

Description

Bridges axR::axivity_read_cwa()'s raw per-sample output (triaxial acceleration at the device's native sampling rate) into the same epoch-level, 9-column shape read_acttrust() produces – so an Axivity recording can flow through the rest of zeitR (run_pipeline(), compute_npcra(), compute_sri(), etc.) exactly like an ActTrust one.

Usage

read_axivity(
  path,
  tz = "UTC",
  epoch_sec = 60,
  filter_low = 0.25,
  filter_high = 2.5,
  zcm_threshold = 0.01,
  tat_threshold = 0.05
)

Arguments

path

character(1). Path to a .cwa/AX6 file, forwarded to axR::axivity_read_cwa().

tz

character(1). Time zone the device's clock was set to. Default "UTC".

epoch_sec

numeric(1). Epoch length in seconds, forwarded to compute_activity_counts(). Default 60, matching the rest of zeitR.

filter_low, filter_high

numeric(1). Band-pass cutoffs in Hz, forwarded to compute_activity_counts(). Default 0.25/2.5 (GT3X+-style preset – see Details; no validated Axivity-specific preset exists).

zcm_threshold, tat_threshold

numeric(1). Forwarded to compute_activity_counts(). Defaults 0.01/0.05.

Value

A tibble with one row per epoch and the same columns as read_acttrust() (datetime, activity, int_temp, ext_temp, ZCMn, light, state, offwrist, sleep), plus one extra column not present there: TAT (time above threshold, seconds/epoch, from compute_activity_counts()). activity is PIM. ext_temp is always NA – Axivity devices have a single on-body temperature sensor, no separate ambient sensor. The tibble carries a "zeitr_axivity" class and a metadata attribute (a named list with device_id, session_id, sample_rate, epoch_sec, filter_low, filter_high, cwa_metadata (axR's raw device metadata string), source_file).

What this does (and doesn't) validate

The raw-to-counts conversion itself is compute_activity_counts() – already documented there as an unvalidated approximation of onboard device processing (no reference converter exists to check it against). Axivity devices additionally have no published or validated filter/threshold preset at all (unlike ActTrust and GT3X+, which at least have a documented processing description to approximate). The filter_low/filter_high defaults here (0.25/2.5 Hz) are compute_activity_counts()'s GT3X+-style preset, reused because it's the closer starting point of the two existing options for a research-grade wrist accelerometer like the AX3 – not because it has been checked against real Axivity output. Treat activity/ZCMn from this function as a rough approximation only; validate against a reference (e.g. GGIR) before relying on it for any published analysis.

ZCMn is compute_activity_counts()'s raw ZCM count with no additional normalisation applied – named ZCMn only for column-name compatibility with read_acttrust()'s CK-scoring input, not because a normalisation step has actually been performed.

Sampling rate

axivity_read_cwa() reports sample_rate per sample (block-level, as stored in the .cwa file). This function takes the single most common value across the whole recording and uses it for the entire conversion; if any samples report a different rate (a genuine rate change mid recording, or a corrupt block), a warning names the discrepancy but the dominant rate is still used throughout. Epoch boundaries and grouping for light/int_temp averaging are derived from this same dominant rate, matching compute_activity_counts()'s own epoch grouping exactly (including which trailing samples get dropped).

Time zone

axivity_read_cwa() tags timestamp as UTC by convention (the device's own real-time clock, not a true UTC source) – exactly like read_acttrust() does for ActTrust's DATE/TIME column. tz here re-labels the same clock reading under the recording's actual local time zone (via lubridate::force_tz(); no shift in wall-clock value), rather than converting it – set it to the time zone the device's clock was actually set to for correct circadian alignment downstream.

See Also

read_actigraphy() (device = "axivity"), compute_activity_counts() for the underlying raw-to-counts conversion and its validation caveats, read_acttrust() for the column shape this matches.

Examples

## Not run: 
rec <- read_axivity("recordings/P001.cwa", tz = "America/Sao_Paulo")
rec
attr(rec, "metadata")

## End(Not run)

Run the full actigraphy sleep analysis pipeline

Description

Orchestrates the complete pipeline for a single ActTrust recording:

Usage

run_pipeline(
  path,
  tz = "UTC",
  gap_s = 120,
  params = acttrust_params(),
  offwrist_args = list(),
  sleep_args = list(),
  nap_args = list(),
  quiet = FALSE
)

Arguments

path

character(1). Path to the ActTrust .txt file.

tz

character(1). Recording time zone. Passed to read_acttrust(). Default is "UTC".

gap_s

numeric(1). Gap threshold (seconds) for check_consistency(). Default is 120.

params

Device parameter preset, as returned by acttrust_params(). When supplied, values from params are used as defaults for each detector stage, with any explicit offwrist_args, sleep_args, or nap_args taking precedence. Defaults to acttrust_params().

offwrist_args

list. Additional arguments passed to detect_offwrist_bimodal(). Default is an empty list.

sleep_args

list. Additional arguments passed to detect_sleep_crespo(). Default is an empty list.

nap_args

list. Additional arguments passed to detect_naps_crespo(). Default is an empty list.

quiet

logical(1). If TRUE, suppresses the timestamp-issue warning emitted when check_consistency() finds problems. Useful in batch or testing contexts where the warning is expected. Default is FALSE.

Details

  1. Readread_acttrust()

  2. Consistency checkcheck_consistency()

  3. Prepareprepare_actigraphy()

  4. Off-wrist detectiondetect_offwrist_bimodal()

  5. Main sleep period detectiondetect_sleep_crespo()

  6. Nap detectiondetect_naps_crespo()

  7. WASO + nightly statisticscompute_waso()

Value

A zeitr_result S3 object — a named list with:

subject_id

character — derived from the input filename stem.

source_file

character — absolute path to the input file.

data

tibble — final epoch-level data frame with all state columns populated.

nights

tibble — per-night sleep statistics.

issues

tibble — timestamp consistency issues (0 rows if none).

metadata

list — device and subject metadata from the file header.

See Also

run_pipeline_batch() for processing a directory of files.

Examples

## Not run: 
result <- run_pipeline("recordings/P001.txt", tz = "America/Sao_Paulo")
result$nights
result$data

## End(Not run)

Run the pipeline on all files in a directory

Description

Applies run_pipeline() to every file matching pattern in folder, returning a list of zeitr_result objects. Files that fail are skipped with a warning.

Usage

run_pipeline_batch(folder, pattern = "*.txt", parallel = FALSE, ...)

Arguments

folder

character(1). Path to a directory containing ActTrust files.

pattern

character(1). Glob pattern for file discovery. Default is "*.txt".

parallel

logical(1). If TRUE, processes files in parallel using future.apply::future_lapply() (a Suggests-only dependency). Requires a future::plan() to be set beforehand, e.g. future::plan(future::multisession(workers = 4)); falls back to sequential processing with a warning if future.apply is not installed. Default FALSE.

...

Additional arguments forwarded to run_pipeline().

Value

A named list of zeitr_result objects, one per successfully processed file. Names are the file stem (subject IDs).

Examples

## Not run: 
results <- run_pipeline_batch("recordings/", tz = "America/Sao_Paulo")
lapply(results, function(r) r$nights)

# Parallel: process a large cohort across 4 workers
future::plan(future::multisession(workers = 4))
results <- run_pipeline_batch("recordings/", tz = "America/Sao_Paulo",
                               parallel = TRUE)

## End(Not run)

Run the Vallim native actigraphy sleep analysis pipeline

Description

Orchestrates the vendor-independent (Vallim) sleep analysis pipeline for a single ActTrust recording. Shares the read / prepare / off-wrist / CSPD epoch-scorer stages with run_pipeline(), then replaces Condor's nights_df classification with the rule set developed by Julia Ribeiro da Silva Vallim and ported from her condor pipeline (Fixes 25, 26a/b/c, 27, 29).

Usage

run_pipeline_native(
  path,
  tz = "UTC",
  gap_s = 120,
  params = acttrust_params(),
  offwrist_args = list(),
  sleep_args = list(),
  classify_args = list(),
  holidays = NULL,
  free_days = c("Saturday", "Sunday"),
  quiet = FALSE
)

Arguments

path

character(1). Path to the ActTrust .txt file.

tz

character(1). Recording time zone. Default "UTC".

gap_s

numeric(1). Gap threshold (seconds) for check_consistency(). Default 120.

params

Device parameter preset, as returned by acttrust_params().

offwrist_args

list. Additional arguments for detect_offwrist_bimodal().

sleep_args

list. Additional arguments for detect_sleep_crespo().

classify_args

list. Additional arguments for classify_sleep_episodes().

holidays

Holidays to treat as free days in addition to the days in free_days. Accepts three forms, which can be mixed in the same vector:

  • Date objects or "YYYY-MM-DD" strings for year-specific dates (e.g. as.Date("2019-03-04") for one Carnival day).

  • "DD-MM" strings for dates that recur every year (e.g. "25-12" for Christmas, "07-09" for Brazilian Independence Day). Stored in result$holidays and auto-forwarded by the zeitr_result S3 methods of compute_sleep_metrics() and compute_cpd_metrics(). Default NULL.

free_days

A character vector of day names ("Monday" through "Sunday", case-insensitive) or ISO integers (1 = Monday ... 7 = Sunday) identifying which days of the week are unconditionally treated as free days. Stored in result$free_days and auto-forwarded by the zeitr_result S3 methods of compute_sleep_metrics() and compute_cpd_metrics(). Default c("Saturday", "Sunday").

quiet

logical(1). Suppress timestamp warnings. Default FALSE.

Details

Steps:

  1. Readread_acttrust()

  2. Consistency checkcheck_consistency()

  3. Prepareprepare_actigraphy()

  4. Off-wrist detectiondetect_offwrist_bimodal()

  5. Epoch scoringdetect_sleep_crespo() (CSPD; same scorer as run_pipeline())

  6. Episode extractionextract_sleep_episodes()

  7. Episode classificationclassify_sleep_episodes() (JRSV rules)

  8. Fine-grained statecompute_waso() (Cole-Kripke within periods, for result$data)

Value

A zeitr_result S3 object with the same structure as run_pipeline(), except nights additionally contains:

sleep_type

character"main" or "secondary".

bed_time, get_up_time

POSIXct – from JRSV bts/gts convention (last sleep epoch for get-up, not first wake epoch).

The is_nap column is retained for backwards compatibility (is_nap == (sleep_type == "secondary")).

See Also

run_pipeline() for the vendor (Condor) pipeline, extract_sleep_episodes(), classify_sleep_episodes()

Examples

## Not run: 
result <- run_pipeline_native("recordings/P001.txt", tz = "America/Sao_Paulo")
result$nights

## End(Not run)

Run the native pipeline on all files in a directory

Description

Applies run_pipeline_native() to every file matching pattern in folder, returning a named list of zeitr_result objects. Files that fail are skipped with a warning.

Usage

run_pipeline_native_batch(folder, pattern = "*.txt", parallel = FALSE, ...)

Arguments

folder

character(1). Path to a directory of ActTrust files.

pattern

character(1). Glob pattern. Default "*.txt".

parallel

logical(1). If TRUE, processes files in parallel using future.apply::future_lapply() (a Suggests-only dependency). Requires a future::plan() to be set beforehand, e.g. future::plan(future::multisession(workers = 4)); falls back to sequential processing with a warning if future.apply is not installed. Default FALSE.

...

Additional arguments forwarded to run_pipeline_native().

Value

A named list of zeitr_result objects.

Examples

## Not run: 
results <- run_pipeline_native_batch("recordings/", tz = "America/Sao_Paulo")
lapply(results, function(r) r$nights)

# Parallel: process a large cohort across 4 workers
future::plan(future::multisession(workers = 4))
results <- run_pipeline_native_batch("recordings/", tz = "America/Sao_Paulo",
                                     parallel = TRUE)

## End(Not run)

Score actigraphy epochs as wake or sleep using the Cole-Kripke algorithm

Description

Applies the Cole-Kripke algorithm to a vector of zero-crossing mode (ZCM) activity counts, scoring each epoch as wake (1) or sleep (0) using a weighted sum of activity in a surrounding window.

Usage

score_epochs_cole_kripke(
  zcm,
  P = 0.000464,
  weights_before = c(34.5, 133, 529, 375, 408, 400.5, 1074, 2048.5, 2424.5),
  weights_after = c(1920, 149.5, 257.5, 125, 111.5, 120, 69, 40.5)
)

Arguments

zcm

numeric vector of ZCM activity counts, one value per epoch.

P

numeric(1). Scaling factor. Default is 0.000464 (Cole et al., 1992).

weights_before

numeric(9). Weights applied to the 9 epochs before the current epoch. Defaults to the values from Cole et al. (1992), Table 2.

weights_after

numeric(8). Weights applied to the 8 epochs after the current epoch. Defaults to the values from Cole et al. (1992), Table 2.

Details

Each epoch's score is computed as:

Di=Pj=19WjAij+Pj=18Wj+Ai+jD_i = P \sum_{j=1}^{9} W_j^{-} \cdot A_{i-j} + P \sum_{j=1}^{8} W_j^{+} \cdot A_{i+j}

where AiA_i is the ZCM count at epoch ii, WW^{-} and W+W^{+} are the before and after weight vectors from Cole et al. (1992), and P=0.000464P = 0.000464. Epochs with Di1D_i \ge 1 are scored as wake.

Value

An integer vector the same length as zcm, with 1 indicating wake and 0 indicating sleep.

References

Cole, R. J., Kripke, D. F., Gruen, W., Mullaney, D. J., & Gillin, J. C. (1992). Automatic sleep/wake identification from wrist activity. Sleep, 15(5), 461–469. doi:10.1093/sleep/15.5.461

Examples

## Not run: 
rec    <- read_acttrust("recordings/P001.txt")
scores <- score_epochs_cole_kripke(rec$ZCMn)
table(scores)  # 0 = sleep, 1 = wake

## End(Not run)

Batch sleep-timing and chronotype metrics across a study

Description

Computes compute_sleep_metrics() and compute_cpd_metrics() for every participant in a batch of pipeline results and stacks them into a single tibble with one row per participant – the sleep-timing/chronotype counterpart to study_summary(), which covers NPCRA activity-rhythm variables instead.

Usage

study_sleep_metrics(
  results,
  min_tib_h = 5,
  min_tib_eve_h = 3,
  tz = "UTC",
  holidays = NULL,
  free_days = NULL
)

Arguments

results

A named list of zeitr_result objects, as returned by run_pipeline_batch() or run_pipeline_native_batch(). participant_id is taken from each result's own ⁠$subject_id⁠, falling back to the list name if that is unavailable.

min_tib_h

numeric(1). Minimum total in-bed time (hours) for a night to be included in compute_sleep_metrics(). Default 5.0.

min_tib_eve_h

numeric(1). Minimum TBT (hours) for a night to qualify as a free-day-eve night in compute_cpd_metrics(). Default 3.0.

tz

character(1). Time zone for extracting clock hours. Default "UTC".

holidays, free_days

Forwarded to both compute_sleep_metrics() and compute_cpd_metrics() for every participant. Default NULL for both, in which case each participant's own result$holidays/result$free_days (set when the pipeline was run) are used instead. Supplying either here overrides that per-participant default for the whole study.

Details

compute_sleep_metrics() and compute_cpd_metrics() each return a single named list per participant with no participant identifier, and there was previously no batch wrapper analogous to study_summary() for them. This is that wrapper – intended to make these chronobiological phenotyping metrics database-ready for tools like syncR::sync(), which expect one row per participant with a shared participant_id column across sources.

If either metric computation fails for a participant (e.g. no free days found, or no nights pass the min_tib_h filter), that participant's row is filled with NA for the affected metrics and a warning is emitted – the rest of the study is unaffected.

Value

A tibble with one row per participant: participant_id, all compute_sleep_metrics() columns (n_overall/n_wd/n_fd and the twelve sleep-timing metrics with ⁠_wd⁠/⁠_fd⁠ suffixes), and all compute_cpd_metrics() columns (n_nights_cpd, n_free_days, n_workdays, msw_h/msf_h/msfsc_h and their ⁠_hms⁠ forms, sjl_h, sjla_h, cpd_s/cpd_min/cpd_h).

See Also

study_summary() for the NPCRA (activity-rhythm) analogue, compute_sleep_metrics(), compute_cpd_metrics(), run_pipeline_native_batch()

Examples

## Not run: 
results <- run_pipeline_native_batch("recordings/", tz = "America/Sao_Paulo")
study_sleep_metrics(results)

# Feed straight into syncR::sync()
sync(zeit = study_sleep_metrics(results))

## End(Not run)

Summarise a zeitr_study across participants

Description

Computes per-participant summary statistics from a zeitr_study object (as returned by read_actigraphy_dir()). For each recording, the function computes NPCRA variables (IS, IV, RA, L5, M10) and basic recording quality metrics.

Usage

study_summary(study, epoch_s = NULL, L5_hours = 5, M10_hours = 10)

Arguments

study

A zeitr_study object as returned by read_actigraphy_dir(), or a named list of zeitr_recording objects.

epoch_s

numeric(1). Epoch duration in seconds. If NULL (default), estimated separately for each recording.

L5_hours

numeric(1). Width of the L5 window in hours. Default is 5.

M10_hours

numeric(1). Width of the M10 window in hours. Default is 10.

Value

A tibble with one row per participant and columns:

participant_id

Participant identifier (filename stem).

n_epochs

Total number of epochs in the recording.

n_days

Recording duration in days.

start

POSIXct — first epoch timestamp.

end

POSIXct — last epoch timestamp.

IS

Interdaily stability.

IV

Intradaily variability.

RA

Relative amplitude.

L5

Mean activity in the least active 5 h window.

L5_onset

Clock time of L5 midpoint.

M10

Mean activity in the most active 10 h window.

M10_onset

Clock time of M10 midpoint.

See Also

compute_npcra() for single-recording NPCRA, read_actigraphy_dir() to create a zeitr_study, study_sleep_metrics() for the sleep-timing/ chronotype analogue (CPD, MSF/MSW, social jetlag).

Examples

## Not run: 
study <- read_actigraphy_dir("recordings/", tz = "America/Sao_Paulo")
study_summary(study)

## End(Not run)