2012-12-28 26 views
9

Po tym artykule wikipedia SQL join chciałem mieć jasny pogląd na temat, w jaki sposób możemy mieć sprzężenia z data.table. Podczas tego procesu mogliśmy wykryć błąd podczas dołączania do NA. Biorąc przykład encyklopedii:data.table wewnętrzne/zewnętrzne sprzężenie z NA w kolumnie łączenia typu double bug?

R) X = data.table(name=c("Raf","Jon","Ste","Rob","Smi","Joh"),depID=c(31,33,33,34,34,NA),key="depID") 
R) Y = data.table(depID=c(31,33,34,35),depName=c("Sal","Eng","Cle","Mar"),key="depID") 
R) X 
    name depID 
1: Joh NA 
2: Raf 31 
3: Jon 33 
4: Ste 33 
5: Rob 34 
6: Smi 34 
R) Y 
    depID depName 
1: 31  Sal 
2: 33  Eng 
3: 34  Cle 
4: 35  Mar 

LEFT OUTER JOIN

R) merge.data.frame(X,Y,all.x=TRUE) 
    depID name depName 
1 31 Raf  Sal 
2 33 Jon  Eng 
3 33 Ste  Eng 
4 34 Rob  Cle 
5 34 Smi  Cle 
6 NA Joh <NA> 

merge.data.table nie wychodzą ten sam wynik i pokazać to, co myślę, że jest to błąd na lign 2.

R) merge(X,Y,all.x=TRUE) 
    depID name depName 
1: NA Joh  Eng 
2: 31 Raf  NA 
3: 33 Jon  Eng 
4: 33 Ste  Eng 
5: 34 Rob  Cle 
6: 34 Smi  Cle 
R) Y[X] #same -> :(
    depID depName name 
1: NA  Eng Joh 
2: 31  NA Raf 
3: 33  Eng Jon 
4: 33  Eng Ste 
5: 34  Cle Rob 
6: 34  Cle Smi 

RIGHT OUTER JOIN Wygląda samego

R) merge.data.frame(X,Y,all.y=TRUE) 
    depID name depName 
1 31 Raf  Sal 
2 33 Jon  Eng 
3 33 Ste  Eng 
4 34 Rob  Cle 
5 34 Smi  Cle 
6 35 <NA>  Mar 

R) merge(X,Y,all.y=TRUE) 
    depID name depName 
1: NA Joh  Eng 
2: 31 NA  Sal 
3: 33 Jon  Eng 
4: 33 Ste  Eng 
5: 34 Rob  Cle 
6: 34 Smi  Cle 
7: 35 NA  Mar 

wewnętrznej (naturalny) DOŁĄCZ

R) merge.data.frame(X,Y) 
    depID name depName 
1 31 Raf  Sal 
2 33 Jon  Eng 
3 33 Ste  Eng 
4 34 Rob  Cle 
5 34 Smi  Cle 
R) merge(X,Y) 
    depID name depName 
1: NA Joh  Eng 
2: 33 Jon  Eng 
3: 33 Ste  Eng 
4: 34 Rob  Cle 
5: 34 Smi  Cle 

Odpowiedz

7

Tak to wygląda jak (żenujące) nowy błąd związany do NA w kluczu. Były inne dyskusje na temat NA w kluczu, które nie były możliwe, ale nie zdawałem sobie sprawy, że może to zepsuć w ten sposób. Zbadam. Dzięki ...

#2453 NA in double key column messes up joins (NA in integer and character ok)

teraz nieruchome 1.8.7 (popełnienia 780) z wiadomości:

NA w kolumnie przyłączenia typu podwójnego może powodować zarówno X [Y], a następnie połączyć (X, Y), aby zwrócić nieprawidłowe wyniki, # 2453. Z powodu błędnego x == NA_REAL w źródle C, które powinno być ISNA (x). Obsługa podwójnych połączeń z kluczami jest stosunkowo nowym dodatkiem do data.table, ale jednak jest nieprzyjemna. Naprawiono i dodano testy. Wielkie podziękowania dla statuanta za dokładny i powtarzalny raport.

