简体   繁体   中英

Convert HH:MM:SS to hours (for more than 24 hours) in R

I would like to convert hours more than 24 hours in R.

For example, I have a dataframe which contains hours and minutes like [HH:MM]:

[1] "111:15" "221:15" "111:15" "221:15" "42:05"

I want them to be converted in hours like this:

"111.25" "221.25" "111.25" "221.25" "42.08333333"

as.POSIXct() 

function works for general purpose, but not for more than 24 hours.

You can split the strings with strsplit and use sapply to transform all values.

vec <- c("111:15", "221:15", "111:15", "221:15", "42:05")

sapply(strsplit(vec, ":"), function(x) {
  x <- as.numeric(x)
  x[1] + x[2] / 60
})

The result:

[1] 111.25000 221.25000 111.25000 221.25000  42.08333

I would just parse the strings with regex. Grab the bit before the : then add on the bit after the : divided by 60

> foo = c("111:15", "221:15", "111:15", "221:15", "42:05")
> foo
[1] "111:15" "221:15" "111:15" "221:15" "42:05" 
> as.numeric(gsub("([^:]+).*", "\\1", foo)) + as.numeric(gsub(".*:([0-9]{2})$", "\\1", foo))/60
[1] 111.25000 221.25000 111.25000 221.25000  42.08333

Another possibility is a vectorized function such as:

FUN <- function(time){
    hours <- sapply(time,FUN=function(x) as.numeric(strsplit(x,split=":")[[1]][1]))
    minutes <- sapply(time,FUN=function(x) as.numeric(strsplit(x,split=":")[[1]][2]))
    result <- hours+(minutes/60)
    return(as.numeric(result))
}

Where you use strsplit to extract the hours and minutes, of which you then take the sum after dividing the minutes by 60.

You can then use the function like this:

FUN(c("111:15","221:15","111:15","221:15","42:05"))

[1] 111.25000 221.25000 111.25000 221.25000  42.08333

strapplyc Here ia a solution using strapplyc in the gsubfn package . It passes the match to each of the parenthesized regular expressions (ie the hours and the minutes) to the function described in the third argument. The function can be specified using the usual R function notation and it also supports a short form using a formula (used here) where the right hand side of the formula is the function body and the left hand side represent the arguments and defaults to the free variables ( m , h ) in the right hand side. We suppose that the original character vector is ch .

library(gsubfn)
strapply(ch, "(\\d+):(\\d+)", ~ as.numeric(h) + as.numeric(m)/60, simplify = TRUE)

numeric processing Another way is to replace the : with a . and manipulate it numerically into what we want:

num <- as.numeric(chartr(":", ".", ch))
trunc(num) + 100 * (num %% 1) / 60

sub This is yet another approach:

h <- as.numeric(sub(":.*", "", ch))
m <- as.numeric(sub(".*:", "", ch))
h + m / 60

The codes above each gives a numberic result but we could wrap each in as.character(...) if a character result were desired.

read.table

as.matrix(read.table(text = ch, sep = ":")) %*% c(1, 1/60)

eval/parse . This one maipulates each one into an R expression which is evaluated. This one is short but the use of eval is often frowned upon:

sapply(parse(text = sub(":", "+(1/60)*", ch)), eval)

ADDED additional solutions.

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