R: How to handle times without dates?

2019-01-07 00:12发布

I have data which includes Date as well as Time enter and Time exit. These latter two contain data like this: 08:02, 12:02, 23:45 etc.

I would like to manipulate the Time eXXX data - for example, substract Time enter from Time exit to work out duration, or plot the distributions of Time enter and Time exit, e.g. to see if most entries are before 10:00, or if most exits are after 17:00.

All the packages I've looked at require a date to precede the time, e.g. 01/02/2012 12:33.

Is this possible, or should I simply append an identical date to every time for the sake of calculations? This seem a bit messy!

标签: r date time
3条回答
\"骚年 ilove
2楼-- · 2019-01-07 00:37

Would something like that work?

SubstracTimes <-  function(TimeEnter, TimeExit){
  (as.numeric(format(strptime(TimeExit, format ="%H:%M"), "%H")) + 
  as.numeric(format(strptime(TimeExit, format ="%H:%M"), "%M"))/60) -
  (as.numeric(format(strptime(TimeEnter, format ="%H:%M"), "%H")) + 
   as.numeric(format(strptime(TimeEnter, format ="%H:%M"), "%M"))/60)
}

Testing:

TimeEnter <- "08:02"
TimeExit <- "12:02"
SubstracTimes(TimeEnter, TimeExit)
> SubstracTimes(TimeEnter, TimeExit)
[1] 4
查看更多
地球回转人心会变
3楼-- · 2019-01-07 00:48

Came across a similar issue and was inspired by this post. @G. Grothendieck and @David Arenburg provided great answers for transforming the time.

For comparison, I feel forcing the time into numeric helps. Instead of comparing "11:22:33" with "9:00:00", comparing as.numeric(hms("11:22:33")) (which is 40953 seconds) and as.numeric(hms("9:00:00")) (32400) would be much easier.

as.numeric(hms("11:22:33")) > as.numeric(hms("9:00:00"))  &  as.numeric(hms("11:22:33")) < as.numeric(hms("17:00:00"))
[1] TRUE

The above example shows 11:22:33 is between 9AM and 5PM.

To extract just time from the date or POSIXct object, substr("2013-10-01 11:22:33 UTC", 12, 19) should work, although it looks stupid to change a time object to string/character and back to time again.

Converting the time to numeric should work for plotting as @G. Grothendieck descirbed. You can convert the numbers back to time as needed for x axis labels.

查看更多
Deceive 欺骗
4楼-- · 2019-01-07 00:56

Use the "times" class found in the chron package:

library(chron)

Enter <- c("09:12", "17:01")
Enter <- times(paste0(Enter, ":00"))

Exit <-  c("10:15", "18:11")
Exit <- times(paste0(Exit, ":00"))

Exit - Enter # durations

sum(Enter < "10:00:00") # no entering before 10am
mean(Enter < "10:00:00") # fraction entering before 10am

sum(Exit >  "17:00:00") # no exiting after 5pm
mean(Exit >  "17:00:00") # fraction exiting after 5pm

table(cut(hours(Enter), breaks = c(0, 10, 17, 24))) # Counts for indicated hours   
 ## (0,10] (10,17] (17,24] 
 ##      1       1       0 

table(hours(Enter))  # Counts of entries each hour
## 9 17 
## 1  1

stem(hours(Enter), scale = 2)
## The decimal point is at the |

##   9 | 0
##  10 | 
##  11 | 
##  12 | 
##  13 | 
##  14 | 
##  15 | 
##  16 | 
##  17 | 0

Graphics:

tab <- c(table(Enter), -table(Exit))  # Freq at each time.  Enter is pos; Exit is neg.
plot(times(names(tab)), tab, type = "h", xlab = "Time", ylab = "Freq")
abline(v = c(10, 17)/24, col = "red", lty = 2) # vertical red lines
abline(h = 0)  # X axis

screenshot

查看更多
登录 后发表回答