Tuesday, June 21, 2016

Measuring Resting Time

So, I concluded that time spent lying down is the best fatigue/performance measure. The question now is how to measure the time spent lying down.

Polar activity trackers track the time spent resting. (See the supine icon with "1hr 25" below it in the picture below? That is the time spent resting). I'm not sure if that is same as time spent lying down or if it can serve as the fatigue/performance metric. But it will be worthwhile exploring. I'll eventually buy one and check it out. For now, I'm staying with Fitbit Charge HR that I already spent money on last year. (I made a feature request to Fitbit to add resting in activities they track, but I haven't heard from them pip squeak).


One way to detect when you are lying down is by monitoring the heart rate. It goes  up about 5 bps when you sit up and another 5 bps when you stand up. But the heart rate is so variable that I don't think it is possible to figure out when you are lying down just by looking at the heart rate. The noise is bigger than the signal, in other words, as you can see in the plot below. And you can't extract useful information when the noise is bigger than the signal unless you can tag the noise somehow and eliminate it, at least partially.



So instead I looked at both the heart rate and calorie data to see if their being at certain level correlates to time spent lying down or fatigue level.  And it turned out that the total number of minutes with less than 120% of the base calories correlates to the fatigue rating at 68%. (Again, this was done for the period from 7/19 to 8/11, for which the manually logged resting time is available).

getCalMinutes=function(fintraday)
{
  wakingcals=fintraday[(10*60+1):(22*60),]$calories
  restingcal=min(wakingcals,na.rm=T)
  sapply(1:20,function(i)length(which(wakingcals<(restingcal*(1+i/20)))))
}

calMinutes=by(fintradays,as.Date(index(fintradays),tz="US/Pacific"),getCalMinutes,simplify=T)
# by() returns a list. convert it to a matrix
calMinutes=t(simplify2array(calMinutes))
# it is now matrix of minutes of N percentile calories for each day. convert it to zoo
dates=rownames(calMinutes)
calMinutes=as.zoo(calMinutes,as.Date(dates))
# Compute correlation to resting minutes and fatigue
calMinutes=merge(calMinutes,restingMinutes,fatigue=lag(daily$fatigue,-1),all=F)
cor(calMinutes,cbind(restingMinutes=calMinutes$restingMinutes,fatigue=calMinutes$fatigue))

               restingMinutes    fatigue
calMinutes.1        0.4571173 -0.5230321
calMinutes.2        0.3673384 -0.4677888
calMinutes.3        0.5258373 -0.6054458
calMinutes.4        0.5494959 -0.6842468
calMinutes.5        0.5929351 -0.6026978
...

68% is a strong correlation and may serve as the proxy for fatigue/performance measure. Unfortunately, it dropped to 43% when I ran it for the complete time period of 1 year. So, it is not that usable.

For strong correlation, I may have to return to the heart rate again. If I combine with motion data, I may be able to tell if I'm resting. That is how the trackers tell if you are sleeping. The problem is there is no tracker that makes the accelerometer/gyroscope data available. They only give you processed data like calories and activity times. So, for that, I may have to resort to an Android Wear device that will let me access all raw data through Android API.

I'll need the raw data anyway to discern activities like showering, doing dishes or doing a few push-ups. (Commercial activity trackers don't need to track those mundane activities since their aim is to make healthy people healthier. But CFS patients need to track ADLs because mundane ADLs are equivalent to heavy exercises for them.) So I may skip Polar tracker and go straight to an Android Wear watch.

No comments:

Post a Comment