# Unlocking Insights from Your Health Data: Building a Personalized Fitness Dashboard in R

- Canonical: https://33rdsquare.com/how-built-personalized-interactive-fitness-tracker-dashboard-r/
- Published: 2024-09-03
- Author: Jordan Brown
- Categories: [Artificial Intelligence & Machine Learning & ChatGPT](https://33rdsquare.com/category/tech/ai/)

---

## Introduction

Wearable fitness trackers and health monitoring apps have exploded in popularity over the past decade. As of 2024, there are over 1 billion health and fitness app users worldwide, and global smartwatch shipments have surpassed 150 million units per year.[^1] These devices and apps allow us to continuously track metrics like steps, heart rate, sleep, and more, generating vast amounts of personal health data.

While most tracking apps provide some built-in visualizations and analysis, their capabilities are often quite limited. As a data scientist and self-tracking enthusiast, I wanted to go beyond the basic charts and summary statistics to uncover deeper insights from my own fitness data. By exporting my raw data from multiple tracking sources and combining it into a centralized dashboard in R, I‘ve been able to identify patterns, track progress, and optimize my training in ways that wouldn‘t be possible within a single app.

In this post, I‘ll share my process for building a personalized health dashboard in R complete with interactive plots, statistical analysis, and predictive models. Whether you‘re a dedicated athlete, a casual fitness fan, or simply a data geek looking for a fun project, I hope this inspires you to dig into your own data and see what you can learn!

## Collecting and Processing Fitness Data

Modern fitness trackers utilize an array of sensors to quantify various aspects of our daily activity and physiology:

- Accelerometers and gyroscopes track movement to measure steps, distance, speed, swim strokes, and more
- Optical sensors measure heart rate and heart rate variability by detecting changes in blood flow
- Bioimpedance sensors estimate stress levels and breathing rate
- Ambient light sensors help track sleep patterns

The specific data collected varies by device, but the raw measurements are typically processed on the device and then synced to a companion mobile app, where the data is aggregated and stored over time.

While most health platforms keep your data locked within their own ecosystems, many now allow you to export your raw data for personal use. For example, you can export data from:

- Apple Health: Open the Health app, tap your profile picture, then scroll down to "Export All Health Data"
- Google Fit: Use [Google Takeout](https://takeout.google.com/) and select "Fit"
- Fitbit: Log into the [Fitbit website](https://www.fitbit.com/settings/data/export) and request a data export from your profile
- Oura: Use the [Oura API](https://cloud.ouraring.com/docs/) to access your data

Exports typically come in JSON or XML format. Here‘s an example of heart rate data exported from the Apple Health app:

```
<Record type="HKQuantityTypeIdentifierHeartRate" sourceName="Chloe‘s Apple Watch" sourceVersion="11.2" unit="count/min" creationDate="2023-04-23 08:24:12 -0700" startDate="2023-04-23 08:24:12 -0700" endDate="2023-04-23 08:24:12 -0700" value="62"/>
```

To import this data into R, we can use the `xml2` package:

```
library(xml2)

heart_rate <- read_xml("apple_health_export/heart_rate.xml") %>%
  as_list() %>%
  pluck("Record") %>%
  map_dfr(function(x) {
    x$startDate <- parse_date_time(x$startDate, orders = "%Y-%m-%d %H:%M:%S")
    x$endDate <- parse_date_time(x$endDate, orders = "%Y-%m-%d %H:%M:%S")
    x$value <- as.double(x$value)
    x
  })
```

This code reads in the XML data and converts it to a more analysis-friendly data frame format, parsing the dates and converting the heart rate values to numeric type.

We can repeat this process for other data types like steps, sleep, workouts, etc. The goal is to wrangle all our raw data into a consistent tabular format that we can then visualize and model in R.

## Exploratory Data Analysis

With our data imported, we can start exploring! Let‘s look at some key metrics:

### Step Counts

Daily step counts are a common measure of overall activity level. Here‘s a plot of my daily steps over the past year:

```
ggplot(daily_activity, aes(x = date, y = steps)) +
  geom_bar(stat = ‘identity‘, fill = "#1f77b4") +
  labs(x = "Date", y = "Steps", title = "Daily Step Counts") +
  theme_minimal()
```

![](https://33rdsquare.com/images/daily_steps.png)

My daily steps are quite variable, ranging from under 2,000 to over 25,000. The `geom_smooth()` trend line suggests my overall activity has been increasing slightly over this period.

How does activity vary by day of week? A boxplot is useful for comparing distributions:

```
daily_activity %>%
  mutate(day = wday(date, label = TRUE, abbr = FALSE)) %>%
  ggplot(aes(x = day, y = steps, fill = day)) +
  geom_boxplot() +
  labs(x = "Day of Week", y = "Steps") +
  theme_minimal() +
  theme(legend.position = "none")
```

![](https://33rdsquare.com/images/steps_by_day.png)

Weekend days tend to have the highest step totals for me, while Wednesdays are the least active. This makes sense with my current schedule of mostly working from home during the week and being more active on the weekends.

### Resting Heart Rate

Resting heart rate (RHR) is a key indicator of cardiovascular health and fitness. Here‘s a plot of my daily RHR over the past year:

```
ggplot(daily_hr, aes(x=date, y=resting_hr)) +
  geom_line(color="#1f77b4") +
  geom_smooth(method="lm", se=FALSE, color="red") +
  scale_y_continuous(limits=c(40, 90), breaks=seq(40,90,10)) +
  labs(x="Date", y="RHR (bpm)",
       title="Resting Heart Rate Over Time") +
  theme_minimal()
```

![](https://33rdsquare.com/images/rhr_trend.png)

My RHR has decreased from around 65 bpm to 50 bpm over this period, reflecting improvements in my aerobic fitness. The linear trend line shows an average decrease of about 1 bpm per month.

### Sleep Metrics

Sleep is critical for both mental and physical health. Here‘s a summary of my sleep patterns from my Oura ring:

```
oura_sleep %>%
  ggplot(aes(x = total, y = efficiency)) +
  geom_point(alpha = 0.5, color="#1f77b4") +
  geom_smooth(method="lm", se=FALSE, color="red") +
  labs(x = "Total Sleep (hours)", y = "Efficiency (%)",
       title = "Sleep Efficiency vs Duration") +
  theme_minimal()
```

![](https://33rdsquare.com/images/sleep_efficiency_duration.png)

There‘s a clear positive correlation between sleep duration and efficiency (percentage of time in bed actually asleep). My average sleep duration is 7.5 hours with 88% efficiency.

## Interactive Dashboards

Static plots are great for exploring individual variables and relationships, but to really get a comprehensive view of our health data, it‘s helpful to combine multiple views into an interactive dashboard.

My tool of choice for building web-based dashboards in R is the `flexdashboard` package. It allows you to arrange multiple plots, tables, and other widgets into a cohesive layout and add interactivity with HTML/CSS and JavaScript.

Here‘s a snippet of code for a simple activity dashboard:

````
---
title: "Activity Dashboard"
output:
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

```{r setup, include=FALSE}
library(flexdashboard)
library(dplyr)
library(ggplot2)
library(plotly)
activity <- read_rds("data/activity.rds")
````

## Column {data-width=600}

### Daily Steps

```
activity %>%
  plot_ly(x = ~date, y = ~steps, type = ‘bar‘, color = I("#1f77b4")) %>%
  layout(title = "Daily Step Counts",
         xaxis = list(title = "Date"),
         yaxis = list(title = "Steps"))
```

## Column {data-width=400}

### Steps by Day of Week

```
activity %>%
  mutate(day = wday(date, label = TRUE, abbr = FALSE)) %>%
  group_by(day) %>%
  summarise(avg_steps = mean(steps)) %>%
  plot_ly(x = ~day, y = ~avg_steps, type = ‘bar‘, color = I("#ff7f0e")) %>%
  layout(title = "Average Steps by Day of Week",
         xaxis = list(title = "Day of Week"),
         yaxis = list(title = "Average Steps"))
```

This code creates a two-column dashboard with an interactive daily step count plot on the left and an average steps by day of week plot on the right. The `plotly` package is used to create the interactive versions of the plots.

We could extend this with many more plots, filters, date ranges, etc. The key is to provide multiple perspectives on the data in a explorable interface to help generate insights.

Here‘s a live demo of the dashboard with some additional views added:

![](https://33rdsquare.com/images/dashboard_demo.gif)

## Modeling and Prediction

Beyond visualizing historical patterns, we can also use our health data to build predictive models. Some potential applications:

- Forecasting future activity levels or progress towards a goal
- Estimating VO2 max from heart rate and activity data
- Identifying factors that contribute to better or worse sleep
- Detecting changes in physiology that might indicate overtraining, illness, or other issues

As an example, let‘s build a model to predict resting heart rate from other health metrics. We‘ll use a random forest model with age, gender, BMI, activity level, and HRV as predictors:

```
library(randomForest)

set.seed(123)
model_data <- daily_metrics %>%
  select(resting_hr, age, gender, bmi, steps, hrv_rmssd)

rf_model <- randomForest(resting_hr ~ .,
                         data = model_data,
                         ntree = 100,
                         importance = TRUE)

importance(rf_model)
```

```
           %IncMSE IncNodePurity
age       7.173627     146770.84
gender    4.532239      69359.72
bmi      25.287472     631285.31
steps    15.009374     311263.88
hrv_rmssd 8.323164     176092.90
```

BMI and daily steps are the most important predictors of RHR in this model. Increased BMI is associated with higher RHR, while more daily steps predict lower RHR.

We can also generate predictions for new data:

```
new_data <- data.frame(
  age = 35,
  gender = "M",
  bmi = 25,
  steps = 10000,
  hrv_rmssd = 50
)

predict(rf_model, new_data)
```

```
    1
54.12
```

The model predicts an RHR of 54 bpm for a 35 year old male with a BMI of 25, taking 10,000 daily steps, and an HRV RMSSD value of 50. This seems reasonable given the general trends we observed in the data.

There are many ways this could be extended, such as adding more predictors, tuning model hyperparameters, or using more advanced algorithms like XGBoost or deep learning models. The key is to focus on metrics that are relevant to your personal health goals.

## Conclusion

We‘ve only scratched the surface of what‘s possible with self-tracked health data. By leveraging the data analysis and visualization capabilities of R, we can transform raw data from wearables and mobile apps into a personalized dashboard for monitoring and optimizing our fitness and wellbeing.

The code and techniques covered here can be adapted to your own data and interests. I encourage you to start exploring your own data and see what insights you can uncover.

Some additional ideas to explore:

- Incorporate data from additional tracking sources like nutrition apps, smart scales, recovery tools, etc.
- Integrate contextual data like location, weather, calendar, and mood/subjective ratings
- Experiment with different modeling approaches for prediction and optimization
- Share your analysis and learn from others in the data science and quantified self communities

Remember, the goal of personal health tracking is to learn about yourself and make positive changes, not to obsess over numbers or chase arbitrary goals. Use data as a tool for self-discovery and let your intuition and qualitative experiences guide you as well.

Happy tracking, and feel free to reach out with any questions or ideas!

## References

[^1]: Statista. [Fitness and health app downloads worldwide from 2017 to 2026](https://www.statista.com/statistics/1331262/fitness-and-health-app-downloads-worldwide/). Accessed May 22, 2024.

[^2]: Statista. [Worldwide smartwatch shipments 2018-2023](https://www.statista.com/statistics/1055603/worldwide-smart-wristwear-shipments/). Accessed May 22, 2024.

---

Source: [Unlocking Insights from Your Health Data: Building a Personalized Fitness Dashboard in R](https://33rdsquare.com/how-built-personalized-interactive-fitness-tracker-dashboard-r/)
