2016-06-10 34 views
-1

我有一個獨特的問題。我已經嘗試了幾個不同的東西,我會在問題本身後詳細介紹。如何快速迭代列,檢查沿途的事情(R)

問題: 對於每個用戶ID,我需要遍歷事件日期並檢查每個日期是否在下一個日期的30天之內。我有260,000條記錄,並且不重要的ID號只有一個條目。數據是這樣的:

id | date1 | date2 
1 | 2016-01-01 | 2016-02-12 

我曾嘗試:

  • 的foreach(拆出每個ID的組事件,計算,重組;跑進內存問題) 。
  • data.table,但我不知道我是否用盡了這個選項。
  • 簡要dplyr(即:

    mutate(time_btwn=abs(as.numeric(difftime(data$date,lag(data$date2,1),"days"))))) 
    
  • 和我目前正在運行的直接for循環,通過所有行迭代這是非常緩慢的,我希望我沒有做到這一點的。代碼:

    for (i in 2:nrow(data)){ 
        if (data$id[ i ] != data$id[ i - 1 ]){ 
         next 
        } else { 
         data$timebtwn[i] <- abs(as.numeric(difftime(data$date1[i], data$date2[ i - 1 ], "days"))) 
        } 
    } 
    

我已經研究過申請,並lapply,但不能完全制定出功能,插入應用或lapply,將我需要什麼(即在列1中的每個條目,在列2中檢查一行nd返回日期之間的差異,如果兩行具有相同的id)。

是否有比直線循環(或使用foreach的方式)快而且不佔用內存的快捷方式?

+2

你可以'輸入()你的數據的一個例子嗎? – effel

+0

聽起來您需要操作很多色譜柱,因此需要融化很長時間才能在單個色譜柱上進行操作。儘管如此,在這種情況下可能會很長,所以解決方法可能是適當的。 – alistaire

+0

不中斷我提到的for循環。儘管如此,這些數據實際上就是我所說的。 ID,date1,date2。對不起(如果和當它結束時,我會更新這個帖子 – user3933614

回答

1

因爲我沒有一個樣本數據集的工作,我不得不做出一個了,因此很難知道你到底是什麼後,但:

library(data.table) 
library(lubridate) 

# generate random date samples 
latemail <- function(N, st="2012/01/01", et="2015/12/31") { 
    st <- as.POSIXct(as.Date(st)) 
    et <- as.POSIXct(as.Date(et)) 
    dt <- as.numeric(difftime(et,st,unit="sec")) 
    ev <- sort(runif(N, 0, dt)) 
    rt <- as_date(st + ev) 
} 

set.seed(42) 
mydat<-data.table(id = as.character(sample.int(1000, 10000, replace =T)), 
        date1 = as_date(latemail(10000)), 
        date2 = as_date(latemail(10000))) 
setkey(mydat, id) 

mydat[, .(timebtw = abs(as.numeric(difftime(date1, date2), "days")), 
      date1 = date1, 
      date2 = date2), by = id] 

#  id timebtw  date1  date2 
#1: 1  4 2012-01-15 2012-01-11 
#2: 1  2 2012-03-21 2012-03-19 
#3: 1  9 2012-10-01 2012-10-10 
#4: 1  1 2013-08-08 2013-08-09 
#5: 1  9 2014-02-11 2014-02-02 
#---         
#9996: 999  7 2014-10-28 2014-11-04 
#9997: 999  9 2015-03-28 2015-04-06 
#9998: 999  0 2015-07-22 2015-07-22 
#9999: 999  10 2015-09-06 2015-09-16 
#10000: 999  8 2015-10-03 2015-10-11 

我得到的日期發生功能從this不錯的帖子。讓我知道這是你正在嘗試做什麼。這個例子有10,000行和999個唯一的ID。爲了說明速度:

system.time(
    mydat[, .(timebtw = abs(as.numeric(difftime(date1, date2), "days")), 
       date1 = date1, 
       date2 = date2), by = id]) 
#user system elapsed 
#0.26 0.00 0.26 
+0

這不是,我很抱歉:( 我需要找到第1行的date1和第i + 1行的date2之間的區別,並將其插入到新列的第i行中。 – user3933614

+0

我解決了這個問題!data.table實際上不是要走的路。我需要的全部是 data < - group_by(data,id)%> mutate(time_btwn = abs(as.numeric(difftime(date2,lead(date1,1),units =「days」)))) 就這樣。野生! – user3933614

+0

很高興你把它整理出來。 –