cgmguru::detect_all_events() is an independent C++/Rcpp
implementation of event calculation and CGM summary output. Its
preprocessing is designed to be compatible with the event grid semantics
used by iglu: subject-specific reading intervals, a
midnight-aligned full-day grid, interpolation up to
inter_gap, removal of larger gap-masked rows, and
segment-wise event classification.
When reading_minutes is omitted or NULL,
cgmguru calculates it automatically per subject from the median positive
timestamp spacing in the input data.
The iglu package is used here as a formal reference,
source of public example datasets, and comparison target. cgmguru does
not call iglu at runtime for its core algorithms.
We use two CGM example datasets shipped with iglu:
example_data_5_subject: 5 subjectsexample_data_hall: 19 subjectsdata(example_data_5_subject, package = "iglu")
data(example_data_hall, package = "iglu")
# Base-R summaries (no external dependencies)
summary_5 <- data.frame(
rows = nrow(example_data_5_subject),
subjects = length(unique(example_data_5_subject$id)),
time_min = min(example_data_5_subject$time),
time_max = max(example_data_5_subject$time),
gl_min = min(example_data_5_subject$gl, na.rm = TRUE),
gl_max = max(example_data_5_subject$gl, na.rm = TRUE)
)
summary_5
#> rows subjects time_min time_max gl_min gl_max
#> 1 13866 5 2015-02-24 17:31:29 2015-06-19 08:59:36 50 400iglu::episode_calculation() identifies
hypo/hyperglycemia episodes.
iglu_episodes_5 <- iglu::episode_calculation(
data = example_data_5_subject
)
print(iglu_episodes_5)
#> # A tibble: 35 × 7
#> id type level avg_ep_per_day avg_ep_duration avg_ep_gl total_episodes
#> <fct> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 Subject 1 hypo lv1 0.0899 35 68.6 1
#> 2 Subject 1 hypo lv2 0 0 NA 0
#> 3 Subject 1 hypo exte… 0 0 NA 0
#> 4 Subject 1 hyper lv1 1.44 80.3 200. 16
#> 5 Subject 1 hyper lv2 0.180 30 264. 2
#> 6 Subject 1 hypo lv1_… 0.0899 35 68.6 1
#> 7 Subject 1 hyper lv1_… 1.26 79.6 195. 14
#> 8 Subject 2 hypo lv1 0 0 NA 0
#> 9 Subject 2 hypo lv2 0 0 NA 0
#> 10 Subject 2 hypo exte… 0 0 NA 0
#> # ℹ 25 more rowsiglu_episodes_hall <- iglu::episode_calculation(
data = example_data_hall
)
print(iglu_episodes_hall)
#> # A tibble: 133 × 7
#> id type level avg_ep_per_day avg_ep_duration avg_ep_gl total_episodes
#> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 1636-69-… hypo lv1 0.468 15 68.1 3
#> 2 1636-69-… hypo lv2 0 0 NA 0
#> 3 1636-69-… hypo exte… 0 0 NA 0
#> 4 1636-69-… hyper lv1 0.623 57.5 201. 4
#> 5 1636-69-… hyper lv2 0 0 NA 0
#> 6 1636-69-… hypo lv1_… 0.468 15 68.1 3
#> 7 1636-69-… hyper lv1_… 0.623 57.5 201. 4
#> 8 1636-69-… hypo lv1 0 0 NA 0
#> 9 1636-69-… hypo lv2 0 0 NA 0
#> 10 1636-69-… hypo exte… 0 0 NA 0
#> # ℹ 123 more rowsall_events_5 <- detect_all_events(example_data_5_subject)
print(all_events_5)
#> $subject_summary
#> # A tibble: 5 × 22
#> id TIR TITR TBR70 TBR54 TAR180 TAR250 CV SD mean_glucose GMI
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Subject 1 91.7 73.7 0.14 0 8.2 0.38 26.9 33.3 124. 6.27
#> 2 Subject 2 26.4 3.36 0 0 73.6 26.1 24.0 52.4 218. 8.54
#> 3 Subject 3 81.3 49.8 0.33 0 18.3 5.68 29.1 44.8 154. 6.99
#> 4 Subject 4 95.1 67.7 0.27 0.05 4.61 0 22.4 29.1 130. 6.41
#> 5 Subject 5 62.1 30.1 0.1 0 37.8 11.3 33.6 58.6 175. 7.49
#> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear_percent <dbl>,
#> # hypo_lv1_total_episodes <int>, hypo_lv2_total_episodes <int>,
#> # hypo_extended_total_episodes <int>, hypo_lv1_excl_total_episodes <int>,
#> # hyper_lv1_total_episodes <int>, hyper_lv2_total_episodes <int>,
#> # hyper_extended_total_episodes <int>, hyper_lv1_excl_total_episodes <int>
#>
#> $glycemic_event_summary
#> # A tibble: 40 × 6
#> id type level total_episodes avg_ep_per_day avg_minutes_below_54…¹
#> <chr> <chr> <chr> <int> <dbl> <dbl>
#> 1 Subject 1 hypo lv1 1 0.09 0
#> 2 Subject 1 hypo lv2 0 0 0
#> 3 Subject 1 hypo extended 0 0 0
#> 4 Subject 1 hypo lv1_excl 1 0.09 0
#> 5 Subject 1 hyper lv1 16 1.44 0
#> 6 Subject 1 hyper lv2 2 0.18 0
#> 7 Subject 1 hyper extended 0 0 0
#> 8 Subject 1 hyper lv1_excl 14 1.26 0
#> 9 Subject 2 hypo lv1 0 0 0
#> 10 Subject 2 hypo lv2 0 0 0
#> # ℹ 30 more rows
#> # ℹ abbreviated name: ¹avg_minutes_below_54_per_episodeall_events_hall <- detect_all_events(example_data_hall)
print(all_events_hall)
#> $subject_summary
#> # A tibble: 19 × 22
#> id TIR TITR TBR70 TBR54 TAR180 TAR250 CV SD mean_glucose GMI
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1636-69… 96.9 88.0 0.54 0 2.55 0 25.2 27.3 108. 5.9
#> 2 1636-69… 99.6 86.5 0.17 0 0.28 0 17.5 20.1 115. 6.06
#> 3 1636-69… 99.8 97.0 0.06 0 0.17 0 14.1 15.2 108. 5.9
#> 4 1636-69… 98.1 89.8 0.91 0 1.02 0 22.0 24.0 109. 5.91
#> 5 1636-69… 100 96.6 0 0 0 0 14.3 14.7 103. 5.78
#> 6 1636-69… 100 94.3 0 0 0 0 14.9 16.8 113. 6.02
#> 7 1636-70… 97.1 89.8 1.46 0.22 1.41 0 19.7 22.3 113. 6.01
#> 8 1636-70… 97.1 85.8 2.64 0 0.27 0 19.7 22.5 114. 6.04
#> 9 2133-004 94.3 74.7 0.73 0 5.01 0 22.6 28.7 127. 6.34
#> 10 2133-015 97.8 94.3 1.2 0 0.98 0 17.4 18.9 109. 5.91
#> 11 2133-017 99.8 91.3 0.06 0 0.11 0 18.8 20.6 110. 5.93
#> 12 2133-018 88.3 80.4 0 0 11.7 1.86 31.1 39.4 127. 6.34
#> 13 2133-019 98.4 89.7 1.44 0.06 0.11 0 21.1 22.5 107. 5.86
#> 14 2133-021 91.3 70.7 0.61 0 8.07 0 24.7 32.1 130. 6.42
#> 15 2133-024 93.8 91.0 6.15 0.55 0 0 20.1 20.0 99.4 5.69
#> 16 2133-027 94.5 93.6 5.48 0 0 0 14.7 13.4 91.1 5.49
#> 17 2133-035 99.2 95.0 0.55 0.05 0.27 0 16.6 16.9 102. 5.74
#> 18 2133-036 93.5 82.6 5.07 0 1.43 0 24.7 26.6 108. 5.88
#> 19 2133-039 95.1 87.3 4.22 0.15 0.7 0 22.8 23.7 104. 5.8
#> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear_percent <dbl>,
#> # hypo_lv1_total_episodes <int>, hypo_lv2_total_episodes <int>,
#> # hypo_extended_total_episodes <int>, hypo_lv1_excl_total_episodes <int>,
#> # hyper_lv1_total_episodes <int>, hyper_lv2_total_episodes <int>,
#> # hyper_extended_total_episodes <int>, hyper_lv1_excl_total_episodes <int>
#>
#> $glycemic_event_summary
#> # A tibble: 152 × 6
#> id type level total_episodes avg_ep_per_day avg_minutes_below_54…¹
#> <chr> <chr> <chr> <int> <dbl> <dbl>
#> 1 1636-69-001 hypo lv1 3 0.47 0
#> 2 1636-69-001 hypo lv2 0 0 0
#> 3 1636-69-001 hypo exten… 0 0 0
#> 4 1636-69-001 hypo lv1_e… 3 0.47 0
#> 5 1636-69-001 hyper lv1 4 0.62 0
#> 6 1636-69-001 hyper lv2 0 0 0
#> 7 1636-69-001 hyper exten… 0 0 0
#> 8 1636-69-001 hyper lv1_e… 4 0.62 0
#> 9 1636-69-026 hypo lv1 0 0 0
#> 10 1636-69-026 hypo lv2 0 0 0
#> # ℹ 142 more rows
#> # ℹ abbreviated name: ¹avg_minutes_below_54_per_episodeWe compare performance using microbenchmark on both
datasets. Each benchmark contrasts
iglu::episode_calculation() with
cgmguru::detect_all_events().
library(microbenchmark)
library(iglu)
# example_data_5_subject
bench_5 <- microbenchmark(
episode_calculation = iglu::episode_calculation(example_data_5_subject),
detect_all_events = cgmguru::detect_all_events(example_data_5_subject),
times = 10,
unit = "ms"
)
print(bench_5)
#> Unit: milliseconds
#> expr min lq mean median uq
#> episode_calculation 289.443600 292.735490 298.193008 295.067980 297.059637
#> detect_all_events 2.922398 3.017805 3.084721 3.106119 3.162248
#> max neval cld
#> 330.980003 10 a
#> 3.166963 10 b
# example_data_hall (all subjects)
bench_hall <- microbenchmark(
episode_calculation = iglu::episode_calculation(example_data_hall),
detect_all_events = cgmguru::detect_all_events(example_data_hall),
times = 10,
unit = "ms"
)
print(bench_hall)
#> Unit: milliseconds
#> expr min lq mean median uq
#> episode_calculation 827.426330 831.417106 863.768660 849.863929 900.149629
#> detect_all_events 8.522957 8.650426 8.963736 8.834106 8.960755
#> max neval cld
#> 902.00562 10 a
#> 10.34889 10 b