2015-11-04 52 views
2

我有一個文件包含時代以來的時代。問題是,那個時代是這樣寫[0-9]{3}[ms|s|m]如何解析一個不同單位的矢量爲毫秒?

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

我希望能夠改造它「米利斯數」(或數量或幾秒或幾分鐘...)。我會得到這樣的:

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

有一些功能,這將使我能夠有效地分析這些時間?

回答

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

這是一個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)