Reputation: 63
I have a dataset calles marathon and I have tried to use lubridate and churn to convert the characters of marathon$Official.Time into time value in order to work on them. I would like the times to be shown in minutes (meaning that 2 hours are shown as 120 minutes).
data.frame': 5616 obs. of 11 variables:
$ Overall.Position : int 1 2 3 4 5 6 7 8 9 10 ...
$ Gender.Position : int 1 2 3 4 5 6 7 8 9 10 ...
$ Category.Position: int 1 1 2 2 3 4 3 4 5 5 ...
$ Category : chr "MMS" "MMI" "MMI" "MMS" ...
$ Race.No : int 21080 14 2 21077 18 21 21078 21090 21084 12 ...
$ Country : chr "Kenya" "Kenya" "Ethiopia" "Kenya" ...
$ Official.Time : chr "2:12:12" "2:12:14" "2:12:20" "2:12:29" ...
I tried with:
library(lubridate)
times(marathon$Official.Time)
Or
library(chron)
chron(times=marathon$Official.Time)
as.difftime(marathon$Official.Time, units = "mins")
But I only get NA
Upvotes: 1
Views: 1188
Reputation: 78792
NOTE: @mathemetical.coffee's solution is ++gd better than these.
Pretty straightforward to kick it out manually:
library(stringi)
library(purrr)
df <- data.frame(Official.Time=c("2:12:12","2:12:14","2:12:20","2:12:29"),
stringsAsFactors=FALSE)
map(df$Official.Time, function(x) {
stri_split_fixed(x, ":")[[1]] %>%
as.numeric() %>%
`*`(c(60, 1, 1/60)) %>%
sum()
}) -> df$minutes
df
## Official.Time minutes
## 1 2:12:12 132.2
## 2 2:12:14 132.2333
## 3 2:12:20 132.3333
## 4 2:12:29 132.4833
You can also do it with just base R operations and w/o "piping":
df$minutes <- sapply(df$Official.Time, function(x) {
x <- strsplit(x, ":", TRUE)[[1]]
x <- as.numeric(x)
x <- x * (c(60, 1, 1/60))
sum(x)
}, USE.NAMES=FALSE)
If "stuck" with base R then I'd prbly actually do:
vapply(df$Official.Time, function(x) {
x <- strsplit(x, ":", TRUE)[[1]]
x <- as.numeric(x)
x <- x * (c(60, 1, 1/60))
sum(x)
}, double(1), USE.NAMES=FALSE)
to ensure type safety.
But, chron
can also be used:
library(chron)
60 * 24 * as.numeric(times(df$Official.Time))
NOTE that lubridate
has no times()
function.
Upvotes: 0
Reputation: 56905
You were almost there with difftime
(which requires two times and gives you the difference). Instead, use as.difftime
(which requires one "difference" - ie marathon time) and specify the format
as hours:minutes:seconds.
> as.difftime("2:12:12", format="%H:%M:%S", units="mins")
Time difference of 132.2 mins
> as.numeric(as.difftime("2:12:12", format="%H:%M:%S", units="mins"))
[1] 132.2
No extra packages needed.
Upvotes: 1