Я хочу преобразовать значения миллисекунд в моих данных в минуты и секунды (в формате MM:SS, например, значение 1772094 должно стать 29:32).
Данные игрушки выглядят так:
df <- data.frame(
ID = c("ID1", "ID2", "ID3"),
duration = c(1723456, 1834537, 1945678)
)
Результат, который я хочу:
Я подошел близко, но не идеально к приведенному ниже коду.
library(dplyr)
library(lubridate)
library(hms)
df2 <- df %>%
mutate(duration_ms = seconds_to_period(duration/1000)) %>%
mutate(duration_ms = hms::hms(duration_ms))
Я делю значения миллисекунд на тысячу, чтобы преобразовать их в секунды, чтобы их можно было использовать функцией seconds_to_period()
в lubridate
, а затем форматирую их с помощью hms
.
Но в настоящее время это ЧЧ:ММ:СС, где секунды имеют десятичные знаки (не округлены).
Как преобразовать значения миллисекунд в значения минут и секунд в формате MM:SS в R?
Вы можете просто round()
разделить duration
на 1000:
df %>%
mutate(duration_ms = seconds_to_period(round(duration / 1000))) %>%
mutate(duration_ms = hms::hms(duration_ms))
# ID duration duration_ms
# 1 ID1 1723456 00:28:43
# 2 ID2 1834537 00:30:35
# 3 ID3 1945678 00:32:26
Обратите внимание, что округление означает, что ваш второй пример, который на самом деле равен 00:30:34.537
секундам, становится 00:30:35
. Если вы предпочитаете всегда округлять в меньшую сторону, вы можете использовать floor() :
df %>%
mutate(duration_ms = seconds_to_period(floor(duration / 1000))) %>%
mutate(duration_ms = hms::hms(duration_ms))
# ID duration duration_ms
# 1 ID1 1723456 00:28:43
# 2 ID2 1834537 00:30:34
# 3 ID3 1945678 00:32:25
Я бы использовал format()
:
df = data.frame(ID = c("ID1", "ID2", "ID3"), duration = c(1723456, 1834537, 1945678))
f = \(d) format(as.POSIXct(d/1e3), "%M:%S")
f(df$duration)
#> [1] "28:43" "30:34" "32:25"
Напишите функцию для этого:
milli_to_ms <- function(milliseconds){
s = milliseconds / 1000
hm = paste0(s %/% 60,":", round(s %% 60))
hm
}
который вы затем можете протестировать:
> milli_to_ms(1000)
[1] "0:1"
> milli_to_ms(6000)
[1] "0:6"
> milli_to_ms(60000)
[1] "1:0"
это правильно? Или вам нужны ведущие нули? Перепишите, на этот раз используя sprintf
для управления размером поля и ведущими нулями:
milli_to_ms <- function(milliseconds){
s = milliseconds / 1000
return(sprintf("%02d:%02d",s %/% 60, round(s%%60)))
}
и протестируйте еще раз:
> milli_to_ms(0)
[1] "00:00"
> milli_to_ms(1)
[1] "00:00"
> milli_to_ms(1000)
[1] "00:01"
> milli_to_ms(10000)
[1] "00:10"
> milli_to_ms(100000)
[1] "01:40"
Теперь хорошо выглядишь? Затем примените к своей проблеме:
> df$duration = milli_to_ms(df$duration)
> df
ID duration
1 ID1 28:43
2 ID2 30:35
3 ID3 32:26
>
Вы могли бы сделать это с помощью mutate
, но в этом нет никакой реальной ценности, если вы можете сделать это быстрее.