【问题标题】:How to Efficiently Update data.table Conditional on a Related Entry in the data.frame Existing?如何有效地更新 data.table 条件上的相关条目 data.frame 现有?
【发布时间】:2018-09-13 21:59:32
【问题描述】:

考虑data.table,dt

   id boro block       date
 1:  1    1     1 01/01/1991
 2:  1    1     2 01/01/1991
 3:  1    2     3 01/01/1991
 4:  1    2     4 01/01/1991
 5:  2    1     1 01/01/1992
 6:  2    1     2 01/01/1992
 7:  2    2     3 01/01/1992
 8:  2    2     5 01/01/1992
 9:  3    1     1 01/01/1993
10:  3    1     2 01/01/1993
11:  3    2     6 01/01/1993
12:  3    2     7 01/01/1993

我想要高效地做的(我有 1900 万行,70 列),是对于每一行,检查dt 中是否存在 id+1、boro、block 条目。如果是这样,请创建一个新列end_date,其中包含 id+1、boro、块条目的日期。我

每一行的代码类似于:

update_end_date <- function(dt,Id,Boro,Block) {
  if (dt[id==(Id+1) & boro==Boro & block==Block,.N]==1) {
    return(dt[id==(Id+1) & boro==Boro & block==Block,date])
  }
}

我使用以下方法在行上迭代函数:

dt[,end_date := update_end_date(dt,id,boro,block), by = seq_len(nrow(dt))]

结果表将是:

    id boro block       date   end_date
 1:  1    1     1 01/01/1991 01/01/1992
 2:  1    1     2 01/01/1991 01/01/1992
 3:  1    2     3 01/01/1991 01/01/1992
 4:  1    2     4 01/01/1991         NA
 5:  2    1     1 01/01/1992 01/01/1993
 6:  2    1     2 01/01/1992 01/01/1993
 7:  2    2     3 01/01/1992         NA
 8:  2    2     5 01/01/1992         NA
 9:  3    1     1 01/01/1993         NA
10:  3    1     2 01/01/1993         NA
11:  3    2     6 01/01/1993         NA
12:  3    2     7 01/01/1993         NA

这可行,但速度非常慢。根据我的观察,它在 80 秒内循环了 100 多行,因此运行 1900 万行需要花费我无数的时间。我是 R 的新手,所以一定有更好的解决方案我不知道。

【问题讨论】:

    标签: r performance data.table


    【解决方案1】:

    使用连接而不是行循环应该更快:

    dat[, idp1 := id + 1]
    dat[dat, on=c("idp1"="id","boro","block"), end_date := i.date]
    dat
    
    #    id boro block       date idp1   end_date
    # 1:  1    1     1 01/01/1991    2 01/01/1992
    # 2:  1    1     2 01/01/1991    2 01/01/1992
    # 3:  1    2     3 01/01/1991    2 01/01/1992
    # 4:  1    2     4 01/01/1991    2         NA
    # 5:  2    1     1 01/01/1992    3 01/01/1993
    # 6:  2    1     2 01/01/1992    3 01/01/1993
    # 7:  2    2     3 01/01/1992    3         NA
    # 8:  2    2     5 01/01/1992    3         NA
    # 9:  3    1     1 01/01/1993    4         NA
    #10:  3    1     2 01/01/1993    4         NA
    #11:  3    2     6 01/01/1993    4         NA
    #12:  3    2     7 01/01/1993    4         NA
    

    【讨论】:

    • 哇,花了大约一秒钟!太棒了!
    猜你喜欢
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多