+0

jak zostało zgłoszone w poprzednim, usuniętego odpowiedź (co było naprawdę komentarzem), scalanie działa poprawnie, jeśli kolumny depID są liczbami całkowitymi. –

+0

@MatthewLundberg Ciekawe, dzięki za to. Dlaczego został usunięty, brzmi użytecznie! To by wyjaśniało, dlaczego testy go nie złapały - prawdopodobnie pomyślałbym tylko o przetestowaniu NA na liczbach całkowitych, myśląc, że NA jako podwójne nie ma znaczenia. –

+0

Nie mogę na to odpowiedzieć, ale nie wiedziałem, czy spróbujesz scalenia z liczbami całkowitymi bez podpowiedzi. Odpowiadający twierdził, że ta postać działała również, ale nie zweryfikowałem. –

2

Nawiązując do komentarzy w drugiej odpowiedzi, tak, oto dowód, że dotyczy tylko wpisać double kolumny (nA w integer i character kolumn są ok).

X = data.table(name=c("Raf","Jon","Ste","Rob","Smi","Joh"), 
       depID=as.integer(c(31,33,33,34,34,NA)),key="depID") 
Y = data.table(depID=as.integer(c(31,33,34,35)), 
       depName=c("Sal","Eng","Cle","Mar"),key="depID") 
Y[X] 
    depID depName name 
1: NA  NA Joh 
2: 31  Sal Raf 
3: 33  Eng Jon 
4: 33  Eng Ste 
5: 34  Cle Rob 
6: 34  Cle Smi 

merge.data.frame(X,Y,all.x=T) 
    depID name depName 
1 31 Raf  Sal 
2 33 Jon  Eng 
3 33 Ste  Eng 
4 34 Rob  Cle 
5 34 Smi  Cle 
6 NA Joh <NA> 

Y = data.table(depID=as.character(c(31,33,34,35)), 
       depName=c("Sal","Eng","Cle","Mar"),key="depID") 
X = data.table(name=c("Raf","Jon","Ste","Rob","Smi","Joh"), 
       depID=as.character(c(31,33,33,34,34,NA)),key="depID") 
X 
    name depID 
1: Raf 31 
2: Jon 33 
3: Ste 33 
4: Rob 34 
5: Smi 34 
6: Joh NA 
Y 
    depID depName 
1: 31  Sal 
2: 33  Eng 
3: 34  Cle 
4: 35  Mar 
str(X) 
Classes ‘data.table’ and 'data.frame': 6 obs. of 2 variables: 
$ name : chr "Raf" "Jon" "Ste" "Rob" ... 
$ depID: chr "31" "33" "33" "34" ... 
- attr(*, "sorted")= chr "depID" 
- attr(*, ".internal.selfref")=<externalptr> 

merge.data.frame(X,Y,all.x=T) 
    depID name depName 
1 31 Raf  Sal 
2 33 Jon  Eng 
3 33 Ste  Eng 
4 34 Rob  Cle 
5 34 Smi  Cle 
6 <NA> Joh <NA> 

Y[X] 
    depID depName name 
1: 31  Sal Raf 
2: 33  Eng Jon 
3: 33  Eng Ste 
4: 34  Cle Rob 
5: 34  Cle Smi 
6: NA  NA Joh 

problem został ustalony przez MATTHEW DOWLE IN V.1.8.7

1

Kilka informacji, które mogą być przydatne:

library(data.table); 

X <- data.table(name=c("Raf","Jon","Ste","Rob","Smi","Joh"),depID=c(31,33,33,34,34,NA),key="depID") 
#R) X 
    #name depID 
#1: Joh NA 
#2: Raf 31 
#3: Jon 33 
#4: Ste 33 
#5: Rob 34 
#6: Smi 34 

Y <- data.table(depID=c(31,33,34,35),depName=c("Sal","Eng","Cle","Mar"),key="depID") 
#R) Y 
    #depID depName 
#1: 31  Sal 
#2: 33  Eng 
#3: 34  Cle 
#4: 35  Mar 

