首页 > 解决方案 > 不允许使用日期滚动?

问题描述

为了创建一张桌子,我需要将人们对一个地方(比如教堂)的访问与对另一个地方(比如商店)的访问进行匹配。在这个简化的例子中,我需要找出人们第一次去教堂的时间,以及每次去教堂之前他们去商店的最后一次时间。所以给定

> test_church=data.table(subject=as.factor(c('S_01','S_01','S_02','S_02')),
    date=as.Date(c('2018-01-15','2018-01-29','2018-01-08','2018-01-22')),
    key='subject')

> test_shop=data.table(subject=as.factor(c('S_01','S_02','S_01','S_02',
                                         'S_01','S_02','S_01','S_02')),
                     date=as.Date(c('2018-01-03','2018-01-7',
                                    '2018-01-11','2018-01-14',
                                    '2018-01-17','2018-01-20',
                                    '2018-01-23','2018-01-26')),
                     key='subject')

> str(test_church)
Classes ‘data.table’ and 'data.frame':  4 obs. of  2 variables:
 $ subject: Factor w/ 2 levels "S_01","S_02": 1 1 2 2
 $ date   : Date, format: "2018-01-15" "2018-01-29" ...
 - attr(*, "sorted")= chr "subject"
 - attr(*, ".internal.selfref")=<externalptr> 
> str(test_shop)
 Classes ‘data.table’ and 'data.frame': 8 obs. of  2 variables:
 $ subject: Factor w/ 2 levels "S_01","S_02": 1 1 1 1 2 2 2 2
 $ date   : Date, format: "2018-01-03" "2018-01-11" ...
 - attr(*, "sorted")= chr  "subject" "date"
 - attr(*, ".internal.selfref")=<externalptr> 

我正在寻找的教堂参观是"2018-01-15"forS_01"2018-01-08"forS_02以及相应的最后一次商店参观是"2018-01-11"for S_01(last before "2018-01-15") 和"2018-01-07"for S_02(last before "2018-01-08")。

我的实际表要大得多(这就是我想使用 data.table 函数的原因),但相关的列是subjectand date

我发现的每个主题的第一次教堂访问

first_church = test_church[ J(unique(subject)), on = 'subject', mult = 'first' ]

但是当我想找到相应的商店访问时

church_shop = test_shop[ first_church, on='date', roll=T ]

我明白了

> church_shop
   subject       date i.subject
1:    S_02 2018-01-15      S_01
2:    S_02 2018-01-08      S_02

因此,我没有找到正确访问的日期,而是在我的新表中获得了一个甚至不正确的主题列表!(S_02不做任何事情"2018-01-15")。first_church如果我将两者的键设置为和test_shop,也会发生同样的事情c('subject','date')

有没有办法通过连接来做到这一点,或者我应该只写一个 for 循环?

标签: rjoindata.table

解决方案


添加什么应该是获得第一次教堂访问的更快方法并结合弗兰克的评论以获得您想要的输出:

#get first church visit
setorder(test_church, subject, date)
first_church <- test_church[test_church[, .I[1L], by=.(subject)]$V1]

#rolling join with Frank's fix
test_shop[first_church, .(x.subject, x.date), on=c("subject", "date"), roll=TRUE]

输出:

   x.subject     x.date
1:      S_01 2018-01-11
2:      S_02 2018-01-07

推荐阅读