[英]R- efficiently convert time in milliseconds to as.POSIXct with varying time zones
我想將具有不同時區的多個時間值轉換為POSIXct格式,當前時區從1970年1月1日開始以毫秒表示。
我有以下數據集:
times <- c(1427450400291, 1428562800616, 1418651628795, 1418651938990, 1418652348281, 1418652450161)
tzones <- c("America/Los_Angeles", "Africa/Casablanca", "Africa/Casablanca", "Africa/Casablanca", "Africa/Casablanca", "Israel Standard Time")
問題在於as.POSIXct
方法僅接受一個tz值,而不接受矢量。 因此,我不能直接調用它。 我嘗試使用lapply並逐個元素地調用它,但是這花費了很長時間(對於更長的向量):
get.dates.with.timezones <- function(epoch.vec,tz.vec) {
res <- lapply(seq(epoch.vec),function(x){
as.POSIXct(epoch.vec[x]/1000,origin = "1970-01-01", tz = tz.vec[x])
})
return(do.call(c,res))
}
因此,僅需要1200個值,就幾乎需要一秒鍾。
timesX200 <- rep(times,200)
tzonesX200 <- rep(tzones,200)
system.time( get.dates.with.timezones(timesX200,tzonesX200) )
user system elapsed
0.86800000000005184 0.01999999999999602 0.88899999999921420
我是R的新手,所以我想知道是否有方法可以提高此任務的性能。 這個問題有矢量化的選擇嗎? 此外,它看起來像as.POXIXct()
方法本身具有一定的性能問題,如顯示這里 。
----------編輯--------
顯然,不可能保存具有不同時區的POSIXct向量。 從POSIXct文檔:
在“ POSIXlt”對象上使用c可以將它們轉換為當前時區,而在“ POSIXct”對象上使用c可以刪除任何“ tzone”屬性(即使它們都標記有相同的時區)。 資源
這太糟糕了。 我想知道是否有其他選擇來處理日期+時間+時區變化。 很高興聽到是否有。
我發現這種方法要快得多。 它還輸出一個列表,其中保留了創建的時區:
f_time <- function(x,y) as.POSIXct(x/1000, origin="1970-01-01", tz=y)
s <- split(timesX200, tzonesX200)
result <- mapply(f_time, s, names(s))
您的輸出不保留時區分配。 檢查您的輸出:
get.dates.with.timezones(times, tzones)
[1] "2015-03-27 06:00:00 EDT" "2015-04-09 03:00:00 EDT"
[3] "2014-12-15 08:53:48 EST" "2014-12-15 08:58:58 EST"
[5] "2014-12-15 09:05:48 EST" "2014-12-15 09:07:30 EST"
它們都被強制到本地時區。
基准測試
times <- c(1427450400291, 1428562800616, 1418651628795, 1418651938990, 1418652348281, 1418652450161)
tzones <- c("America/Los_Angeles", "Africa/Casablanca", "Africa/Casablanca", "Africa/Casablanca", "Africa/Casablanca", "Israel")
timesX200 <- rep(times,200)
tzonesX200 <- rep(tzones,200)
get.dates.with.timezones <- function(epoch.vec,tz.vec) {
res <- lapply(seq(epoch.vec),function(x){
as.POSIXct(epoch.vec[x]/1000,origin = "1970-01-01", tz = tz.vec[x])
})
return(do.call(c,res))
}
library(microbenchmark)
microbenchmark(
get = get.dates.with.timezones(timesX200, tzonesX200),
plafort = {s <- split(timesX200, tzonesX200);mapply(f_time, s, names(s))},
times=20L)
# Unit: microseconds
# expr min lq mean median uq
# get 342693.638 362465.069 378195.687 372553.491 389080.277
# plafort 997.138 1027.731 1110.846 1107.471 1149.314
# max neval cld
# 445539.744 20 b
# 1558.473 20 a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.