2015-09-30 21 views
5

Tôi có một cột của tem thời gian ở định dạng nhân vật trông như thế này:Đọc dữ liệu timestamp trong R từ nhiều múi giờ

2015-09-24 06:00:00 UTC

2015-09- 24 05:00:00 UTC

dateTimeZone <- c("2015-09-24 06:00:00 UTC","2015-09-24 05:00:00 UTC") 

tôi muốn chuyển đổi nhân vật này dữ liệu vào dữ liệu thời gian sử dụng POSIXct, và nếu tôi biết rằng tất cả các tem thời gian được tính theo giờ UTC trong, tôi sẽ làm điều đó như thế này:

dateTimeZone <- asPOSIXct(dateTimeZone, tz="UTC") 

Tuy nhiên, tôi không nhất thiết phải biết rằng tất cả các tem thời gian là ở UTC, vì vậy tôi cố gắng

dateTimeZone <- asPOSIXct(dateTimeZodateTimeZone, format = "%Y-%m-%d %H:%M:%S %Z") 

Tuy nhiên, do strptime hỗ trợ% Z chỉ dành cho đầu ra, điều này sẽ trả về lỗi sau:

Error in strptime(x, format, tz = tz) : use of %Z for input is not supported

Tôi đã kiểm tra tài liệu cho gói lubridate và tôi không thể thấy rằng nó xử lý vấn đề này khác với POSIXct.

Tùy chọn duy nhất của tôi là kiểm tra múi giờ của mỗi hàng và sau đó sử dụng múi giờ thích hợp với một số thông tin như sau?

temp[grepl("UTC",datetimezone)] <- as.POSIXct(datetimezone, tz="UTC") 
temp[grepl("PDT",datetimezone)] <- as.POSIXct(datetimezone, tz="America/Los_Angeles") 

Trả lời

4

Bạn có thể đến đó bằng cách kiểm tra từng hàng và xử lý tương ứng, sau đó đưa mọi thứ trở lại thời gian UTC nhất quán. (#edited đến nay bao gồm phù hợp với các chữ viết tắt múi giờ để các đặc điểm kỹ thuật đầy đủ múi giờ)

dates <- c(
    "2015-09-24 06:00:00 UTC", 
    "2015-09-24 05:00:00 PDT" 
) 

#extract timezone from dates 
datestz <- vapply(strsplit(dates," "), tail, 1, FUN.VALUE="") 

## Make a master list of abbreviation to 
## full timezone names. Used an arbitrary summer 
## and winter date to try to catch daylight savings timezones. 

tzabbrev <- vapply(
    OlsonNames(), 
    function(x) c(
    format(as.POSIXct("2000-01-01",tz=x),"%Z"), 
    format(as.POSIXct("2000-07-01",tz=x),"%Z") 
), 
    FUN.VALUE=character(2) 
) 
tmp <- data.frame(Olson=OlsonNames(), t(tzabbrev), stringsAsFactors=FALSE) 
final <- unique(data.frame(tmp[1], abbrev=unlist(tmp[-1]))) 

## Do the matching: 
out <- Map(as.POSIXct, dates, tz=final$Olson[match(datestz,final$abbrev)]) 
as.POSIXct(unlist(out), origin="1970-01-01", tz="UTC") 
# 2015-09-24 06:00:00 UTC 2015-09-24 05:00:00 PDT 
#"2015-09-24 06:00:00 GMT" "2015-09-24 12:00:00 GMT" 
0

Một giải pháp data.table:

library(data.table) 

data <- data.table(dateTimeZone=c("2015-09-24 06:00:00 UTC", 
            "2015-09-24 05:00:00 America/Los_Angeles")) 
data[, timezone:=tstrsplit(dateTimeZone, split=" ")[[3]]] 
data[, datetime.local:=as.POSIXct(dateTimeZone, tz=timezone), by=timezone] 
data[, datetime.utc:=format(datetime.local, tz="UTC")] 

Điều quan trọng là để phân chia các dữ liệu trên các lĩnh vực múi giờ để bạn có thể cấp từng bộ múi giờ cho as.POSIXct riêng biệt (tôi không thực sự chắc chắn tại sao as.POSIXct sẽ không cho phép bạn cung cấp cho nó một vectơ múi giờ, thực sự). Ở đây tôi sử dụng cú pháp kết hợp phân chia áp dụng hiệu quả của data.table, nhưng bạn có thể áp dụng cùng một ý tưởng chung với cơ sở R hoặc sử dụng dplyr.

Các vấn đề liên quan