使用 lubridate 从 R 中提取时间段

Using lubridate to extract time periods from in R

上下文

作为 Exclude specific time periods in R

的后续
str(databank[[1]])
'data.frame':   987344 obs. of  13 variables:
 $ Date      : Factor w/ 43 levels "01/03/2017","02/03/2017",..: 17 17 17 17 17 17 17 17 17 17 ...
 $ Time      : Factor w/ 23400 levels "01:00:00 PM",..: 15344 15343 15342 15341 15340 15339 15338 15337 15336 15335 ...
 $ Bar.      : Factor w/ 63033 levels "","1/63032","10/63032",..: 58929 1 1 1 1 1 1 1 58928 1 ...
 $ Bar.Index : int  0 NA NA NA NA NA NA NA -1 NA ...
 $ Tick.Range: int  5 NA NA NA NA NA NA NA 0 NA ...
 $ Open      : num  16.9 NA NA NA NA ...
 $ High      : num  16.9 NA NA NA NA ...
 $ Low       : num  16.9 NA NA NA NA ...
 $ Close     : num  16.9 NA NA NA NA ...
 $ Vol       : num  900 0 0 0 0 0 0 0 100 0 ...
 $ MACDHist  : num  -137 NA NA NA NA ...
 $ MACD      : num  -225 NA NA NA NA ...
 $ MACDSig   : num  -87.9 NA NA NA NA ...

head(databank[[1]])
Date        Time        Bar. Bar.Index Tick.Range  Open  High  Low Close
1 12/04/2017 10:45:43 AM 63032/63032         0          5 16.95 16.95 16.9 16.95
2 12/04/2017 10:45:42 AM                    NA         NA    NA    NA   NA    NA
3 12/04/2017 10:45:41 AM                    NA         NA    NA    NA   NA    NA
4 12/04/2017 10:45:40 AM                    NA         NA    NA    NA   NA    NA
5 12/04/2017 10:45:39 AM                    NA         NA    NA    NA   NA    NA
6 12/04/2017 10:45:38 AM                    NA         NA    NA    NA   NA    NA
  Vol MACDHist    MACD MACDSig
1 900  -136.77 -224.68  -87.91
2   0       NA      NA      NA
3   0       NA      NA      NA
4   0       NA      NA      NA
5   0       NA      NA      NA
6   0       NA      NA      NA

问题

我尝试使用以下方法实现最佳答案的 lubridate 方法:

test1 <- databank[[1]][hour(d) == 9 & minute(d) > 30,] 

但是从9:30:00到9:59:59只有returns次,得到从9:35:00到15:55:00的次数...

我尝试过的东西

test1 <- databank[[1]][hour(d) == 9 & minute(d) > 30, hour(d) == 15 & minute(d) < 55]

test1 <- databank[[1]][hour(d) == 9 & minute(d) > 30 & hour(d) == 15 & minute(d) < 55, ] 

但前者 returns 是一个空的 table,有 ~79,000 个空白行(只有条目号),没有 headers,后者是一个空的 table只有 headers。我认为这是一个问题,因为我的日期和时间不在 POSIX 但 运行 转换它们时遇到麻烦...

我错过了什么?

在其他SO答案中遇到|操作数后,我实现了它并得到了这个:

test1 <- databank[[1]][(hour(d) == 9 & minute(d) > 34) | (hour(d) == 10 & minute(d) > 0) | (hour(d) == 11 & minute(d) > 0) | (hour(d) == 12 & minute(d) > 0) | (hour(d) == 01 & minute(d) > 0) | (hour(d) == 02 & minute(d) > 0) | (hour(d) == 03 & minute(d) <= 54), ]

鉴于有限的知识,一个丑陋的解决方案,但它有效。

根据 Uwe Block 的建议:

databank[[1]][hour(d) == 9 & minute(d) >= 35) | hour(d) %in% 10:14 | (hour(d) == 15 & minute(d) < 55]

我非常欢迎看到一个更优雅的解决方案!

你的问题不是很清楚你的起始条件是什么。要只处理时间(没有关联日期),chron 包很方便。

#create a random time sequnce
h<-rep( c(1:22), each=2)
m <- c(1:44)
randomtimes<-paste(h, m, "00", sep=":")

library(chron)
#convert the time strings in time objects
samplet<- times(randomtimes)

#perform comparison and subset
samplet[(samplet > times("9:30:00") & samplet< times("15:55:00"))]

实际问题(此处)中给出的数据样本databank[[1]]与参考问题Exclude specific time periods in R中的情况不同():

  1. timestamp那里已经转换为classPOSIXctDateTime 这里在单独的factor列中。
  2. 此处Time使用12小时制,指标为AM/PM。

可能可以使用 Time 的因子水平,但这是不可靠的。因此,恕我直言,最安全的方法是从 DateTime 列创建一个 POSIXct 时间戳,稍后按一天中的时间(没有日期)创建 select。

添加时间戳

databank[[1L]]$datetime <- 
  with(databank[[1L]], as.POSIXct(paste(Date, Time), "%d/%m/%Y %I:%M:%S %p", tz = "GMT"))

添加时间

为方便起见,添加了一个 time_of_day(无日期)列作为字符:

databank[[1L]]$time_of_day <- 
  with(databank[[1L]], format(datetime, "%T"))

databank[[1L]][, c("Date", "Time", "datetime", "time_of_day")]
#         Date        Time            datetime time_of_day
#1: 12/04/2017 10:45:43 AM 2017-04-12 10:45:43    10:45:43
#2: 12/04/2017 10:45:42 AM 2017-04-12 10:45:42    10:45:42
#3: 12/04/2017 10:45:41 AM 2017-04-12 10:45:41    10:45:41
#4: 12/04/2017 10:45:40 AM 2017-04-12 10:45:40    10:45:40
#5: 12/04/2017 10:45:39 AM 2017-04-12 10:45:39    10:45:39
#6: 12/04/2017 10:45:38 AM 2017-04-12 10:45:38    10:45:38
#7: 12/04/2017 10:45:00 PM 2017-04-12 22:45:00    22:45:00

请注意,我添加了下午时间以供说明。

Select 行按时间范围

databank[[1L]][time_of_day >= "09:35:00" & time_of_day < "15:55:00", ]