aidR: Tandem Source export format

library(aidR)

Overview

A Tandem Source export is a folder (possibly zipped) containing CSV files for several data types. Filenames combine the participant, serial number, and export date with a data-type suffix, for example:

[1] "tandem_source_example/XXX_1111111_10Mar2026_1111-Basal-doses.csv"          
[2] "tandem_source_example/XXX_1111111_10Mar2026_1111-BG.csv"                   
[3] "tandem_source_example/XXX_1111111_10Mar2026_1111-Bolus.csv"                
[4] "tandem_source_example/XXX_1111111_10Mar2026_1111-CGM.csv"                  
[5] "tandem_source_example/XXX_1111111_10Mar2026_1111-Hourly-basal-delivery.csv"

Each file records the device type (e.g. Tandem Mobi™ System) and serial number on every row:

Device Type,Serial Number,Description,Event Date Time,Readings (mg/dL)
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:04:33,131
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:09:32,126
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:14:33,125
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:19:33,120
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:24:33,116
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:29:33,111
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:34:33,107
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:39:32,105
⁦Tandem Mobi™⁩ System,1111111,EGV,2026-03-05T00:44:32,104

How aidR detects this format

Because the headers in a Tandem Source export are language-specific, aidR cannot identify a file from its header names. It relies instead on the structure of the file, and distinguishes between data types by the expected number of columns, which columns are numeric, and, where available, a language-independent keyword such as "Tandem" or "t:slim X2" for the files containing CGM, SMBG and basal rates, as well as "Bolus" for the file containing the bolus data.

Files and the data types they produce

To inspect the raw files, we parse the export with clean = FALSE, which returns the full information provided by Tandem Source:

data <- parse_data(id = "1", paths = path, clean = FALSE)
#> Parsing data for id 1...

Each entry below describes one raw file and shows an example.

  • *-CGM.csv: CGM data.
head(data$cgm)
          Device Type Serial Number Description     Event Date Time
1 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:04:33
2 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:09:32
3 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:14:33
4 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:19:33
5 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:24:33
6 ⁦Tandem Mobi™⁩ System       1111111         EGV 2026-03-05 00:29:33
  Readings (mg/dL)
1              131
2              126
3              125
4              120
5              116
6              111
  • *-Basal-doses.csv: the basal insulin dose commanded at each event. Tandem reports doses rather than rates and gives no explicit duration, so aidR derives the duration of each entry from the gap to the following one and converts the dose into a rate in U/h.
head(data$basal)
          Device Type Serial Number     Event Date Time
1 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:04:04
2 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:09:03
3 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:14:04
4 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:19:04
5 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:24:04
6 ⁦Tandem Mobi™⁩ System       1111111 2026-03-05 00:29:05
  Commanded Basal Dose (units of insulin)
1                                   0.028
2                                   0.041
3                                   0.102
4                                   0.139
5                                   0.139
6                                   0.139
  • *-Bolus.csv: insulin boluses, including the bolus type and delivery method, the entered carbohydrate amount, the food and correction components, and the completion status.
head(data$bolus)
   Type        Bolus Type Bolus Delivery Method BG (mg/dL) Serial Number
1 Bolus Food / Correction              Standard        158       1111111
2 Bolus Food / Correction              Standard        159       1111111
3 Bolus Food / Correction              Standard        177       1111111
  Completion Date Time Insulin Delivered Food Delivered Correction Delivered
1  2026-03-05 04:51:44              2.48           1.89                 0.59
2  2026-03-05 08:02:13              2.96           1.78                 1.18
3  2026-03-05 12:24:41              1.81           1.67                 0.14
  Completion Status Desc Bolex Start Date Time Bolex Completion Date Time
1              Completed                    NA                         NA
2              Completed                    NA                         NA
3              Completed                    NA                         NA
  Bolex Insulin Delivered Bolex Completion Status Desc Standard Percent
1                      NA                           NA              100
2                      NA                           NA              100
3                      NA                           NA              100
  Duration (mins) Carb Size Target BG (mg/dL) Correction Factor Carb Ratio
1               0        17                 0                 0          0
2               0        16                 0                 0          0
3               0        15                 0                 0          0
  • *-BG.csv: self-monitored blood glucose (SMBG).
head(data$SMBG)
NULL
  • *-Hourly-basal-delivery.csv: basal insulin aggregated per hour, with one column per hour of the day (the hours are named either 12 AM … 11 PM or 00 … 23, depending on the export). This aggregated file is not used to build the cleaned basal, which is derived from *-Basal-doses.csv instead; it is used for total_basal.
head(data$hourly_basal)
  Serial Number Event Date 12 AM  1 AM 2 AM  3 AM  4 AM  5 AM  6 AM  7 AM  8 AM
1       1111111 2026-03-05 1.037 0.968 0.57 0.811 0.707 0.241 0.114 0.338 0.732
  9 AM 10 AM 11 AM 12 PM  1 PM  2 PM  3 PM  4 PM  5 PM  6 PM  7 PM  8 PM 9 PM
1 0.61 1.093 0.684 0.684 1.162 1.057 0.518 0.372 0.114 1.175 0.817 1.254 0.57
  10 PM 11 PM
1 0.457 0.376

Cleaning files

When parse_data is run with clean = TRUE, the cleaned data types are built from the following raw files and attributes:

Cleaned data type Used files Used attributes from clean = FALSE
cgm *-CGM.csv data$cgm
basal *-Basal-doses.csv data$basal
bolus *-Bolus.csv data$bolus
carbs *-Bolus.csv data$bolus
SMBG *-BG.csv data$bg
total_basal *-Hourly-basal-delivery.csv data$hourly_basal
total_bolus *-Bolus.csv data$bolus

Notes

  • CGM and SMBG values are reported in mg/dL or mmol/L depending on the account settings; aidR converts them to mg/dL automatically.
  • timezone_offset is always NA, since Tandem Source exports report only local (wall-clock) time.
  • The device type is stored as pump_name for insulin data and sensor_name for glucose data.
  • The hourly basal file reports the basal insulin delivered in each hour of the day, one row per day and one column per hour. aidR sums the 24 hourly columns into total_basal, which therefore carries source = "reported". total_bolus, in contrast, is summed from the cleaned bolus data and carries source = "summed".
  • Because basal durations are inferred from consecutive timestamps, the final basal entry of an export has no successor and its duration is therefore unknown.
  • Each row of the bolus file holds a bolus together with the carbohydrates entered for it, so bolus and carbs are linked by link_id. Boluses without carbohydrates have link_id = NA.