2011-11-03 45 views
2

外積,我需要在0:10小時過去每個原始日期時間來創建data.frame包含日期時間 - 第一個列0小時過去,第二列1小時過去等具有給定的日期時間值的矢量日期

我在使用lubridate的東西時遇到了一些麻煩。我認爲這應該工作:

rt <- ymd_hms(c("2011-11-03 19:24:12", "2011-10-28 20:48:21", 
    "2011-11-04 10:06:14", "2011-10-31 17:10:05", "2011-10-28 06:35:59")) 
result <- outer(rt, hours(0:10), "+") 

但該管道中的各個部分發生故障。最終,我得到這個錯誤:

Error in FUN(X[[1L]], ...) : invalid 'times' argument 

這似乎來自rep.POSIXct()的或rep.period()的無法處理非單位長度times說法。或者其他的東西。

它可能不會工作,因爲outer()返回一個矩陣,日期對象,甚至POSIXct日期(它們在內部只是整數),它似乎不能是矩陣中的元素。

我想通了,工作(只是爲了獲得倍,而不是把它們放在一個數據幀)後,在約10其他的猜測,是這樣的:

with_tz(do.call(c, lapply(rt, function(x) x+hours(0:3))), tz(rt[1])) 

with_tz()除了是必要的,因爲c()失去時區屬性。我還必須做do.call(c, lapply(...))而不只是sapply(...),因爲sapply()失去了它是一個日期的事實。

也許另一種選擇是通過做do.call(cbind, ...)或其他東西來創建數據幀。一般來說,如果我們發現在查找解決方案之前似乎在概念上很簡單但需要大量體操的R日期/時間任務,我們可以通過更改lubridate或其他任何方法來消除障礙。我想這可能是其中的一個。 =)

+0

我覺得@hadley會很高興,如果你提交了一個補丁到'lubridate'。你可以在這裏提交一個問題(和你的補丁代碼):https://github.com/hadley/lubridate/issues – Andrie

+0

我已經爲其他兩個問題做了實際的工作(參見https://github.com/kenahoo/lubridate /)在過去幾個月裏,@哈德利很感激,但他們沒有得到迴應。自從5月份以來,Lubridate並沒有提交任何提交,它似乎可能處於開發平靜期。 –

+0

我認爲你應該編輯標題。你已經承認外層不可能返回日期時間值。 –

回答

4

這不使用outer(),但我認爲它可以讓你在你想要的地方。它確實使用plyr

library("lubridate") 
library("plyr") 

rt <- ymd_hms(c("2011-11-03 19:24:12", "2011-10-28 20:48:21", 
    "2011-11-04 10:06:14", "2011-10-31 17:10:05", "2011-10-28 06:35:59")) 

offsets = 0:10 
names(offsets) <- offsets 

dat <- data.frame(llply(offsets, function(offset){rt+hours(offset)})) 

給予名稱爲offsets變量只是使的data.frame更好的列名。

> str(dat) 
'data.frame': 5 obs. of 11 variables: 
$ X0 : POSIXct, format: "2011-11-03 19:24:12" "2011-10-28 20:48:21" ... 
$ X1 : POSIXct, format: "2011-11-03 20:24:12" "2011-10-28 21:48:21" ... 
$ X2 : POSIXct, format: "2011-11-03 21:24:12" "2011-10-28 22:48:21" ... 
$ X3 : POSIXct, format: "2011-11-03 22:24:12" "2011-10-28 23:48:21" ... 
$ X4 : POSIXct, format: "2011-11-03 23:24:12" "2011-10-29 00:48:21" ... 
$ X5 : POSIXct, format: "2011-11-04 00:24:12" "2011-10-29 01:48:21" ... 
$ X6 : POSIXct, format: "2011-11-04 01:24:12" "2011-10-29 02:48:21" ... 
$ X7 : POSIXct, format: "2011-11-04 02:24:12" "2011-10-29 03:48:21" ... 
$ X8 : POSIXct, format: "2011-11-04 03:24:12" "2011-10-29 04:48:21" ... 
$ X9 : POSIXct, format: "2011-11-04 04:24:12" "2011-10-29 05:48:21" ... 
$ X10: POSIXct, format: "2011-11-04 05:24:12" "2011-10-29 06:48:21" ... 

UPDATE:

Ken的評論關於ldply()data.frame(llply())讓我意識到還有另一種方式來處理這個。

dat <- ldply(rt, `+`, hours(0:10)) 

這給

> str(dat) 
'data.frame': 5 obs. of 11 variables: 
$ V1 : POSIXct, format: "2011-11-03 12:24:12" "2011-10-28 13:48:21" ... 
$ V2 : POSIXct, format: "2011-11-03 13:24:12" "2011-10-28 14:48:21" ... 
$ V3 : POSIXct, format: "2011-11-03 14:24:12" "2011-10-28 15:48:21" ... 
$ V4 : POSIXct, format: "2011-11-03 15:24:12" "2011-10-28 16:48:21" ... 
$ V5 : POSIXct, format: "2011-11-03 16:24:12" "2011-10-28 17:48:21" ... 
$ V6 : POSIXct, format: "2011-11-03 17:24:12" "2011-10-28 18:48:21" ... 
$ V7 : POSIXct, format: "2011-11-03 18:24:12" "2011-10-28 19:48:21" ... 
$ V8 : POSIXct, format: "2011-11-03 19:24:12" "2011-10-28 20:48:21" ... 
$ V9 : POSIXct, format: "2011-11-03 20:24:12" "2011-10-28 21:48:21" ... 
$ V10: POSIXct, format: "2011-11-03 21:24:12" "2011-10-28 22:48:21" ... 
$ V11: POSIXct, format: "2011-11-03 22:24:12" "2011-10-28 23:48:21" ... 

需要注意的是,除了不同的列名(V1-V11,而不是X0-X10),這些日期已轉換爲本地時間(PDT,在我的情況):

> dat$V1 
[1] "2011-11-03 12:24:12 PDT" "2011-10-28 13:48:21 PDT" 
[3] "2011-11-04 03:06:14 PDT" "2011-10-31 10:10:05 PDT" 
[5] "2011-10-27 23:35:59 PDT" 
+0

謝謝,這是有效的。我是否正確地認爲你使用'data.frame(llply(...))'而不是'ldply(...)'的原因是按列而不是行重組?如果'ldply'(和其他'* dply'函數)有一個指示加入方向的參數,可能會更好。 –

+0

@KenWilliams,這是正確的。 'ldply'會將函數調用的結果(在這裏,將小時添加到rt向量中)作爲行,將它們作爲列表返回,然後調用'data.frame'使每個列表成爲列。儘管如此,您的評論確實指出了另一種方式,但是通過其他方式進行迭代。我會將其添加到答案中。 –

+0

好主意!我從來沒有想過使用'l * ply'這樣的外層產品。 –

相關問題