开发者

R: calculate time elapsed between 2 numeric times, e.g 944 and 1733 is 469 minutes

I'm trying to write an elegant function in R to calculate the elapsed time between two timestamps, which are stored as integers with the format hmm or hhmm. I would like to return the elapsed time as an integer of minutes.

Here's my solution so far, which can probably be greatly improved:

#Treatment of varous length inputs:
#1 digit  = m
#2 digits = mm
#3 digits = hmm
#4 digits = hhmm
#5+ digits = failure

elapsedtime <- function(S,E) {
    S<-c(as.character(S))
    开发者_如何学PythonE<-c(as.character(E))

    if (length(S)!=length(E)) {
        stop("Invalid input")
    }

    for (i in seq(1:length(S))) {
        if (nchar(S[i])>4) {S[i]<-NA}
        if (nchar(E[i])>4) {E[i]<-NA}

        while (nchar(S[i])<4) {
            S[i]<-paste('0',S[i],sep='')
        }

        while (nchar(E[i])<4) {
            E[i]<-paste('0',E[i],sep='')
        }
        S[i]<-as.character(as.numeric(substr(S[i],1,2))*60+as.numeric(substr(S[i],3,4)))
        E[i]<-as.character(as.numeric(substr(E[i],1,2))*60+as.numeric(substr(E[i],3,4)))

    }
    S<-as.numeric(S)
    E<-as.numeric(E)

    return(E-S)
}
elapsedtime(944,1733) 
elapsedtime(44,33)
elapsedtime(44,133)
elapsedtime(c(944,44),c(1733,33))
elapsedtime(c(44,44),c(33,133))
elapsedtime(944,17335)
elapsedtime(c(944,945),c(1733,17335))
elapsedtime(c(944,945),c(1733,17335,34))

I'm not too wedded to the need to deal with the 1 and 2 digit cases, but I need to be able to handle input with 3 or 4 digits. I'm running this on a lot of dates, and doing 3/4 digits quickly is much preferable to doing 1,2,3 or 4 digits slowly.

/edit: Changed code to work properly on vectors of times


Try the following functions:

 # calculate number of minutes of timestamp
 mins <- function(x){
   floor(x/100)*60+x%%100
 }

 # calculate difference in minutes
 elapsedtime <- function(S,E){
   mins(E)-mins(S)
 }

This avoids loops so is vectorised. mins will work if hours are greater than 99, ie HHHMM, or you can modify for higher time units.

If 5 digits timestamps are actually erroneous, you can add the following as the first line of mins:

ifelse(x<10000,x,NA)

So you will get an NA in the difference when either or both of the timestamps are 5 digits.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