如何将不同单位的向量解析为毫秒?

时间:2015-11-04 22:28:26

标签: r

我有一个包含自纪元以来的时间的文件。问题是那些时间写得像[0-9]{3}[ms|s|m]

times = c('001ms','023ms','011s','923s','001m','012m','111m')

我希望能够将其转换为"毫秒数" (或数字或秒或分钟......)。我会得到类似的东西:

c(1, 23, 11000, 923000, ...)

是否有某些功能可以让我有效地解析这些时间?

2 个答案:

答案 0 :(得分:5)

您可以使用查找向量。

## create a conversion lookup vector
converter <- c(ms = 1, s = 1e3, m = 1e3*60)
## get the units from the 'times' vector
units <- sub("[^a-z]+", "", times)
## get the numerics from the 'times' and convert them
as.vector(converter[units]) * as.numeric(sub("[a-z]+$", "", times))
# [1]     1      23   11000  923000   60000  720000 6660000 

as.vector()仅用于删除转换器查找遗留的名称。上面的代码为您提供毫秒转换。要转换为秒,只需将转换器除以1000。

as.vector((converter/1e3)[units]) * as.numeric(sub("[a-z]+$", "", times))
# [1]    0.001    0.023   11.000  923.000   60.000  720.000 6660.000

当然你也可以在转换器向量中使用s = 1,然后转向其他方式,即通话。

如果你想要一个功能,你可以用上面的代码自己动手。包括units参数,我们可以指定我们希望单位在结果中的位置。

convert <- function(x, units = "ms") {
    conv <- c(ms = 1, s = 1e3, m = 1e3*60)
    div <- if(units == "s") 1e3 else if(units == "m") 1e3*60 else 1
    as.vector((conv/div)[sub("[^a-z]+", "", x)] * as.numeric(sub("[a-z]+$", "", x)))
}
## milliseconds
convert(times)
# [1]       1      23   11000  923000   60000  720000 6660000
## seconds
convert(times, "s")
# [1]    0.001    0.023   11.000  923.000   60.000  720.000 6660.000
## minutes
convert(times, "m")
# [1] 1.666667e-05 3.833333e-04 1.833333e-01 1.538333e+01 1.000000e+00 1.200000e+01 1.110000e+02

它也适用于十进制值,并且在效率方面也表现得相当不错。

convert(c("10.45ms", "1.32s"))
# [1]   10.45 1320.00
convert(c("10.45ms", "1.32s"), "s")
# [1] 0.01045 1.32000

x <- rep(times, 1e4)
library(microbenchmark)
microbenchmark(ms = convert(x), s = convert(x, "s"), m = convert(x, "m"))
# Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval
#    ms 106.9894 108.7634 111.6799 109.1281 110.5011 167.4422   100
#     s 107.0723 108.8816 113.4689 109.1957 110.6959 163.7447   100
#     m 107.1299 108.9235 113.6086 109.2279 110.9650 164.1910   100

答案 1 :(得分:1)

这是一种dplyr / tidyr方法。

library(dplyr)
library(tidyr)
library(rex)

units = data_frame(
  unit = c("ms", "s", "m"),
  conversion = c(1/1000, 1, 60) )

data_frame(time = times) %>%
  extract(time, 
          c("value", "unit"), 
          rex(capture(any_digits), capture(any_letters))) %>%
  left_join(units) %>%
  mutate(value = as.numeric(value),
         converted_value = value*conversion)