Below is a chart I made showing all of my sleep tracking data for last year collected using my Basis Health Tracker. Each day shows a stacked bar consisting of each major sleep stage (Light, REM, Deep) as well as any time I woke up during the night (Interruption) or the device was unable to get readings (Unknown).
Note that Basis didn’t enable their sleep tracking functionality until January 19th, which is why there is no data showing on the chart for the first few weeks.
Average Sleep by Day of Week
I wanted to dig a little deeper into the data and see if there were any obvious trends. The first thing I did was calculate my average sleep for each day of the week:
For the year, I averaged 6.8 hours of sleep per night, ranging from a low of 6.48 hours on Wednesdays to a high of 7.37 hours on Saturdays (no surprise there!). I’m actually somewhat surprised that my average is so low, as I have always considered myself to be someone that got closer to a “solid 8″ hours a night.
Average Sleep Stages by Day of Week
I then looked at how my various sleep stages compared for each day of the week:
|Day||Light||Light %||REM||REM %||Deep||Deep %||Interrupt||Interrupt %||Unknown||Unknown %|
What’s interesting is that even though my total sleep time fluctuates throughout the week, my relative percentages of Light, REM, and Deep sleep remain consistent.
I wanted to then calculate the average time I fell asleep each night. Unfortunately, I ran into some problems doing this because you can’t simply use Excel’s AVERAGE() command. Let’s say you fell asleep one night at 11pm, the next night at 1am, and the third night at 3:00am – the average time you fell asleep would be 1am, right? Not according to Excel:
Excel calculates the average time as 9am! The problem is that some nights I fall asleep before midnight (23:59:59), and others I fall after (00:00:00). This is like averaging 24 and 0, which equals noon. Ugh.
Time Zones and Travel
I noticed several instances where my sleep start time looked a bit strange. This was because although Basis provides each sleep instance in UTC time format (along with offset, so you can adjust for your local time zone/daylight savings time), it doesn’t factor in traveling to other time zones. So, all of my sleep times are based on my local time zone, even if I was, say, traveling halfway around the world.
Surprisingly, there weren’t as many sleep trends as I had expected. Overall, I seem to sleep pretty consistently. I think a more valuable use of my sleep data is to begin correlating it with other variables – i.e., if I exercise or drink alcohol, does that have a positive or adverse effect on overall sleep? Does meditation or brain entrainment result in improved REM function that evening? Does sleep quality predict Heart Rate Variability (HRV) the following day (or vice versa)?
How I Did It
Manipulating this data was a bit more laborious than I was expecting. First, I exported all of my sleep data from Basis using my export script that I have previously posted about. Here is a sample JSON response that Basis provides for one given day of sleep data. I wrote a simple Python script to dump each day’s worth of data into MongoDB (preserving the original JSON structure), then wrote a MongoDB aggregation query that would return a summary of sleep data for each day:
This would dump the results into a temporary collection called “sleepexport” that contains each day’s aggregate sleep totals (since you may have multiple segments of sleep for any given night):
I could then run mongoexport on to create a .csv file that I could import into Excel and make pretty charts:
If anyone knows how to calculate average time in Excel from a series of UTC-formatted timestamps, please let me know!