library(PhysioDevices)
#> Loading required package: PhysioCoreFitbit exports your data as an account archive (Settings → Export
Your Account Archive) or as the Fitbit slice of Google
Takeout — a directory of per-day JSON (and some CSV) files.
Google Pixel Watch stores its health data in Fitbit, so
the same reader covers Pixel Watch. The analysis then reuses the same
PhysioWearable / PhysioECG functions as the
Apple Watch workflow.
1. Ingest the archive
fb <- readFitbit("Takeout/Fitbit", tz = "Asia/Tokyo")
fb # which modalities were found, with row counts and spansreadFitbit() discovers files by name
(heart_rate-*, steps-*, sleep-*,
resting_heart_rate-*, SpO2), parses the nested JSON, and
skips anything it cannot read (with a warning). Restrict with
what = if you only need some modalities.
2. Heart rate
hr <- fitbitSeries(fb, "heart_rate") # columns: time, bpm (intraday)
summary(hr$bpm)
fb$resting_heart_rate # daily resting HRFor HRV, Fitbit exports its own daily RMSSD (a
Heart Rate Variability file); for beat-to-beat HRV use a
Fitbit Sense/Charge ECG recording with PhysioECG.
4. Sleep
Fitbit scores sleep stages itself
(wake/light/deep/rem).
summarizeSleepStages() turns them into per-night clinical
metrics — the same engine used for Apple Watch, just with Fitbit’s stage
labels:
5. Activity
steps <- fitbitSeries(fb, "steps")
tapply(steps$value, as.Date(steps$time), sum) # steps per dayFor epoch-level free-living metrics (ENMO, intensity, fragmentation, HAR → ICF) you need raw accelerometry, which Fitbit does not export — only derived activity.
Google Fit and Health Connect
Phone-level Google data has two other paths, both reusing the same analysis:
# Google Takeout "Fit": granular heart-rate/step JSON + daily-summary CSVs
gf <- readGoogleFit("Takeout/Fit", tz = "Asia/Tokyo")
gf$heart_rate
gf$daily
# Android Health Connect: a per-record-type CSV export
hc <- readHealthConnect("health_connect_export", tz = "Asia/Tokyo")
PhysioWearable::spo2Metrics(hc$spo2$value, time = hc$spo2$time)
PhysioWearable::summarizeSleepStages(
hc$sleep, asleep_levels = c("light", "deep", "rem"), wake_levels = "awake",
stage_cols = c(deep = "deep", rem = "rem"))Scope and limitations
- Covers the Fitbit account archive / Google Takeout JSON layout; exact filenames vary slightly by export version (the reader keys off filename patterns and skips what it cannot parse).
- The Fitbit Web API (OAuth2, live JSON) is a separate path not covered here.
-
Google Pixel Watch = Fitbit data
(
readFitbit()). -
Google Fit (
readGoogleFit(), Takeout) is being retired by Google in favour of Health Connect (readHealthConnect(), per-type CSV export). Health Connect has no single official export file, so column names vary by exporter; the reader detects them heuristically. - No raw acceleration and no continuous SpO2 (spot readings) — same limits as the Apple Watch workflow.