Search code examples
rvectorizationstrsplit

Vectorizing a function that uses strsplit


I am trying to make a function that converts time (in character form) to decimal format such that 1 corresponds to 1 am and 23 corresponds to 11 pm and 24 means the end of the day.

Here are the two function that does this. Here one function vectorizes while other do

time2dec <- function(time0)
{
time.dec <-as.numeric(substr(time0,1,2))+as.numeric(substr(time0,4,5))/60+(as.numeric(substr(time0,7,8)))/3600
return(time.dec)
}

time2dec1 <- function(time0)
{
time.dec <-as.numeric(strsplit(time0,':')[[1]][1])+as.numeric(strsplit(time0,':')[[1]][2])/60+as.numeric(strsplit(time0,':')[[1]][3])/3600
return(time.dec)
}

This is what I get...

times <- c('12:23:12','10:23:45','9:08:10')

#>time2dec(times)
[1] 12.38667 10.39583       NA
Warning messages:
1: In time2dec(times) : NAs introduced by coercion
2: In time2dec(times) : NAs introduced by coercion

#>time2dec1(times)
[1] 12.38667

I know time2dec which is vectorized, gives NA for the last element because it extracts 9: instead of 9 as hour. That is why I created time2dec1 but I do not know why it is not getting vectorized.

I will also be interested in getting a better function for doing what I am trying to do. I saw this which explain a part of my question but does not provide a clue to do what I am trying.


Solution

  • Don't try to reinvent the wheel:

    times1 <- difftime(as.POSIXct(times, "%H:%M:%S", tz="GMT"),
                       as.POSIXct("0:0:0", "%H:%M:%S", tz="GMT"), 
                       units="hours")
    #Time differences in hours
    #[1] 12.386667 10.395833  9.136111
    
    as.numeric(times1)
    #[1] 12.386667 10.395833  9.136111