2013-12-12 24 views
3

Im新的data.table「場景」,所以我道歉,如果我的問題是簡單化的。我一直處於必須應用某些分析或某些數據子集的位置,這些數據按唯一ID分組。通常情況下,我每個唯一標識約有1,000行,包含大約30個唯一標識。所以,我被建議切換到data.table,而不是試圖找出lapply或sapply或plyr包。使用data.table來計算和格式化行之間的時間差

這裏是我喜歡的類型數據的樣本

structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), dt = structure(c(1138366975, 
1138370472, 1138374064, 1138377669, 1138381264, 1138384873, 1138388503, 
1138399312, 1138402842, 1138406507, 1138413700, 1138417261, 1138420848, 
1138424444, 1138428071, 1138431695, 1138435287, 1138438938, 1138442428, 
1138446098), class = c("POSIXct", "POSIXt"), tzone = "GMT")), .Names = c("ID", 
"dt"), row.names = c(NA, -20L), class = "data.frame") 

我轉換成data.table

X = data.table(test) 

這一套我的 「鑰匙」 是個人

setkey(X,ID) 

然後,目標是以小時(現在或者我希望會很容易)計算時差。因此,需要Time2-Time1來獲取每個連續位置BY Individual(本例中爲ID)之間的小時數和分鐘數。

X[, diff:=c(NA,diff(dt)),by = ID] 

diff命令在這裏計算它分鐘,但我想轉換/圓這幾個小時在最有效的方式,同時仍保持值作爲POSIX或時間對象。我知道我可能會創建另一列,並將差值除以60.但是我希望有一些方法可以輸入"hours""minutes"或某處。由於我不瞭解data.table如何處理時間。 我曾嘗試在data.frame中使用for循環使用difftime命令執行此操作,但它太繁瑣並且將數據鏈接回原始數據幀對我來說很混亂,因爲我對for循環不熟練。一旦我將數據轉換爲數小時,我只想選擇間隔0.5小時,然後相隔4小時,然後相隔12小時的數據。我還沒有想出如何做然而在data.table

回答

1

是不是X[, diff := c(NA,round(diff(dt)/60)),by=ID]簡單?似乎沒有時間處罰。

f1 <- function(X){return(X[, diff := {tmp = diff(dt); units(tmp) <- "hours"; c(NA, as.numeric(tmp))}, by=ID][])} 
f2 <- function(X){return(X[, diff := c(NA,round(diff(dt)/60)),by=ID])} 

library(microbenchmark) 
microbenchmark(f1(X),f2(X)) 
# Unit: milliseconds 
# expr  min  lq median  uq  max neval 
# f1(X) 4.676918 4.772861 5.233032 5.324829 7.387008 100 
# f2(X) 4.615325 4.854294 5.161371 5.383165 7.147151 100 
+0

我也想到了這一點,但如果可能的話,我想保留它的屬性作爲「時間」對象。下一次我想知道這些地點之間發生了多少天或幾個月。這種方法肯定有效,只是不容易轉換成其他測量單位 – Kerry

2

下面是做這件事,概率不是最有效的,但...

X[ , diff := c(NA_character_ , difftime(tail(dt , -1) , head(dt , -1) , units = "hours")) , by = ID ] 
# ID    V1 
# 1: 1    NA 
# 2: 1 0.971388888888889 
# 3: 1 0.997777777777778 
# 4: 1 1.00138888888889 
# 5: 2    NA 
+0

你能解釋爲什麼你必須引用'tail(dt,-1)'和頭版嗎?我不明白爲什麼這會起作用。我不清楚爲什麼你必須參考「最後」或尾巴,但不是最後一個(-1)?另外,什麼是NA_character_?這是一個命令還是指向其他東西? – Kerry

+0

另外,當我運行這個命令時,它似乎產生一個「新」表?不確定,但基本上它不會簡單地添加一個額外的列到data.table的結尾?我嘗試添加類似'X $ timediff <-X [,c(NA_character_,difftime(tail,dt,-1),head(dt,-1),units =「hours」)),by = ID] '並得到一個錯誤消息,新的信息列更像是一個與1變量相關的3個新元素的列表。很混亂。 – Kerry

+0

@Kerry你很混亂'data.frame'和'data.table'語法。不要做'X $ timediff < - ...'。 'X [,c(NA_character_,...''是正確的,運行它,然後看看'X',你會看到一個新的列,'NA_character_就是'NA'的字符版本將結果強制轉換爲「字符」向量,否則'data.table'會抱怨數據類型(數字和字符)不匹配 –