簡體   English   中英

滾動獨立地連接多列以消除NA

[英]Rolling Join multiple columns independently to eliminate NAs

我正在嘗試在data.table中進行滾動連接,該連接data.table多個列,但是即使存在該行,也可以滾動整個丟失的行以及特定列中的單個NA 舉例來說,我有兩個表AB

library(data.table)
A <- data.table(v1 = c(1,1,1,1,1,2,2,2,2,3,3,3,3), 
                v2 = c(6,6,6,4,4,6,4,4,4,6,4,4,4), 
                t = c(10,20,30,60,60,10,40,50,60,20,40,50,60),
                key = c("v1", "v2", "t"))

B <- data.table(v1 = c(1,1,1,1,2,2,2,2,3,3,3,3), 
                v2 = c(4,4,6,6,4,4,6,6,4,4,6,6), 
                t = c(10,70,20,70,10,70,20,70,10,70,20,70), 
                valA = c('a','a',NA,'a',NA,'a','b','a', 'b','b',NA,'b'), 
                valB = c(NA,'q','q','q','p','p',NA,'p',NA,'q',NA,'q'),
                key = c("v1", "v2", "t"))

B
##     v1 v2  t valA valB
##  1:  1  4 10    a   NA
##  2:  1  4 70    a    q
##  3:  1  6 20   NA    q
##  4:  1  6 70    a    q
##  5:  2  4 10   NA    p
##  6:  2  4 70    a    p
##  7:  2  6 20    b   NA
##  8:  2  6 70    a    p
##  9:  3  4 10    b   NA
## 10:  3  4 70    b    q
## 11:  3  6 20   NA   NA
## 12:  3  6 70    b    q

如果我進行滾動聯接(在這種情況下為向后聯接),則當在B找不到行時,它將滾動所有點,但是當該行存在但要合並的數據為NA時,它仍包括點:

B[A, , roll=-Inf]

##     v1 v2  t valA valB
##  1:  1  4 60    a    q
##  2:  1  4 60    a    q
##  3:  1  6 10   NA    q
##  4:  1  6 20   NA    q
##  5:  1  6 30    a    q
##  6:  2  4 40    a    p
##  7:  2  4 50    a    p
##  8:  2  4 60    a    p
##  9:  2  6 10    b   NA
## 10:  3  4 40    b    q
## 11:  3  4 50    b    q
## 12:  3  4 60    b    q
## 13:  3  6 20   NA   NA

我想以這樣一種方式滾動加入,即它也可以覆蓋這些NA 對於單列,我可以將B子集除去NA ,然后使用A滾動:

C <- B[!is.na(valA), .(v1, v2, t, valA)][A, roll=-Inf]

C
##     v1 v2  t valA
##  1:  1  4 60    a
##  2:  1  4 60    a
##  3:  1  6 10    a
##  4:  1  6 20    a
##  5:  1  6 30    a
##  6:  2  4 40    a
##  7:  2  4 50    a
##  8:  2  4 60    a
##  9:  2  6 10    b
## 10:  3  4 40    b
## 11:  3  4 50    b
## 12:  3  4 60    b
## 13:  3  6 20    b

但是對於多列,我必須依次執行此操作,為每個添加的列存儲值,然后重復。

B[!is.na(valB), .(v1, v2, t, valB)][C, roll=-Inf]

##     v1 v2  t valB valA
##  1:  1  4 60    q    a
##  2:  1  4 60    q    a
##  3:  1  6 10    q    a
##  4:  1  6 20    q    a
##  5:  1  6 30    q    a
##  6:  2  4 40    p    a
##  7:  2  4 50    p    a
##  8:  2  4 60    p    a
##  9:  2  6 10    p    b
## 10:  3  4 40    q    b
## 11:  3  4 50    q    b
## 12:  3  4 60    q    b
## 13:  3  6 20    q    b

上面的最終結果是所需的輸出,但是對於多列它很快變得難以處理。 有更好的解決方案嗎?

聯接是關於匹配行。 如果要以多種方式匹配行,則需要多個聯接。

我將使用循環,但將列添加到A中(而不是在每次聯接之后創建新表C,D,...):

k     = key(A)
bcols = setdiff(names(B), k)

for (col in bcols) A[, (col) :=
  B[!.(as(NA, typeof(B[[col]]))), on=col][.SD, roll=-Inf, ..col]
][]

A 

    v1 v2  t valA valB
 1:  1  4 60    a    q
 2:  1  4 60    a    q
 3:  1  6 10    a    q
 4:  1  6 20    a    q
 5:  1  6 30    a    q
 6:  2  4 40    a    p
 7:  2  4 50    a    p
 8:  2  4 60    a    p
 9:  2  6 10    b    p
10:  3  4 40    b    q
11:  3  4 50    b    q
12:  3  4 60    b    q
13:  3  6 20    b    q

B[!.(NA_character_), on="valA"]是一個防B[!.(NA_character_), on="valA"] ,可刪除valA中帶有NA的行。 上面的代碼試圖對此進行概括(因為NA需要匹配列的類型)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM