根据另一个表

时间:2017-12-15 12:57:03

标签: r

我有2个tibble数据框,我正在努力调和。第一个tibble有超过一百万个观测值,前几行如下:

    data
    ID  Time(Converted to number)  
     1    23160
     1    23161
     1    23162
     1    23163
     1    23164
     1    23165
     2    24251
     2    24252

第二个tibble是一个查找表(包含已发生的特定事件的信息),简化版本如下:

     lookup_table
     ID  Event_Time  Event_Indicator Number_of_Cumulative_Events
     1    23162           1                    1
     1    23164           1                    2
     2    24255           1                    1
     2    24280           0                    1

我想在第一个tibble中创建第3列,以便显示观察时的累积事件数。因此,上例中的第3列是:

    ID  Time(Converted to number)  Number 
     1    23160                     0      
     1    23161                     0
     1    23162                     1
     1    23163                     1
     1    23164                     2
     1    23165                     2
     2    24251                     0
     2    24252                     0

由于计算时间的原因,我试图避免在数百万次观察中循环以将每个观察的时间与查找表中的Event_Time进行比较。

但是,我不知道如何在不使用循环的情况下这样做。问题是lookup_table多次包含一些ID,如果所有ID只出现在lookup_table中一次,那么我可以这样做:

     data$Event_Time <- lookup_table[match(data$ID, lookup_table$ID),"Event_Time"] 
     data$Number <- data %>% mutate(ifelse(Time >= Event_Time,1,0))

我有什么想法可以避免使用循环并为每次观察应用查找条件?谢谢。

编辑:我不是要尝试连接表,而是更多地比较lookup_table和数据表中的时间列以获取我想要的列。例如,如果我要写一个低效的循环函数,那就是:

     for (i in 1:nrow(data)) {
          data$Number[i] <- subset(lookup_table,ID == data$ID[i])[max(which
         (data$Time[i] >= lookup_table$Event_Time)), "Number_of_Cumulative_Events"]
     }

1 个答案:

答案 0 :(得分:2)

可能的解决方案是在加入后计算累积事件。请注意,使用更新连接

library(data.table)
setDT(data)[, new := 0L][setDT(lookup_table), on = .(ID, Time = Event_Time), new := Event_Indicator][
  , new := cumsum(new), by = ID][]
   ID  Time new
1:  1 23160   0
2:  1 23161   0
3:  1 23162   1
4:  1 23163   1
5:  1 23164   2
6:  1 23165   2
7:  2 24251   0
8:  2 24252   0

可替换地,

setDT(data)[setDT(lookup_table), on = .(ID, Time = Event_Time), new := Event_Indicator][
  is.na(new), new := 0][
    , new := cumsum(new), by = ID][]

将在连接后将缺失的条目设置为零。

完全不同的方法是使用滚动连接

lookup_table[, !"Event_Indicator"][data, on = .(ID, Event_Time = Time), roll = TRUE]
   ID Event_Time Number_of_Cumulative_Events
1:  1      23160                          NA
2:  1      23161                          NA
3:  1      23162                           1
4:  1      23163                           1
5:  1      23164                           2
6:  1      23165                           2
7:  2      24251                          NA
8:  2      24252                          NA

NA&#39}未被触及以供说明)