2015-10-20 53 views
-1

注意:我重新構造了前面的問題,如評論中所述。將時間序列數據從秒轉換爲小時意味着在R

我使用三種不同的套餐,即,dplyr,data.table和XTS彙總我秒的數據每小時平均表示。但是,令我驚訝的是,與其他兩個人相比,他們的行爲有所不同。與XTS的問題是:

  • 結果在一個額外的觀測相比其他兩種
  • 每小時平均計算比其他兩個

這裏完全不同的是你的測試目的冷凝代碼:

library(xts) 
library(data.table) 
library(dplyr) 
t2 <- as.POSIXct(seq(from = 1438367408, to = 1440959383, by = 30), origin = "1970-01-01") 
dframe <- data.frame(timestamp=t2, power=rnorm(length(t2))) 
#using xts 
x <- xts(dframe$power,dframe$timestamp) 
h1 <- period.apply(x, endpoints(x, "hours"), mean) 
h1 <- data.frame(timestamp=trunc(index(h1),'hours'), power=coredata(h1)) 
#using data.table 
h2 <- setDT(dframe)[, list(power= mean(power)) ,(timestamp= as.POSIXct(cut(timestamp, 'hours')))] 
#using dpylr 
h3 <- dframe %>% group_by(timestamp= as.POSIXct(cut(timestamp, 'hour'))) %>% summarise(power=mean(power)) 

輸出關於尺寸:

> dim(h1) 
[1] 721 2 
> dim(h2) 
[1] 720 2 
> dim(h3) 
[1] 720 2 

輸出關於每小時手段:

> head(h1) 
      timestamp  power 
1 2015-08-01 00:00:00 0.04485894 
2 2015-08-01 01:00:00 -0.02299071 
> head(h2) # equals to head(h2) 
      timestamp  power 
1: 2015-08-01 00:00:00 0.10057538 
2: 2015-08-01 01:00:00 -0.07456292 

額外觀察H1的情況下:

> tail(h1) 
       timestamp  power 
719 2015-08-30 22:00:00 0.069544538 
720 2015-08-30 23:00:00 0.011673835 
721 2015-08-30 23:00:00 -0.053858563 

顯然爲一天的最後一小時有兩個觀察。通常,應該只有一個。

我的系統信息:

> sessionInfo() 
R version 3.2.2 (2015-08-14) 
Platform: x86_64-apple-darwin13.4.0 (64-bit) 
Running under: OS X 10.10.3 (Yosemite) 

locale: 
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] dplyr_0.4.3  data.table_1.9.7 xts_0.9-7  zoo_1.7-12  

loaded via a namespace (and not attached): 
[1] lazyeval_0.1.10 magrittr_1.5 R6_2.1.1  assertthat_0.1 parallel_3.2.2 DBI_0.3.1  tools_3.2.2  
[8] Rcpp_0.12.1  grid_3.2.2  chron_2.3-47 lattice_0.20-33 

注:

  • 原始數據集可以在link
  • 找到我想要解決這個問題,因爲在我的實現方案XTS是近35倍比其餘兩個
+0

請你把這個重複的。 – 2015-10-20 06:59:51

+0

我已經提供了代碼和數據集。我還需要什麼才能使其具有可再現性 –

+0

對不起,但我不想點擊未知鏈接。 – 2015-10-20 07:02:03

回答

2

這看起來像是endpoints中的一個錯誤,因爲您的本地時區不是UTC的整小時偏移量。如果我將本地時區設置爲您的時區,我可以複製該問題。

R> Sys.setenv(TZ="Asia/Kolkata") 
R> x <- xts(dframe$power,dframe$timestamp) 
R> h <- period.apply(x, endpoints(x, "hours"), mean) 
R> head(h) 
         [,1] 
2015-08-01 00:29:31 124.9055 
2015-08-01 01:29:31 129.7197 
2015-08-01 02:29:31 139.0899 
2015-08-01 03:29:32 145.6592 
2015-08-01 04:29:32 153.6840 
2015-08-01 05:29:32 114.4809 

請注意,端點是半小時增量,而不是在小時結束時。這是因爲亞洲/加爾各答的UTC + 0530和endpoints會以UTC表示的時間進行所有計算。

您可以通過顯式設置爲POSIXct對象爲UTC時區避免這種情況。

require(xts) 
require(dplyr) 
require(data.table) 
Sys.setenv(TZ="Asia/Kolkata") 

dframe <- read.csv("~/ap601.csv",head=TRUE,sep=",") 
# set timezone on POSIXct object 
dframe$timestamp <- as.POSIXct(dframe$timestamp, tz="UTC") 

#using xts 
x <- xts(dframe$power, dframe$timestamp) 
h <- period.apply(x, endpoints(x, "hours"), mean) 
h1 <- data.frame(timestamp=trunc(index(h),'hours'), power=coredata(h)) 
# using data.table 
h2 <- setDT(dframe)[, list(power= mean(power)) ,(timestamp= cut(timestamp, 'hour'))] 
# using dplyr 
h3 <- dframe %>% group_by(timestamp= cut(timestamp, 'hour')) %>% summarise(power=mean(power)) 

all.equal(h1$power, h2$power) # TRUE 
all.equal(h1$power, h3$power) # TRUE 

這裏有一個變通,以獲得相同的結果,而不設置時區爲POSIXct列UTC。請注意,這可能不適用於夏令時(亞洲/加爾各答沒有觀察到任何夏令時)的時區。

基本上,這個想法是在計算endpoints時從當地時間減去半小時,以便底層UTC時間與小時對齊。

dframe <- read.csv("~/ap601.csv",head=TRUE,sep=",") 
dframe$timestamp <- as.POSIXct(dframe$timestamp) 

# subtract half an hour from the index when calculating endpoints 
h <- period.apply(x, endpoints(index(x)-3600*0.5, 'hours'), mean) 
h1 <- data.frame(timestamp=trunc(index(h),'hours'), power=coredata(h)) 
all.equal(h1$power, h2$power) # TRUE 
all.equal(h1$power, h3$power) # TRUE 
+0

感謝Joshua指出根本原因。但是,我無法使用UTC,因爲我的所有數據都存儲在「亞洲/加爾各答」時區。如果我使用UTC,那麼它將數據移回0530小時的時差。 –

+0

我嘗試了'endpoints(x,「minutes」,90)',但它似乎沒有正常工作。除UTC時間轉換之外是否還有其他任何修正? –

+0

@HaroonRashid:看我的編輯。這也應該工作,並且不會更改'dframe'對象中的時區。 –