# How to split a time series into “day” and “night” intervals?

I have measured a lot of daily activity of people, with data for one person looking like in this image:

I would now like to automatically estimate the time when this person wakes up, and more generally, extract one coherent interval from (in this image) around 5:00am to 10:00pm as the "active" interval, i.e. where this person is awake.

The following line is the per-time-point standard deviation for one person, which shows the clearest separation from day and night so far.

I have brainstormed a few ideas, like tree stumps, something similar to HPD intervals, Hidden Markov Models, or k-means of the y values. But none would result in exactly one coherent interval of higher activity.

What methods would you suggest to split the day up into two intervals using this data?

I'm not even sure if it's better to work with the set of raw days, or the single line of standard deviations (the means have a similar shape but are not so well separated).

• Have you looked at tests for a break at an unkown period like sup-Wald, sup-LM, sup-LR? – suckrates Sep 10 '18 at 12:23
• Not yet, but from what I just read, it looks promising. Is there any way I can fit two linear models to the data, where (a) the slope is fixed to zero and only the intercept can vary, and (b) the x-axis is cyclical, i.e. the "night" interval from 10pm to 5am is also one coherent interval? – Alexander Engelhardt Sep 10 '18 at 12:39

You can use changepoint analysis. I have used with the changepoint package in R. There are several algorithms available (not sure that it would matter computationally, but it will for available parameters). More important would be the parameter selection.
I'll suppose that your data is in a data frame called dat and that you have columns for personid, time and activity. I'm assuming you want to automatically determine this interval for each person, and you would need to aggregate it to mean activity by person and time.
changepoint has 3 different functions you may want to try. One will look for changes according to mean, one according to variance, and one according to both. I'd suggest some trial and error to see which one most consistently gives the type of result you expect. Then you would end up with something like:
cpt.mean(data,method="BinSeg",Q=2)

This will search for changepoints on the mean only using the BinSeg method. You could also use the SegNeigh method. These both give you the Q parameter, which is the maximum number of changepoints. You want this to be 2 (with SegNeigh, you would specify 3 to mean the maximum number of segments). You need a break in the morning when they wake, and a break in the evening when they rest.