2017-02-09 68 views
4

數據卷加入使NA在data.table

Usage <- structure(list(feature = c("M11", "M11", "M11", "M11", "M11", "M11", "M11"), 
         startDate = structure(c(17130, 17130, 17130, 17130,17155, 17155, 17155), class = "Date"), 
         cc = c("X6", "X6", "X6", "X6", "X6", "X6", "X6"), vendor = c("Z1", "Z1", "Z1", "Z1", "Z1","Z1", "Z1")), .Names = c("feature", "startDate", "cc", "vendor"), 
        row.names = c(NA,-7L), class = c("data.table", "data.frame")) 


Limits <- structure(list(vendorId = c("Z1", "Z1", "Z1", "Z1", "Z1", "Z1"), 
         featureId = c("M11", "M11", "M11", "M11", "M11", "M11"), 
         costcenter = c("X6", "X6", "X6", "X6", "X6", "X6"), 
         oldLimit = c(1L,2L, 3L, 4L, 5L, 6L), date = structure(c(17135, 17105, 17074, 17044, 17149, 17119), class = "Date")), 
        .Names = c("vendorId", "featureId","costcenter",  "oldLimit", "date"), row.names = c(NA, -6L), class = "data.frame") 

    setDT(Usage) 
    setDT(Limits) 

蔭試圖通過看「限制」 DT列「限制」 DT添加到「用法」。這是爲了找出在其相應使用時該「功能」,「成本中心」,「供應商」組合的限制。

但是,當我嘗試使用下面的代碼進行roll-join時,我得到了奇怪的結果。我爲我的數據獲得了大量的NAs,因此如上創建了示例數據。以下是我的roll-join代碼。

Usage[Limits, limitAtStartDate:= i.oldLimit, on=c(cc="costcenter",feature="featureId", 
            vendor="vendorId", startDate="date"), roll=T,verbose=T] 

> Usage 
    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 

爲什麼是「5」 &「6」是爲一個記錄「limitAtStartDate」?

我期待着5對所有行與日期2016年12月20日和6只全部設置2016年11月25日。請讓我知道我要多多錯了。我現在用data.table版本1.10.0。

+0

我想你是這樣做的。嘗試'限制[usage,oldLimit,on =。(costcenter = cc,featureId = feature,vendorId = vendor,date = startDate),roll = TRUE]'另外,請不要忘記'setDT(Usage); setDT(限制)' –

+0

@DavidArenburg感謝你。用適當的setDT()更新問題和結果。但我不想加入其他方式,因爲之後我不會得到正確的DT結構。 – pauljeba

+1

我給你你需要的價值。你可以把它們放回'Usage'表中。例如。 'Usage [,limitAtStartDate:=限制[usage,oldLimit,on =。(costcenter = cc,featureId = feature,vendorId = vendor,date = startDate),roll = TRUE]] –

回答

2

當執行X[Y]data.table加入你基本上在做Y是每個價值你是試圖在X中找到一個值。因此,最終的連接將會是Y s表。在你的情況下,你試圖找到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 

作爲一個側面說明,非常(有的時候不那麼)簡單的情況下,你可以只使用findInterval

setorder(Limits, date)[findInterval(Usage$startDate, date), oldLimit] 
## [1] 6 6 6 6 5 5 5 

它雖然

  • 您需要先排序的間隔矢量有一些需要注意的一個非常有效的功能。
  • 您不能設置滾動間隔容易,你會在data.table做(例如roll = 2,而不是僅僅roll = TRUE
  • 也可能是最大的缺點是,這將是棘手的執行滾動一次幾個變量加入(不涉及循環),因爲你很容易做到這一點data.table