0

I am trying to figure out how to take the mean and SD of bedtimes, but I am having difficulty managing times after midnight. These concepts make sense logically (I think) but figuring out how to code it in R is tricky.

Right now, those pull the mean down toward daytime (i.e., toward noon), when they logically should pull the mean toward nighttime (i.e., toward midnight).

Here is an example, where the mean time should be closer to midnight but isn't.

library(chron)
In.Bed.Date <- c("6/15/2019", "6/15/2019", "6/16/2019", "6/17/2019", "6/17/2019", "6/19/2019")
In.Bed.Time <- c("12:50 AM", "7:22 PM",  "5:20 PM",  "12:52 AM", "9:39 PM",  "1:00 AM")

#Fix In Bed Date/Time Variables
In.Bed.Date <- as.dates(In.Bed.Date)
In.Bed.Time <- as.times(format(strptime(In.Bed.Time, '%I:%M %p'), format = '%H:%M:%S'))

#New Combined Date/Time Variable for Bed
In.Bed <- chron(dates. = In.Bed.Date, times. = In.Bed.Time, format = c(dates = 'm/d/y', times = 'h:m:s'))

#Mean/SD just using Time variable
Mean <- mean(In.Bed.Time)
SD <- times(sd(In.Bed.Time))

#Mean/SD trying to use Date/Time variable
Mean <- mean(In.Bed)
SD <- times(sd(In.Bed))

The issues I am having is that the mean using the Time variable is coming out at 10:10:30 am. I think the SD is also incorrectly formatting the time variable, as it is coming out as 10:15:06, but I'm less sure about that.

Trying to use the Date/Time variable causes the calculation to include the date, which is also not what I want. Instead, I just want to find the average bedtime each night, and the SD of bedtimes.

Zach
  • 21
  • 3
  • Good starting points: read about POSIX dates, and take a look at the `lubridate` package for many easy tools to handle "rollover" situations like this. Then calculate the "raw" datevalue - which is an always-increasing number from a certain epoch -- , get the statistics on that, and **then** convert back to a time of day – Carl Witthoft Jul 22 '20 at 15:31

1 Answers1

1

Why don't you just add 12 hours to calculate the mean and standard deviation and then subtract 12 to get your times back. Like this:

Here is your own code

In.Bed.Time <- c("12:50 AM", "7:22 PM",  "5:20 PM",  "12:52 AM", "9:39 PM",  "1:00 AM")
In.Bed.Time <- as.times(format(strptime(In.Bed.Time, '%I:%M %p'), format = '%H:%M:%S'))
In.Bed.Time
[1] 00:50:00 19:22:00 17:20:00 00:52:00 21:39:00 01:00:00

Here is what I suggest you do

In.Bed.Time = In.Bed.Time + as.times('12:00:00')
Mean = mean(In.Bed.Time)
SD = sd(In.Bed.Time)
Mean
[1] 22:10:30
SD
[1] 0.4271581

And you get your original times back

In.Bed.Time = In.Bed.Time - as.times('12:00:00')
In.Bed.Time
[1] 00:50:00 19:22:00 17:20:00 00:52:00 21:39:00 01:00:00
Haci Duru
  • 456
  • 3
  • 9
  • No no no!!! **NEVER** start creating your own date-manipulation functions! – Carl Witthoft Jul 22 '20 at 15:28
  • I don't understand. What is wrong with my answer. It is easy and straightforward. It does not need any library other than what is already imported, which is chron. Can you clarify what you mean by "No no no!! ..."? – Haci Duru Jul 22 '20 at 15:41
  • Well, you could start by skimming thedailywtf.com for articles describing how all sorts of homebrew time/date handling led to disastrous results. – Carl Witthoft Jul 22 '20 at 16:57
  • But I did not suggest any data home-brew manipulation function. I just offered a simple solution to a simple question. And it works. – Haci Duru Jul 22 '20 at 17:11
  • 1
    I've found this answer while looking for a duplicate of [this question](https://stackoverflow.com/q/65637024/). I agree that this seems like a very reasonable approach. – Ian Campbell Jan 08 '21 at 23:47