簡體   English   中英

R-在不同時區有效地將毫秒轉換為as.POSIXct

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM