简体   繁体   中英

Find rows with time between two values in R

I have a dataframe temp which looks like the following:

Time       Count       Colour                 
01:02:30  11.000000       Red
17:05:49  52.000000       White
04:06:07   4.000000       Blue 
01:07:03  30.000000       Red  
20:08:30   4.000000       Yellow

The Time was initially an ISODate do I stripped it off to get the time, which is what I wanted, using the code below.

temp$Time = parse_iso_8601(temp$Time)
temp$Time <- as.POSIXlt(temp$Time) 
library(chron)
temp$Time=times(format(temp$Time, format="%H:%M:%S"))

Now, I wish to find rows with time between 02:00:00 and 05:00:00. Can you please suggest how this can be done? Thanks!

Here is my try,

temp <- read.table(text = "Time       Count       Colour                 
01:02:30  11.000000       Red
17:05:49  52.000000       White
04:06:07   4.000000       Blue 
01:07:03  30.000000       Red  
20:08:30   4.000000       Yellow", header = TRUE)

library(chron)
temp$Time <- times(format(temp$Time, format="%H:%M:%S"))
temp[temp$Time >= 2/24 & temp$Time <= 5/24, ]

Output:

> temp[temp$Time >= 2/24 & temp$Time <= 5/24, ]
      Time Count Colour
3 04:06:07     4   Blue

The logic:

The code below shows that the function times should be mapping [00:00:00, 23:59:59.999...) to [0, 1)

> as.numeric(times(paste(0:23, ":00:00", sep = "")))
 [1] 0.00000000 0.04166667 0.08333333 0.12500000 0.16666667 0.20833333
 [7] 0.25000000 0.29166667 0.33333333 0.37500000 0.41666667 0.45833333
[13] 0.50000000 0.54166667 0.58333333 0.62500000 0.66666667 0.70833333
[19] 0.75000000 0.79166667 0.83333333 0.87500000 0.91666667 0.95833333

Thus, to find if the Time is between 02:00:00 and 05:00:00, you can check whether it is greater or equal to 2/24 and smaller or equal to 5/25.


The gap problem:

Not sure if it is what you want.

Assume temp is ordered by date and time, like the one below

library(chron)
temp <- data.frame(
  Record = 1:8, 
  Day = c(1, 1, 1, 1, 1, 2, 2, 2), 
  Time = c("01:02:30", "01:07:03", "04:06:07", "17:05:49", "20:08:30", "02:00:00", "02:15:00", "04:07:00")
)
temp$Time <- times(format(temp$Time, format="%H:%M:%S"))
> temp
  Record Day     Time
1      1   1 01:02:30
2      2   1 01:07:03
3      3   1 04:06:07
4      4   1 17:05:49
5      5   1 20:08:30
6      6   2 02:00:00
7      7   2 02:15:00
8      8   2 04:07:00

R code to do your task:

temp$Gap <- 24 * (c(NA, diff(temp$Time)) + c(NA, diff(temp$Day) > 0))
temp$Gap3hr <- temp$Gap >= 3 # 3 hour gap
temp$HourFromFirst <- 24 * (temp$Time - temp$Time[1]) + 24 * (temp$Day - temp$Day[1])

tempSelected <- lapply(which(temp$Gap3hr == TRUE), function(i) {
    BeforeGap1hr <- (temp$HourFromFirst[i - 1] - temp$HourFromFirst) <= 1 & (temp$HourFromFirst[i - 1] - temp$HourFromFirst) >= 0
    AfterGap1hr <- (temp$HourFromFirst - temp$HourFromFirst[i]) <= 1 & (temp$HourFromFirst - temp$HourFromFirst[i]) >= 0
    temp[BeforeGap1hr | AfterGap1hr, ]
  }
)

Output:

> tempSelected
[[1]]
  Record Day     Time       Gap Gap3hr HourFromFirst
3      3   1 04:06:07  2.984444  FALSE      3.060278
4      4   1 17:05:49 12.995000   TRUE     16.055278

[[2]]
  Record Day     Time       Gap Gap3hr HourFromFirst
4      4   1 17:05:49 12.995000   TRUE      16.05528
5      5   1 20:08:30  3.044722   TRUE      19.10000

[[3]]
  Record Day     Time      Gap Gap3hr HourFromFirst
5      5   1 20:08:30 3.044722   TRUE      19.10000
6      6   2 02:00:00 5.858333   TRUE      24.95833
7      7   2 02:15:00 0.250000  FALSE      25.20833

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM