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)
#> $events_long_df
#> # A tibble: 40 × 6
#> id type level event_count avg_ep_per_day avg_episode_duration_be…¹
#> <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_episode_duration_below_54
#>
#> $summary_df
#> # 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… 91.8 74.0 0.156 0 8.08 0.375 0.267 33.0 123. 6.26
#> 2 Subject… 25.8 3.28 0 0 74.2 26.5 0.241 52.7 219. 8.54
#> 3 Subject… 81.3 49.8 0.316 0 18.4 5.44 0.290 44.5 154. 6.98
#> 4 Subject… 94.9 67.4 0.326 0.0271 4.75 0 0.224 29.0 130. 6.41
#> 5 Subject… 62.0 29.6 0.102 0 37.9 11.5 0.335 58.4 175. 7.49
#> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear <dbl>,
#> # hypo_lv1_event_count <int>, hypo_lv2_event_count <int>,
#> # hypo_extended_event_count <int>, hypo_lv1_excl_event_count <int>,
#> # hyper_lv1_event_count <int>, hyper_lv2_event_count <int>,
#> # hyper_extended_event_count <int>, hyper_lv1_excl_event_count <int>all_events_hall <- detect_all_events(example_data_hall)
print(all_events_hall)
#> $events_long_df
#> # A tibble: 152 × 6
#> id type level event_count avg_ep_per_day avg_episode_duration_…¹
#> <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 extended 0 0 0
#> 4 1636-69-001 hypo lv1_excl 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 extended 0 0 0
#> 8 1636-69-001 hyper lv1_excl 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_episode_duration_below_54
#>
#> $summary_df
#> # 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-6… 96.8 87.4 0.703 0 2.54 0 0.252 27.2 108. 5.90
#> 2 1636-6… 99.6 86.4 0.110 0 0.329 0 0.173 19.9 115. 6.06
#> 3 1636-6… 99.7 96.9 0.112 0 0.168 0 0.140 15.1 108. 5.90
#> 4 1636-6… 97.8 89.4 0.901 0 1.27 0 0.222 24.3 109. 5.92
#> 5 1636-6… 100 96.6 0 0 0 0 0.141 14.6 103. 5.78
#> 6 1636-6… 100 94.4 0 0 0 0 0.148 16.7 113. 6.02
#> 7 1636-7… 97.2 89.4 1.50 0.214 1.34 0 0.196 22.1 113. 6.01
#> 8 1636-7… 96.9 85.3 2.82 0 0.325 0 0.197 22.5 114. 6.03
#> 9 2133-0… 94.0 73.8 0.898 0 5.11 0 0.226 28.6 127. 6.34
#> 10 2133-0… 97.7 94.0 1.17 0 1.17 0 0.176 19.2 109. 5.92
#> 11 2133-0… 99.8 91.3 0 0 0.164 0 0.187 20.4 110. 5.93
#> 12 2133-0… 88.3 80.2 0 0 11.7 1.85 0.311 39.3 127. 6.34
#> 13 2133-0… 98.5 89.5 1.42 0.0548 0.110 0 0.210 22.4 107. 5.86
#> 14 2133-0… 91.1 70.5 0.665 0 8.26 0 0.247 32.1 130. 6.42
#> 15 2133-0… 93.3 90.5 6.68 0.657 0 0 0.202 20.0 99.3 5.69
#> 16 2133-0… 94.6 93.7 5.42 0 0 0 0.146 13.3 91.1 5.49
#> 17 2133-0… 99.3 95.0 0.421 0.0527 0.316 0 0.165 16.8 102. 5.74
#> 18 2133-0… 92.9 81.0 5.70 0 1.39 0 0.249 26.8 108. 5.89
#> 19 2133-0… 94.7 86.9 4.56 0.138 0.738 0 0.229 23.9 104. 5.81
#> # ℹ 11 more variables: uGMI <dbl>, GRI <dbl>, sensor_wear <dbl>,
#> # hypo_lv1_event_count <int>, hypo_lv2_event_count <int>,
#> # hypo_extended_event_count <int>, hypo_lv1_excl_event_count <int>,
#> # hyper_lv1_event_count <int>, hyper_lv2_event_count <int>,
#> # hyper_extended_event_count <int>, hyper_lv1_excl_event_count <int>We 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 288.468743 294.080659 299.54513 296.002329 299.337023
#> detect_all_events 3.086931 3.112187 3.25153 3.228586 3.386518
#> max neval cld
#> 333.061901 10 a
#> 3.497997 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 811.18824 843.066190 861.301133 863.023698 882.685638
#> detect_all_events 8.85887 8.902699 9.163725 8.966065 9.091832
#> max neval cld
#> 891.88222 10 a
#> 10.53282 10 b