我有一个包含自纪元以来的时间的文件。问题是那些时间写得像[0-9]{3}[ms|s|m]
times = c('001ms','023ms','011s','923s','001m','012m','111m')
我希望能够将其转换为"毫秒数" (或数字或秒或分钟......)。我会得到类似的东西:
c(1, 23, 11000, 923000, ...)
是否有某些功能可以让我有效地解析这些时间?
答案 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)