Roll join在data.table中提供NA

pau*_*eba 6 r data.table

样本数据:

Usage = data.table(
  feature = 'M11', 
  startDate = structure(rep(17130, 17155, c(4, 3)), class = "Date"), 
  cc = 'X6', vendor = 'Z1'
)
Limits = data.table(
  vendorId = 'Z1',
  featureId = 'M11', 
  costcenter ='X6', oldLimit = 1:6, 
  date = structure(17044 + c(91, 61, 30, 0, 105, 75), class = "Date")
)
Run Code Online (Sandbox Code Playgroud)

我试图添加一列limitUsage data.table通过查看Limits data.table.这是找出究竟是什么的限制feature,costCenter,vendor在其相应的使用时间组合.

但是当我尝试使用下面的代码进行滚动连接时,我得到了奇怪的结果.NA我的数据很多,所以我们创建了如上所示的样本数据.下面是我的滚动加入代码.

Usage[Limits, limitAtStartDate:= i.oldLimit,   
      on = c(cc="costcenter", feature="featureId",
             vendor="vendorId", startDate="date" ), 
      roll=TRUE, verbose=TRUE][] 
#    feature  startDate cc vendor limitAtStartDate
# 1:     M11 2016-11-25 X6     Z1                6
# 2:     M11 2016-11-25 X6     Z1               NA
# 3:     M11 2016-11-25 X6     Z1               NA
# 4:     M11 2016-11-25 X6     Z1               NA
# 5:     M11 2016-12-20 X6     Z1                5
# 6:     M11 2016-12-20 X6     Z1               NA
# 7:     M11 2016-12-20 X6     Z1               NA
Run Code Online (Sandbox Code Playgroud)

这是为什么56正在为一个记录只设置limitAtStartDate

我希望5所有行都有日期2016-12-206所有2016-11-25.请让我知道我哪里出错了.我正在使用data.table版本1.10.0.

Dav*_*urg 3

当执行X[Y]连接时,data.table您基本上所做的就是为中的每个值Y尝试查找 中的值X。因此,生成的连接将具有Ys 表的长度。Limits在你的例子中,你试图为每个值找到一个值Usage并获得一个 7 长度的向量。因此,您可能应该以相反的方式加入,然后将其存储回Limits

Limits[Usage, 
       oldLimit, 
       on = .(costcenter = cc, featureId = feature, vendorId = vendor, date = startDate),
       roll = TRUE]
## [1] 6 6 6 6 5 5 5
Run Code Online (Sandbox Code Playgroud)

作为旁注,对于非常(有时不是那么)简单的情况,您可以只使用findInterval.

setorder(Limits, date)[findInterval(Usage$startDate, date), oldLimit]
## [1] 6 6 6 6 5 5 5
Run Code Online (Sandbox Code Playgroud)

这是一个非常有效的函数,但有一些注意事项

  • 您需要首先对间隔向量进行排序。
  • 您无法像在data.table(例如roll = 2而不只是roll = TRUE)中那样轻松设置滚动间隔
  • 最大的缺点可能是同时对多个变量执行滚动连接(不涉及循环)会很棘手,就像您可以轻松做到的那样data.table