2012-07-20 81 views
2

我試圖在R中創建一個乾淨的函數來返回TRUE/FALSE,如果一個POSIXlt時間向量在早晨高峯時間,也就是週一早上7.30到9.30到星期五。這是我迄今爲止所做的,但似乎有點漫長而複雜。是否有可能在保持代碼本身可讀性的同時進行改進?R早晨高峯時間測試 - 時間間隔向量

library(lubridate) 

morning.rush.hour <- function(tm) { 
    # between 7.30am and 9.30am Monday to Friday 
    # vectorised... 
    # HARDCODED times here! 
    tm.mrh.start <- update(tm, hour=7, minute=30, second=0) 
    tm.mrh.end <- update(tm, hour=9, minute=30, second=0) 
    mrh <- new_interval(tm.mrh.start, tm.mrh.end) 
    # HARDCODED weekdays here! 
    ((tm$wday %in% 1:5) & # a weekday? 
     (tm %within% mrh)) 
} 
# for test purposes... 
# nb I'm forcing UTC to avoid the error message "Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value" 
# - bonus points for solving this too :-) 
tm <- with_tz(as.POSIXlt(as.POSIXlt('2012-07-15 00:00:01', tz='UTC') + (0:135)*3000), 'UTC') 
data.frame(tm, day=wday(tm, label=TRUE, abbr=FALSE), morning.rush.hour(tm)) 

更妙的是,如果有平日時間清洗功能的定義範圍喜歡這一點,因爲我也有晚高峯時段,和白天這是不急於小時,最後在沒有任何這些!

回答

2

我會做一些比使用difftimecut更簡單的方法。你可以這樣做(使用base功能)以下情況:

morning.rush.hour<-function(tm){ 
    difftime(tm, cut(tm, breaks="days"), units="hours") -> dt #This is to transform the time of day into a numeric (7:30 and 9:30 being respectively 7.5 and 9.5) 
    (tm$wday %in% 1:5) & (dt <= 9.5) & (dt >= 7.5) #So: Is it a weekday, it is before 9:30 and is it after 7:30? 
    } 

編輯:如果需要,您還可以添加一個時區參數difftime

difftime(tm, cut(tm, breaks="days"), units="hours", tz="UTC") 
+0

很整齊!這適用於單個值,例如重命名你的函數mrh1(),mrh1(as.POSIXlt('2012-07-20 07:31:00 UTC')) mrh1(tm)其中tm如上定義 - 與我自己的data.frame(tm,day = wday(tm,label = TRUE,abbr = FALSE),morning.rush.hour(tm),mrh1(tm) ) – Sean 2012-07-20 10:05:05

+1

我試着用你的矢量,它對我來說工作得非常好。你在'difftime'中嘗試了'tz'參數嗎? – plannapus 2012-07-20 10:56:35

+0

是的,如果我把tz ='UTC' – Sean 2012-07-20 16:32:23