如何快速迭代列,在过程中检查内容(R)

如何快速迭代列,在过程中检查内容(R),r,loops,foreach,data.table,dplyr,R,Loops,Foreach,Data.table,Dplyr,我有一个独特的问题。我尝试了一些不同的方法,我会在解决问题后详细介绍 问题: 对于每个用户ID,我需要遍历事件日期,并检查每个日期是否在下一个日期的30天内。我有260000条记录,并且相当数量的ID只有一个条目。数据如下所示: id | date1 | date2 1 | 2016-01-01 | 2016-02-12 等等 我试过: foreach(拆分每个ID的事件集、计算、重新组合;遇到内存问题) data.table,但我不知道是否用尽了此选项 简要介绍dplyr(

我有一个独特的问题。我尝试了一些不同的方法,我会在解决问题后详细介绍

问题: 对于每个用户ID,我需要遍历事件日期,并检查每个日期是否在下一个日期的30天内。我有260000条记录,并且相当数量的ID只有一个条目。数据如下所示:

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

我试过:

  • foreach(拆分每个ID的事件集、计算、重新组合;遇到内存问题)
  • data.table,但我不知道是否用尽了此选项
  • 简要介绍dplyr(即:

  • 我目前正在运行一个直接的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" ) ) )
        }
    }
    
    for(2中的i:nrow(数据)){
    if(数据$id[i]!=数据$id[i-1]){
    下一个
    }否则{
    
    data$timebtwn[i]由于我没有样本数据集可供使用,因此我必须制作一个样本数据集,因此很难知道您到底想要什么,但是:

    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
    

    你能
    dput()吗
    您的数据示例?听起来您需要对很多列进行操作,因此需要将其融化到很长的长度,以便可以对单个列进行操作。不过,在这种情况下,很长的长度可能非常长,因此可能需要采取适当的解决方法。这可能会中断我提到的for循环。不过,数据确实是我所说的。ID,date1,date 2.抱歉:(如果它完成了,我会更新帖子。你需要一个布尔向量来说明每一行的差值是否小于或等于30吗?你可以很容易地创建一个新的date_diff列,然后检查它是否小于或等于30。你应该使有问题的代码可复制。这不是,我很抱歉:(我需要找出第一行的date1和第I+1行的date2之间的差异,并将其插入新列的第I行中。我已经解决了!data.table实际上不是解决的办法。我所需要的只是数据%mutate(time_btwn=abs(as.numeric)(difftime(date2,lead(date1,1),units=“days”))仅此而已。狂野!很高兴你解决了。
    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
    
    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