% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cgmguru-functions-docs.R
\encoding{UTF-8}
\name{detect_hypoglycemic_events}
\alias{detect_hypoglycemic_events}
\title{Detect Hypoglycemic Events}
\usage{
detect_hypoglycemic_events(df, ..., type = "extended",
 reading_minutes = NULL, sort_time = FALSE, inter_gap = 45,
 return_interpolated = TRUE)
}
\arguments{
\item{df}{A dataframe containing continuous glucose monitoring (CGM) data.
Must include columns:
\itemize{
  \item \code{id}: Subject identifier (string or factor)
  \item \code{time}: Time of measurement (POSIXct)
  \item \code{gl}: Glucose value (integer or numeric, mg/dL)
}}

\item{...}{Custom event criteria supplied by name. Prefer \code{type} for
standard Level 1, Level 2, and Extended events. Supported custom criteria
are:
\itemize{
  \item \code{dur_length}: Minimum event duration in minutes required for
    an event to qualify.
  \item \code{end_length}: Required recovery duration in minutes before
    event termination is confirmed.
  \item \code{start_gl}: Glucose threshold in mg/dL used to qualify
    hypoglycemic readings. Hypoglycemic readings are below this value, and
    recovery is confirmed after glucose remains at or above this value for
    \code{end_length} minutes.
}}

\item{type}{Hypoglycemia event definition. One of \code{"extended"}
(default), \code{"lv1"}, \code{"lv2"}, or \code{"lv1_excl"}.}

\item{reading_minutes}{Time interval between readings in minutes (optional).
If omitted or \code{NULL}, the interval is calculated automatically per id
as the median positive time difference in the data.}

\item{sort_time}{Logical. If \code{TRUE}, sort rows within each id by
\code{time} in C++ before interpolation. Defaults to \code{FALSE}.}

\item{inter_gap}{Maximum gap in minutes to interpolate across. Defaults to
45; larger gaps split event-detection segments.}

\item{return_interpolated}{Logical. If \code{TRUE}, include the interpolated
grid data used for event detection in the returned list. Defaults to
\code{TRUE}.}
}
\value{
A list containing:
\itemize{
  \item \code{events_total}: Tibble with summary statistics per subject (id, total_episodes, avg_ep_per_day)
  \item \code{events_detailed}: Tibble with detailed event information (id, start_time, start_glucose, end_time, end_glucose, start_index, end_index, duration_below_54_minutes). End fields report the last dysglycemic reading before confirmed recovery starts. \code{start_index} and \code{end_index} are 1-based row positions in the returned \code{interpolated_data}.
  \item \code{interpolated_data}: Included by default with columns
    \code{id}, \code{time}, and \code{gl}; set
    \code{return_interpolated = FALSE} to omit it.
}
}
\description{
Identifies and segments hypoglycemic events in CGM data based on international consensus
CGM metrics (Battelino et al., 2023). Use \code{type} to select one of
three event definitions:
\itemize{
  \item \strong{Level 1}: \eqn{\geq} 15 consecutive min of \eqn{<} 70 mg/dL, ends with \eqn{\geq} 15 consecutive min \eqn{\geq} 70 mg/dL
  \item \strong{Level 2}: \eqn{\geq} 15 consecutive min of \eqn{<} 54 mg/dL, ends with \eqn{\geq} 15 consecutive min \eqn{\geq} 54 mg/dL
  \item \strong{Extended}: \eqn{>} 120 consecutive min of \eqn{<} 70 mg/dL, ends with \eqn{\geq} 15 consecutive min \eqn{\geq} 70 mg/dL
}
Events are counted only after glucose remains at or above the recovery
threshold for the specified end length. In \code{events_detailed},
\code{end_time}, \code{end_glucose}, and \code{end_index} report the last
hypoglycemic reading immediately before that confirmed recovery period starts.
}
\section{Methods}{

Hypoglycemic events can be detected using either the recommended
\code{type} argument or named custom threshold and duration criteria.

\strong{1. Preset method using \code{type} (recommended):}
Use \code{type} when you want the standard Level 1, Level 2, or Extended
hypoglycemia definitions without manually entering thresholds.
\itemize{
  \item \code{type = "lv1"} uses \code{start_gl = 70},
    \code{dur_length = 15}, and \code{end_length = 15}.
  \item \code{type = "lv2"} uses \code{start_gl = 54},
    \code{dur_length = 15}, and \code{end_length = 15}.
  \item \code{type = "extended"} uses \code{start_gl = 70},
    \code{dur_length = 120}, and \code{end_length = 15}.
  \item \code{type = "lv1_excl"} returns Level 1 episodes that do not
    overlap Level 2 episodes.
}

\strong{2. Custom criteria method:}
Supply \code{start_gl}, \code{dur_length}, and \code{end_length} directly
when using a custom definition, for example
\code{detect_hypoglycemic_events(df, start_gl = 70, dur_length = 15,
end_length = 15)} for Level 1 hypoglycemia. If an explicit \code{type} is
supplied together with custom numeric criteria, the function returns results
based on \code{type}; the custom criteria are ignored and a warning is
issued.
}

