Introduction
In part 1 of this series, I will demonstrate how to interact with the Fitbit API in R.
Huge credit to Matt Kaye for creating the fitbitr package that provides an interface between R and the Fitbit API. If you are familiar with R and you have a Fitbit, you should have success following what I have laid out below.
Install the fitbitr
package
From CRAN:
install.packages("fitbitr")
Or the development version from github:
devtools::install_github("mrkaye97/fitbitr")
Register for a Fitbit API Key
While this information is also provided on the repo’s Github page, I provide similar instructions here for ease of access.
You’ll need to request an API key from the Fitbit developers webpage. At this page, you should find a form similar to this.
Fill out the form as accurately as possible, but I recommend the following 3 inputs I specify in the red box.
If you want to copy and paste the Redirect URL, here you go: http://localhost:1410/
After you agree to Fitbit’s terms, you receive your client ID and API key. I censored mine, but you can see below where yours will be located.
Now, the fun part…
Access Your Fitbit Data
Authenticate Your Session
I’ve saved both my Client ID and Client Secret in my .Revniron
file in the root of my repo. I saved them as FITBIT_KEY
and FITBIT_SECRET
respectively. Access them using the Sys.getenv()
function.
To find out more information about how to do this, look here.
You’ll need to generate a token using the function below.
library(tidyverse)
library(fitbitr)
generate_token(
client_id = Sys.getenv("FITBIT_KEY"),
client_secret = Sys.getenv("FITBIT_SECRET"),
callback = "http://localhost:1410/",
cache = TRUE
)
When you execute this function, you should get a window that looks like this.
As long as you set the cache
argument to TRUE
, you will have a token saved in a file named .httr-oauth
in the root of your repo. For future authentications, you can simply use the function below. Should you want to create a new token every time, you can leave the cashe
argument equal to FALSE
.
load_cached_token(path = ".httr-oauth")
Download Data
There are several functions for accessing all your data tracked on Fitbit. For the purposes of this post, I’ll highlight a few. I will do deeper analysis in subsequent posts.
Lifetime Performance: Personal Bests
lifetime_bests()
## # A tibble: 3 x 3
## metric date value
## <chr> <chr> <dbl>
## 1 distance 2014-03-23 38.7
## 2 floors 2021-03-21 136.
## 3 steps 2014-03-23 47985
I’ve had two Fitbits. One I wore for part of 2014 and one I’ve worn since the beginning of 2021.
It appears I ran a marathon on 23 March 2021. (Checks Old Facebook Photos) Yep, The Bataan Death March in White Sands Missile Range, NM. And I apparently went on quite a hilly hike with my wife and kids in March of 2021. March is clearly an active month for me….
Lifetime Performance: Totals
lifetime_totals()
## # A tibble: 1 x 3
## distance floors steps
## <dbl> <int> <int>
## 1 4472. 12627 6233067
12K floors. Makes me feel tired just thinking about it. :)
Daily Performance: Elevation, Distance, Steps, Floors
To save some space, I display the following four daily performance outputs in one dataframe.
start_date <- lubridate::ymd("20220501")
end_date <- lubridate::ymd("20220507")
elevation <- elevation(start_date = start_date, end_date = end_date)
distance <- distance(start_date = start_date, end_date = end_date)
steps <- steps(start_date = start_date, end_date = end_date)
floors <- floors(start_date = start_date, end_date = end_date)
reduce(.x = list(distance, steps, floors), .f = left_join, by = "date", .init = elevation)
## # A tibble: 7 x 5
## date elevation distance steps floors
## <date> <dbl> <dbl> <dbl> <dbl>
## 1 2022-05-01 27 3.77 5506 9
## 2 2022-05-02 121 14.4 18182 40
## 3 2022-05-03 131 10.0 11761 43
## 4 2022-05-04 42 10.3 15103 14
## 5 2022-05-05 121 11.2 13537 40
## 6 2022-05-06 124 11.3 16501 41
## 7 2022-05-07 51 8.60 12578 17
Special Note About Request Dates
Thought the fitbitr
library will not stop you, the Fitbit API will only allow you to request up to 100 days of data at at time. You can read more about it in the documentation.
Sleep Details
There are three different functions for displaying sleep data. I display one for simplicity.
# sleep_stage_granular(start_date = start_date,end_date = end_date) ## not shown
# sleep_summary(start_date = start_date, end_date = end_date) ## not shown
sleep_stage_summary(start_date = start_date, end_date = end_date)
## # A tibble: 28 x 5
## date stage count minutes thirty_day_avg_minutes
## <chr> <chr> <int> <int> <int>
## 1 2022-05-07 deep 4 68 70
## 2 2022-05-07 light 27 282 276
## 3 2022-05-07 rem 16 125 79
## 4 2022-05-07 wake 29 49 43
## 5 2022-05-06 deep 3 57 73
## 6 2022-05-06 light 30 282 274
## 7 2022-05-06 rem 5 71 80
## 8 2022-05-06 wake 28 44 43
## 9 2022-05-05 deep 6 88 69
## 10 2022-05-05 light 31 223 287
## # ... with 18 more rows
Maybe I should sleep more….
Heart Rate By Minute
heart_rate_intraday(date = start_date, minutes = TRUE) ## FALSE = By Second
## # A tibble: 1,316 x 2
## time heart_rate
## <dttm> <int>
## 1 2022-05-01 00:00:00 83
## 2 2022-05-01 00:01:00 79
## 3 2022-05-01 00:02:00 84
## 4 2022-05-01 00:03:00 79
## 5 2022-05-01 00:04:00 70
## 6 2022-05-01 00:05:00 72
## 7 2022-05-01 00:06:00 75
## 8 2022-05-01 00:07:00 77
## 9 2022-05-01 00:08:00 69
## 10 2022-05-01 00:09:00 74
## # ... with 1,306 more rows
Heart Rate Zones
heart_rate_zones(start_date = start_date, end_date = end_date)
## # A tibble: 28 x 6
## date zone min_hr max_hr minutes_in_zone calories_out
## <date> <chr> <int> <int> <int> <dbl>
## 1 2022-05-01 Out of Range 30 109 1438 2119.
## 2 2022-05-01 Fat Burn 109 133 2 12.2
## 3 2022-05-01 Cardio 133 164 0 0
## 4 2022-05-01 Peak 164 220 0 0
## 5 2022-05-02 Out of Range 30 108 1375 2699.
## 6 2022-05-02 Fat Burn 108 133 35 215.
## 7 2022-05-02 Cardio 133 164 13 152.
## 8 2022-05-02 Peak 164 220 17 209.
## 9 2022-05-03 Out of Range 30 108 1382 2302.
## 10 2022-05-03 Fat Burn 108 133 32 184.
## # ... with 18 more rows
Activity
active_fairly <- minutes_fairly_active(start_date = start_date,end_date = end_date)
active_lighty <- minutes_lightly_active(start_date = start_date,end_date = end_date)
active_sedentary <- minutes_sedentary(start_date = start_date,end_date = end_date)
reduce(.x = list(active_lighty, active_sedentary), .f = left_join, by = "date", .init = active_fairly)
## # A tibble: 7 x 4
## date minutes_fairly_active minutes_lightly_active minutes_sedentary
## <date> <dbl> <dbl> <dbl>
## 1 2022-05-01 0 236 645
## 2 2022-05-02 27 350 515
## 3 2022-05-03 31 232 722
## 4 2022-05-04 21 470 498
## 5 2022-05-05 15 312 606
## 6 2022-05-06 23 453 482
## 7 2022-05-07 12 289 539
In future posts, I’ll do some visualizations and statistical analysis of this data!