Первое и последнее решения, представленные ниже, кажутся самыми простыми, но решения со сложными регулярными выражениями более точно соответствуют тому, что могло быть сделано в perl.
Прежде чем перечислять сами решения, обратите внимание, что в них мы предполагаем, что входное значение равно tt
, а вектор преобразования mult
представляет собой 4-вектор, чьи компоненты представляют собой количество секунд в дне, часах, минутах и секундах. Мы можем установить mult
как в комментарии или рассчитать как показано:
tt <- c("0d 20h 46m 31s", "2d 0h 13m 54s", "2d 0h 13m 53s",
"0d 9h 53m 38s", "5d 12h 17m 37s", "0d 10h 21m 19s")
# mult <- c(86400, 3600, 60, 1)
mult <- rev(cumprod(rev(c(24, 60, 60, 1))))
Вот 4 подхода:
1) быстро извлекаемые числа Мы можем использовать strapply
в пакете gsubfn, чтобы избежать сложных регулярных выражений. strapply
используется для извлечения всех чисел, упорядочивая их в матрице и умножая на mult
, выводя результат в виде простого числового вектора:
library(gsubfn)
mat <- strapply(tt, "\\d+", as.numeric, simplify = TRUE)
secs <- c(mult %*% mat)
Эти две строки можно объединить в одно утверждение, но мы оставим его, как указано выше, на случай, если вы захотите изучить mat
отдельно.
2) связывание со сложным регулярным выражением Другая возможность, также использующая strapply
, заключается в следующем единственном утверждении. Захваченные строки помещаются в свободные переменные по мере их появления, поэтому первый захват переходит в day
, второй в hour
и т. Д. Эта строка может быть ближе к тому, что вы сделали бы в perl:
secs <- strapply(tt, "(\\d+)d (\\d+)h (\\d+)m (\\d+)s",
~ 86400 * as.numeric(day) + 3600 * as.numeric(hour) +
60 * as.numeric(minute) + as.numeric(second), simplify = TRUE)
3) со сложным регулярным выражением, но векторизовано или даже короче:
secs <- strapply(tt, "(\\d+)d (\\d+)h (\\d+)m (\\d+)s",
~ as.numeric(list(...)) %*% mult, simplify = TRUE)
4) strsplit и вот еще один ответ на один оператор. Этот не использует strapply
, но использует тот факт, что соответствующий разделитель в конце строки просто удаляется без вывода следующей пустой строки. Подробнее см. ?strsplit
.
secs <- sapply(strsplit(tt, "[dhms]"), function(x) as.numeric(x) %*% mult)
Результат любого из вышеперечисленного:
> secs
[1] 74791 173634 173633 35618 476257 37279