\section{Units and sampling}{

- \code{reading_minutes} can be a scalar (all rows) or a vector per-row.
- If \code{reading_minutes} is omitted or \code{NULL}, it is calculated
  automatically per id from timestamp spacing.
- Event classification uses cgmguru's independent C++ implementation of an
  iglu-compatible, midnight-aligned full-day grid. Data are linearly
  interpolated at the id-specific interval up to \code{inter_gap}; larger
  gaps are masked, removed from the event-classification data, and split
  segments.
- This preprocessing is specific to event calculation and does not affect
  \code{\link{grid}}, \code{\link{maxima_grid}}, or \code{\link{excursion}}.
}

\examples{
# Load sample data
library(iglu)
data(example_data_5_subject)
data(example_data_hall)

# Level 1 Hypoglycemia Event (>=15 consecutive min of <70 mg/dL and event
# ends when there is >=15 consecutive min with a CGM sensor value of >=70 mg/dL)
hypo_lv1 <- detect_hypoglycemic_events(example_data_5_subject, type = "lv1")
print(hypo_lv1$events_total)

# Level 2 Hypoglycemia Event (>=15 consecutive min of <54 mg/dL and event
# ends when there is >=15 consecutive min with a CGM sensor value of >=54 mg/dL)
hypo_lv2 <- detect_hypoglycemic_events(example_data_5_subject, type = "lv2")

# Extended Hypoglycemia Event (>120 consecutive min of <70 mg/dL and event
# ends when there is >=15 consecutive min with a CGM sensor value of >=70 mg/dL)
hypo_extended <- detect_hypoglycemic_events(example_data_5_subject, type = "extended")
print(hypo_extended$events_total)

# Custom criteria method for the same standard definitions
hypo_lv1_custom <- detect_hypoglycemic_events(
  example_data_5_subject,
  start_gl = 70,
  dur_length = 15,
  end_length = 15
)
hypo_lv2_custom <- detect_hypoglycemic_events(
  example_data_5_subject,
  start_gl = 54,
  dur_length = 15,
  end_length = 15
)
hypo_extended_custom <- detect_hypoglycemic_events(
  example_data_5_subject,
  start_gl = 70,
  dur_length = 120,
  end_length = 15
)

# Compare event rates across levels
cat("Level 1 episodes:", sum(hypo_lv1$events_total$total_episodes), "\n")
cat("Level 2 episodes:", sum(hypo_lv2$events_total$total_episodes), "\n")
cat("Extended episodes:", sum(hypo_extended$events_total$total_episodes), "\n")

# Analysis on larger dataset with Level 1 criteria
large_hypo <- detect_hypoglycemic_events(example_data_hall, type = "lv1")
print(large_hypo$events_total)

# Analysis on larger dataset with Level 2 criteria
large_hypo_lv2 <- detect_hypoglycemic_events(example_data_hall, type = "lv2")
print(large_hypo_lv2$events_total)

# Analysis on larger dataset with Extended criteria
large_hypo_extended <- detect_hypoglycemic_events(example_data_hall, type = "extended")
print(large_hypo_extended$events_total)
}
\references{
Battelino, T., et al. (2023). Continuous glucose monitoring and metrics for clinical trials: an international consensus statement. The Lancet Diabetes & Endocrinology, 11(1), 42-57.
}
\seealso{
\link{detect_all_events}
}
