class: left, bottom, title-slide .title[ # 2. Fitbit ] .subtitle[ ## Analytics Sandbox ] .author[ ### K. Bret Staudt Willet | Florida State University ] .date[ ### January 18, 2023 ] --- class: inverse, center, middle #
<br><br> **Part 2:** <br> Fitbit --- class: inverse, center, middle #
<br><br> Setup <br> with Fitbit API ### Step 1: Register a Fitbit developer app This health assessment utilizes the {fitbitr} R package ([Kaye, 2021](https://mrkaye97.github.io/fitbitr/)). The functions in the package are relatively straightforward, but getting access to the [Fitbit API](https://dev.fitbit.com/build/reference/web-api/) set up is a bit tricky. --- class: inverse, center, middle #
<br><br> Setup <br> with Fitbit API ### Step 1: Register a Fitbit developer app The first thing to do is register a new Fitbit developer app at [dev.fitbit.com](https://dev.fitbit.com/apps/new). --- #
Setup with Fitbit API ### Step 1: Register a Fitbit developer app Here's how I completed the form: <hr> - **Application Name:** `r-health-tracker` - **Description:** `fitbitr script` - **Application Website URL:** `https://github.com/bretsw/fitbit` (replace with your GitHub repo) - **Organization:** `bretsw` (replace with your GitHub user name) - **Organization Website URL:** `https://github.com/bretsw/fitbit` (replace with your GitHub repo) - **Terms of Service URL:** `https://github.com/bretsw/fitbit` (replace with your GitHub repo) - **Privacy Policy URL:** `https://github.com/bretsw/fitbit` (replace with your GitHub repo) - **OAuth 2.0 Application Type:** `Personal` - **Redirct URL:** `http://localhost:1410/` - **Default Access Type:** `Read Only` --- #
Setup with Fitbit API ### Step 1: Register a Fitbit developer app I got a warning from the dev website that the redirect URL needs to be an `https`, but it needs to be in the exact format I have above, because this is how R is set up to take you back to your R console. If you have to, complete the initial form with `https://localhost:1410/` initially, then go back and edit it before you run your R script. Once you submit your Fitbit dev app, you will be taken to a webpage that lists your **OAuth 2.0 Client ID** and **Client Secret**. --- class: inverse, center, middle #
<br><br> Setup <br> with Fitbit API ### Step 2: Record your dev app credentials --- #
Setup with Fitbit API ### Step 2: Record your dev app credentials Be sure to make a copy of your Fitbit dev app **OAuth 2.0 Client ID** and **Client Secret**. I find it easiest to securely store these in my local R user environment. You can open this file with the command `usethis::edit_r_environ()` and then retrieve stored variables with `Sys.getenv()`. In my R script below, note that you should save your credentials in the form `FITBIT_CLIENT_ID = XXXXXX` and `FITBIT_CLIENT_SECRET = XXXXXX`. Once you have your credentials stored, close the .Renviron file and quit out of R entirely. When you restart R, your credentials are ready to go. You can check if things are stored correctly by running: `Sys.getenv('FITBIT_CLIENT_ID')` and `Sys.getenv('FITBIT_CLIENT_SECRET')`. Just be sure that you don't share these credentials with anyone! --- class: inverse, center, middle #
<br><br> Setup <br> with Fitbit API ### Step 3: Retrieve your Fitbit data --- #
Setup with Fitbit API ### Step 3: Retrieve your Fitbit data ```r generate_token(client_id = Sys.getenv('FITBIT_CLIENT_ID'), client_secret = Sys.getenv('FITBIT_CLIENT_SECRET') ) ``` --- class: inverse, center, middle #
<br><br> Try it Out! --- #
Try it Out! What do you think this code will do? ```r start_date <- lubridate::today() - lubridate::years(2) end_date <- lubridate::today() steps_df <- steps(start_date, end_date) write_csv(steps_df, "data/fitbit-steps.csv") ``` --- #
Try it Out! ### Look at your daily steps ```r glimpse(steps_df) ``` ``` ## Rows: 731 ## Columns: 2 ## $ date <date> 2021-01-18, 2021-01-19, 2021-01-20, 2021-01-21, 2021-01-22, 202… ## $ steps <dbl> 12838, 10826, 11052, 12304, 9067, 5008, 5936, 8994, 9242, 11000,… ``` --- #
Picture it! ```r ggplot(steps_df, aes(x=date, y=steps)) + geom_point() + geom_smooth() + geom_vline(aes(xintercept = as.Date("2020-03-11")), color = 'green') + xlab(NULL) + ylab("Steps per Day") + ggtitle("Number of Daily Steps") + theme_bw() ``` <img src="2-fitbit_files/figure-html/unnamed-chunk-5-1.png" width="33%" style="display: block; margin: auto;" /> --- #
Compare! <img src="output/2-daily-steps-old.png" width="49%" style="display: block; margin: auto;" /> <img src="output/2-daily-steps.png" width="49%" style="display: block; margin: auto;" /> --- #
Try it Out! What do you think this code will do? ```r hr <- heart_rate_intraday(lubridate::today() - 1) write_csv(hr, "data/fitbit-hr.csv") ``` --- #
Try it Out! ### Look at yesterday's heart rate ```r glimpse(hr) ``` ``` ## Rows: 1,045 ## Columns: 2 ## $ time <dttm> 2023-01-17 00:00:00, 2023-01-17 00:01:00, 2023-01-17 00:02… ## $ heart_rate <dbl> 76, 68, 73, 80, 74, 79, 72, 87, 81, 69, 75, 84, 63, 64, 66,… ``` --- #
Picture it! ```r ggplot(hr, aes(x=time, y=heart_rate)) + geom_point() + geom_smooth() + xlab(NULL) + ylab("Beats per Minute") + ggtitle("Yesterday's Heart Rate") + theme_bw() ``` <img src="2-fitbit_files/figure-html/unnamed-chunk-12-1.png" width="33%" style="display: block; margin: auto;" /> --- #
Compare! <img src="output/2-heart-rate-yesterday-old.png" width="49%" style="display: block; margin: auto;" /> <img src="output/2-heart-rate-yesterday.png" width="49%" style="display: block; margin: auto;" /> --- #
Try it Out! What do you think this code will do? ```r yesterday_df <- activity_summary(lubridate::today() - 1) write_csv(yesterday_df, "data/fitbit-yesterday-df.csv") ``` --- #
Try it Out! ```r glimpse(yesterday_df) ``` ``` ## Rows: 1 ## Columns: 14 ## $ date <date> 2023-01-17 ## $ active_score <dbl> -1 ## $ activity_calories <dbl> 853 ## $ calories_bmr <dbl> 1852 ## $ calories_out <dbl> 2625 ## $ elevation <dbl> 0 ## $ fairly_active_minutes <dbl> 0 ## $ floors <dbl> 0 ## $ lightly_active_minutes <dbl> 188 ## $ marginal_calories <dbl> 443 ## $ resting_heart_rate <dbl> 58 ## $ sedentary_minutes <dbl> 1252 ## $ steps <dbl> 5099 ## $ very_active_minutes <dbl> 0 ``` --- #
Try it Out! What do you think this code will do? ```r health_df = NULL for (i in 0:60) { new_row = tibble(date = lubridate::today() - i, resting_hr = activity_summary(date)$resting_heart_rate, steps = activity_summary(date)$steps ) health_df <- health_df %>% bind_rows(new_row) } write_csv(health_df, "data/fitbit-health-df.csv") ``` --- #
Try it Out! ### Look at yesterday's heart rate ```r glimpse(health_df) ``` ``` ## Rows: 61 ## Columns: 3 ## $ date <date> 2023-01-18, 2023-01-17, 2023-01-16, 2023-01-15, 2023-01-14… ## $ steps <dbl> 105, 5099, 7161, 5281, 7645, 5875, 6366, 6336, 6099, 8664, … ## $ resting_hr <dbl> NA, 58, 57, 57, 57, 58, 58, 58, NA, 57, 57, 58, 58, 58, 60,… ``` --- #
Try it Out! This block of code looks at my resting heart rate across the past 2 months (60 days). Note that a Fitbit dev app's rate limit is 150 API requests per hour for each user who has consented to share their data; and it resets at the top of each hour. This means that you are limited to retrieving the `activity_summary()` data for 150 days at a time. You could store this data, wait an hour, and the retrieve the next 150 days if you wanted to. --- #
Picture it! ```r ggplot(health_df, aes(x=date, y=resting_hr)) + geom_point() + geom_smooth() + xlab(NULL) + ylab("Beats per Minute while Resting") + ggtitle("Resting Heart Rate") + theme_bw() ``` <img src="2-fitbit_files/figure-html/unnamed-chunk-22-1.png" width="33%" style="display: block; margin: auto;" /> --- #
Compare! <img src="output/2-resting-heart-rate-old.png" width="49%" style="display: block; margin: auto;" /> <img src="output/2-resting-heart-rate.png" width="49%" style="display: block; margin: auto;" /> --- #
Try it Out! What do you think this code will do? ```r ggplot(health_df, aes(x=steps, y=resting_hr)) + geom_point() + geom_smooth() + xlab("Daily Steps") + ylab("Beats per Minute while Resting") + ggtitle("Resting Heart Rate vs. Daily Steps") + theme_bw() ``` --- #
Picture it! ```r ggplot(health_df, aes(x=steps, y=resting_hr)) + geom_point() + geom_smooth() + xlab("Daily Steps") + ylab("Beats per Minute while Resting") + ggtitle("Resting Heart Rate vs. Daily Steps") + theme_bw() ``` <img src="2-fitbit_files/figure-html/unnamed-chunk-27-1.png" width="33%" style="display: block; margin: auto;" /> --- #
Picture it! ```r ggplot(health_df, aes(x=steps, y=resting_hr)) + geom_jitter(alpha=0.6) + geom_smooth(method='lm') + xlab("Daily Steps") + ylab("Beats per Minute while Resting") + ggtitle("Resting Heart Rate vs. Daily Steps") + theme_bw() ``` <img src="2-fitbit_files/figure-html/unnamed-chunk-29-1.png" width="33%" style="display: block; margin: auto;" /> --- #
Compare! <img src="output/2-resting-heart-rate-vs-daily-steps-a.png" width="49%" style="display: block; margin: auto;" /> <img src="output/2-resting-heart-rate-vs-daily-steps-b.png" width="49%" style="display: block; margin: auto;" /> --- class: inverse, center, middle #
<br><br> Try it out! --- #
Try it out! - Download a copy of this repository. - If you have a Fitbit, see if you can retrieve and analyze your own data. - Regardless, use the saved data in the "data" folder to play around a bit more, changing different parameters. - Reflect: - What other comparisons might you make? - How else might you analyze these Fitbit data? --- class: inverse, center, middle #
<br><br> Appendix: <br> Helpful Resources <br> and Troubleshooting --- # Resources **Beginners:** - [RStudio Beginners' Guide](https://education.rstudio.com/learn/beginner/) - Book: [*Data Science in Education Using R*](https://datascienceineducation.com) - See [Chapter 12](https://datascienceineducation.com/c12.html) - Walkthrough 6: Exploring Relationships Using Social Network Analysis With Social Media Data - [Physical copy of DSIEUR](https://www.routledge.com/Data-Science-in-Education-Using-R/Estrellado-Freer-Mostipak-Rosenberg-Velasquez/p/book/9780367422257) - [Even more resources from DSIEUR](https://datascienceineducation.com/c18.html) **Intermediates:** - [RStudio Intermediates' Guide](https://education.rstudio.com/learn/intermediate/) - [{tidytags} package notes](https://docs.ropensci.org/tidytags/index.html) - Book: [*R for Data Science*](http://r4ds.had.co.nz/) **Experts:** - [RStudio Experts' Guide](https://education.rstudio.com/learn/expert/) - Book: [*Learning Statistics with R*](https://learningstatisticswithr.com/) - [*Data Science in Education Using R*](https://datascienceineducation.com) - See [Chapter 20.3 Appendix C](https://datascienceineducation.com/c20.html#c20c) - Social Network Influence and Selection Models - SNA resources: [Dr. Ken Frank's website](https://sites.google.com/msu.edu/kenfrank/social-network-resources) --- # Troubleshooting - Try to find out what the specific problem is - Identify what is *not* causing the problem - "Unplug and plug it back in" - restart R; close and reopen R - Seek out workshops and other learning opportunities - Reach out to others! Sharing what is causing an issue can often help to clarify the problem - [RStudio Community forum](https://community.rstudio.com/) (highly recommended!) - Twitter hashtag: [#RStats](https://twitter.com/search?q=%23RStats&src=typeahead_click&f=live) - [Contact Bret!](https://bretsw.com) - General strategies on learning more: [Chapter 17 of *Data Science in Education Using R*](https://datascienceineducation.com/c17.html)