Вы можете сделать что-то вроде этого
duration <- c("57M8S","31S","2H20M31S", "21M32S")
sapply(duration, function(x) {
v <- as.numeric(unlist(strsplit(x, "[HMS]")));
return(sum(60^(rev(seq_along(v) - 2)) * v));
})
# 57M8S 31S 2H20M31S 21M32S
#57.1333333 0.5166667 140.5166667 21.5333333
Объяснение: Разделить записи на любой символ HMS
; затем умножьте каждое значение на 60^k
, где показатель степени k
определяется числом делений минус 2
. Таким образом, если мы получим только одно значение после разделения, оно будет обозначать секунды, и мы умножим эту запись на 60^(-1)
, чтобы преобразовать в минуты.
Или продемонстрировать более явно (и более неловко):
sapply(duration, function(x) {
v <- as.numeric(unlist(strsplit(x, "[HMS]")));
if (length(v) == 1) val <- v / 60;
if (length(v) == 2) val <- v[1] + v[2] / 60;
if (length(v) == 3) val <- v[1] * 60 + v[2] + v[3] / 60;
return(val);
})
Другой интересный подход @akrun использует пакет gsubfn
для замены H
на * 60 +
, M
на * 1 +
и S
на * 1/60 +
, перед eval
с использованием полученной строки:
library(gsubfn);
sapply(sub(
" \\+$", "",
gsubfn("([HMS])", list(H = "* 60 +",M = "* 1 +", S = "* 1/60 +"), duration)),
function(x) eval(parse(text= x)))
# 57* 1 +8* 1/60 31* 1/60 2* 60 +20* 1 +31* 1/60
# 57.1333333 0.5166667 140.5166667
# 21* 1 +32* 1/60
# 21.5333333