【问题标题】:R roll using dates not allowed?不允许使用日期滚动?
【发布时间】:2018-09-13 15:43:53
【问题描述】:

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

> 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" 代表 S_01"2018-01-08" 代表 S_02 和之前相应的最后一次商店访问是 "2018-01-11" 代表 S_01 (最后在 "2018-01-15" 之前)和"2018-01-07"S_02(最后在"2018-01-08" 之前)。

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

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

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_churchtest_shop 的键都设置为c('subject','date'),也会发生同样的事情。

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

【问题讨论】:

  • 你的意思是on=c("subject", "date")
  • 我想我以前也遇到过这个问题。尝试将所有日期转换为数字 - 连接应该可以工作 - 然后你可以将它们转换回 Date
  • @Frank 我这样做了,但随后得到一个错误,即连接列不是整数、双精度或字符...
  • ...我认为这与@C8H10N4O2 提到(并解决)的问题相同。加入的结果是一样的。
  • 也许当你尝试它时,你把日期放在主题之前——只有 on= 表达式中的最后一列是“滚动”的,这就是它需要订购的原因

标签: r join data.table


【解决方案1】:

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

#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

【讨论】:

  • 非常感谢!我在两列上都尝试了连接,但出现了一个错误,即连接列需要是整数或字符(主题两者都不是)。现在将在更大的数据集上进行尝试。我不确定我是否理解first_church 行。这会和setorder(church,'subject') 一样吗?
  • 你能分享一下这两列的‘str’吗?
  • 好的,我已经把它们放在帖子里了。
  • 你能先把你的主题列转换成字符类吗?你可以使用 as.character
猜你喜欢
  • 2021-11-07
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多