################# 
#LEFT OUTER JOIN# 
################# 
LJ <- merge.data.frame(X,Y,by="depID",all.x=TRUE); #by is implicit (see ?merge.data.frame) 
#R) LJ 
    #depID name depName 
#1 31 Raf  Sal 
#2 33 Jon  Eng 
#3 33 Ste  Eng 
#4 34 Rob  Cle 
#5 34 Smi  Cle 
#6 NA Joh <NA> 

LJ2 <- Y[X]; 
#R) LJ2 
    #depID depName name 
#1: NA  NA Joh 
#2: 31  Sal Raf 
#3: 33  Eng Jon 
#4: 33  Eng Ste 
#5: 34  Cle Rob 
#6: 34  Cle Smi 

################## 
#RIGHT OUTER JOIN# 
################## 
RJ <- merge.data.frame(X,Y,by="depID",all.y=TRUE); #by is implicit (see ?merge.data.frame) 
#R) RJ 
    #depID name depName 
#1 31 Raf  Sal 
#2 33 Jon  Eng 
#3 33 Ste  Eng 
#4 34 Rob  Cle 
#5 34 Smi  Cle 
#6 35 <NA>  Mar 

RJ2 <- X[Y]; 
#R) RJ2 
    #depID name depName 
#1: 31 Raf  Sal 
#2: 33 Jon  Eng 
#3: 33 Ste  Eng 
#4: 34 Rob  Cle 
#5: 34 Smi  Cle 
#6: 35 NA  Mar 

################# 
#FULL OUTER JOIN# 
################# 
FJ <- merge.data.frame(X,Y,all=T) 
#R) FJ 
    #depID name depName 
#1 31 Raf  Sal 
#2 33 Jon  Eng 
#3 33 Ste  Eng 
#4 34 Rob  Cle 
#5 34 Smi  Cle 
#6 35 <NA>  Mar 
#7 NA Joh <NA> 

FJ2 <- merge(X,Y,all=T) 
#R) FJ2 
    #depID name depName 
#1: NA Joh  NA 
#2: 31 Raf  Sal 
#3: 33 Jon  Eng 
#4: 33 Ste  Eng 
#5: 34 Rob  Cle 
#6: 34 Smi  Cle 
#7: 35 NA  Mar 

#################### 
#NATURAL INNER JOIN# 
#################### 
IJ <- merge.data.frame(X,Y) 
#R) IJ 
    #depID name depName 
#1 31 Raf  Sal 
#2 33 Jon  Eng 
#3 33 Ste  Eng 
#4 34 Rob  Cle 
#5 34 Smi  Cle 

IJ2 <- merge(X,Y) 
#R) IJ2 
    #depID name depName 
#1: 31 Raf  Sal 
#2: 33 Jon  Eng 
#3: 33 Ste  Eng 
#4: 34 Rob  Cle 
#5: 34 Smi  Cle 


A <- data.table(time=as.POSIXct(c("10:01:01","10:01:02","10:01:04","10:01:05","10:01:02","10:01:01","10:01:01"),format="%H:%M:%S"), 
       b=c("a","a","a","a","b","c","c"), 
       d=c(1,1.9,2,1.8,5,4.1,4.2)); 
B <- data.table(time=as.POSIXct(c("10:01:01","10:01:03","10:01:00","10:01:01"),format="%H:%M:%S"),b=c("a","a","c","d"), e=c(1L,2L,3L,4L)); 
setkey(A,b,time) 
setkey(B,b,time) 


########### 
#ASOF JOIN# 
########### 
AOJ <- B[A,roll=T] 
#R) AOJ 
    #b    time e d 
#1: a 2013-01-11 10:01:01 1 1.0 
#2: a 2013-01-11 10:01:02 1 1.9 
#3: a 2013-01-11 10:01:04 2 2.0 
#4: a 2013-01-11 10:01:05 2 1.8 
#5: b 2013-01-11 10:01:02 NA 5.0 
#6: c 2013-01-11 10:01:01 3 4.1 
#7: c 2013-01-11 10:01:01 3 4.2