2012-01-19 27 views
12

Mục tiêu của tôi là tạo ra một vectơ của dấu thời gian POSIXct cho một khởi đầu, một kết thúc và một đồng bằng (15 phút, 1 giờ, 1 ngày). Tôi hy vọng tôi có thể sử dụng seq cho điều này, nhưng tôi có một vấn đề chuyển đổi giữa các đại diện số và POSIXct:seq() cho POSIXct

now <- Sys.time() 
now 
# [1] "2012-01-19 10:30:39 CET" 
as.POSIXct(as.double(now), origin="1970-01-01", tz="CET") 
# [1] "2012-01-19 09:30:39 CET" 
as.POSIXct(as.double(now), origin=as.POSIXct("1970-01-01", tz="CET"), tz="CET") 
# [1] "2012-01-19 09:30:39 CET" 

Một giờ bị mất trong quá trình chuyển đổi này. Tôi đang làm gì sai?

Trả lời

20

Có một phương pháp seq() cho các đối tượng của lớp "POSIXt" đó là lớp siêu của "POSIXlt""POSIXct" lớp. Như vậy bạn không cần thực hiện bất kỳ chuyển đổi nào.

> now <- Sys.time() 
> tseq <- seq(from = now, length.out = 100, by = "mins") 
> length(tseq) 
[1] 100 
> head(tseq) 
[1] "2012-01-19 10:52:38 GMT" "2012-01-19 10:53:38 GMT" 
[3] "2012-01-19 10:54:38 GMT" "2012-01-19 10:55:38 GMT" 
[5] "2012-01-19 10:56:38 GMT" "2012-01-19 10:57:38 GMT" 
+3

Và điều này được chỉ ra trong tài liệu hướng dẫn của seq(), nơi tôi đáng lẽ phải xem xét ở vị trí đầu tiên. Cảm ơn bạn! –

+0

xem câu trả lời của @ RichieCotton bên dưới nếu bạn cần nó theo khoảng thời gian thông thường như "10 phút" – d8aninja

3

Tôi không có câu trả lời cho vấn đề của bạn, nhưng tôi có một cách khác để tạo vectơ của các đối tượng POSIXct. Nếu, ví dụ, bạn muốn tạo một vector 1000 timestamps từ bây giờ với một delta_t 15 phút:

now = Sys.time() 
dt = 15 * 60 # in seconds 
timestamps = now + seq(0, 1000) * dt 
> head(timestamps) 
[1] "2012-01-19 11:17:46 CET" "2012-01-19 11:32:46 CET" 
[3] "2012-01-19 11:47:46 CET" "2012-01-19 12:02:46 CET" 
[5] "2012-01-19 12:17:46 CET" "2012-01-19 12:32:46 CET" 

Bí quyết là bạn có thể thêm một vector của giây đến một đối tượng POSIXct.

7

Các vấn đề múi giờ này luôn khó sử dụng, nhưng tôi nghĩ vấn đề là nguồn gốc của bạn đang được tính theo múi giờ sai (vì chuỗi chỉ chỉ định ngày tháng).

Thử sử dụng origin <- now - as.numeric(now).

Hoặc, sử dụng lubridate::origin, là chuỗi "1970-01-01 UTC".


Giải pháp đầy đủ, một lần nữa sử dụng lubridate.

start <- now() 
seq(start, start + days(3), by = "15 min") 
+0

Điều này (nguồn gốc <- now - as.numeric (now)) hoạt động, cảm ơn! –

+0

Bạn phải cẩn thận, vì điều này chỉ hoạt động khi chuyển sang ngôn ngữ hiện tại của riêng bạn. Một giải pháp tổng quát hơn được đưa ra trong câu trả lời của tôi. Ý tưởng là như nhau, nhưng độc lập với ngôn ngữ của riêng bạn. –

+1

@Richie Sử dụng ví dụ 'lubridate', tôi nhận được' chuỗi không hợp lệ cho "bằng cách" –

10

Bạn cần phải lưu ý rằng khi chuyển đổi từ POSIXct để số, R lấy múi giờ vào tài khoản nhưng luôn luôn bắt đầu đếm từ một nguồn gốc GMT:

> xgmt <- as.POSIXct('2011-01-01 14:00:00',tz='GMT') 
> xest <- as.POSIXct('2011-01-01 14:00:00',tz='EST') 
> (as.numeric(xgmt) - as.numeric(xest))/3600 
[1] -5 

Như bạn thấy, thời gian trong EST được hình thành sớm hơn năm giờ so với giờ GMT, đó là sự khác biệt về thời gian giữa cả hai múi giờ. Đó là giá trị được lưu trong nội bộ.

Hàm as.POSIXCT() chỉ thêm thuộc tính chứa múi giờ. Nó không làm thay đổi giá trị, vì vậy bạn nhận được thời gian được trình bày theo giờ GMT, nhưng với một thuộc tính cho biết đó là EST. Điều này cũng có nghĩa là khi bạn đi từ số POSIXct đến số, bạn nên xử lý dữ liệu của mình như thể là giờ GMT. (Nó phức tạp hơn rất nhiều, nhưng đó là ý tưởng chung). Vì vậy, bạn phải tính toán bù đắp như sau:

> nest <- as.numeric(xest) 
> origin <- as.POSIXct('1970-01-01 00:00:00',tz='EST') 
> offset <- as.numeric(origin) 
> as.POSIXct(nest-offset,origin=origin) 
[1] "2011-01-01 14:00:00 EST" 

Điều này làm việc bất kỳ múi giờ nào là ngôn ngữ của bạn (trong trường hợp của tôi, thực sự là CET). Cũng lưu ý rằng hành vi của dữ liệu múi giờ có thể khác nhau giữa các hệ thống.

4

Một thay thế cho việc sử dụng seq.POSIXtxts::timeBasedSeq, cho phép bạn chỉ định chuỗi là một chuỗi:

library(xts) 
now <- Sys.time() 
timeBasedSeq(paste("2012-01-01/",format(now),"/H",sep="")) # Hourly steps 
timeBasedSeq(paste("2012-01-01/",format(now),"/d",sep="")) # Daily steps 
1

Bạn cần phải sử dụng seq (từ = bắt đầu, để = kết thúc, bởi = bước).Lưu ý rằng trong bước bạn có thể sử dụng "ngày" hoặc số nguyên xác định số giây trôi qua từ mục này đến mục khác.

+0

Bạn cần phải đọc các câu trả lời khác trước khi đăng câu trả lời mới 3 năm sau đó. Điều này đã được cung cấp trong ít nhất hai câu trả lời trước đó. –

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