我有一個有點大的數據集(784,932行/項目,27,492唯一ID)。在每個ID每個項目,我試圖創建一個虛擬變量等於1,如果日期之間的差小於60秒。R:如何快速轉換子集的子集(優化或替代`ddply`)?
程式化的數據和代碼:
ID <- c(1,1,1,1,1,1,3,3,3,3,3,3)
Item <- c(10,10,10,20,20,20,10,20,10,10,10,20)
Date <- c("19/11/13 18:58:00","19/11/13 18:58:21","19/11/13 20:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 18:58:00","19/11/13 19:58:00")
df <- data.frame(ID, Item, Date)
df <- df[order(ID, Date), ]
df[, "Date"] = lapply(df["Date"],function(x){strptime(x, "%d/%m/%y %H:%M:%S")})
# less than 60 sec difference = 1 (first item set to 999 -> 0)
fnDummy <- function(date) { ifelse(c(999, diff(date))<60, 1, 0) }
library(plyr)
ddply(df, .(ID, Item), transform, Dummy=fnDummy(Date))
輸出:
ID Item Date Dummy
1 1 10 2013-11-19 18:58:00 0
2 1 10 2013-11-19 18:58:21 1
3 1 10 2013-11-19 20:58:00 0
4 1 20 2013-11-19 18:58:00 0
5 1 20 2013-11-19 18:58:00 1
6 1 20 2013-11-19 18:58:00 1
7 3 10 2013-11-19 18:58:00 0
8 3 10 2013-11-19 18:58:00 1
9 3 10 2013-11-19 18:58:00 1
10 3 10 2013-11-19 18:58:00 1
11 3 20 2013-11-19 18:58:00 0
12 3 20 2013-11-19 19:58:00 1
從你看到第一行和第二行有共同的編號和項目的輸出,在日期的差別只有21秒,所以僞是1。第二排和第三排也有共同的編號和項目,但這裏日期的差值小於60秒大得多,所以假爲0
我設法日我想要的輸出,但操作很慢。對於1000行,大約需要40秒(參見下面的system.time
結果)。這對應於約。 180分鐘的整個數據集(我的電腦耗盡內存並在此之前很久崩潰)。
user system elapsed
36.485 3.328 39.800
如何使此操作更快?我可以使用data.table
完成相同的輸出嗎?速度更快嗎?
爲什麼你使用'ifelse'? 'c(FALSE,diff(date)<60)'應該就足夠了。如果你真的需要0和1,請使用'as.integer'。 – Roland
我意識到你已經得到了答案,但我有點困惑。你問題中的代碼甚至不會爲我運行。我在'ddply'行發生錯誤。 – joran