2012-12-28 7 views
9

In seguito a questo articolo di wikipedia SQL join volevo avere una visione chiara su come potremmo aver aderito con data.table. Durante il processo potremmo aver scoperto un bug quando ci si è uniti a NA. Prendendo l'esempio wiki:data.table inner/outer join with NA nella colonna join di tipo 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 no uscita lo stesso risultato e mostrare quello che penso è un bug su 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 Sembra che lo stesso

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 

INTERNO (naturale) ENTRA

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 

risposta

7

Sì Sembra un (imbarazzante) nuovo bug relativo alla NA in chiave. Ci sono state altre discussioni su NA in chiave non possibile, ma non mi ero reso conto che avrebbe potuto rovinare in quel modo. Indagherà. Grazie ...

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

Ora fissato 1.8.7 (commit 780), dalle notizie:

NA di una colonna di collegamento di tipo double potrebbero causare sia X [Y] e unire (X, Y) per restituire risultati errati, # 2453. A causa di un errante x == NA_REAL nella sorgente C che avrebbe dovuto essere ISNA (x). Il supporto per il doppio in join con chiave è un'aggiunta relativamente recente a data.table, ma imbarazzante lo stesso. Risolti e test aggiunti. Mille grazie a statuaria per il rapporto completo e riproducibile.

+0

Come è stato riportato in una precedente risposta, cancellato (che era davvero un commento), l'unione funziona correttamente se le colonne depID sono numeri interi. –

+0

@MatthewLundberg Interessante, grazie. Perché è stato cancellato, sembra utile! Questo spiegherebbe perché i test non l'hanno colto - probabilmente avrei solo pensato di testare NA con interi pensando che NA come doppio non avrebbe fatto la differenza. –

+0

Non posso rispondere, ma non sapevo se avresti provato l'unione con interi senza il suggerimento. Il rispondente ha affermato che il personaggio ha funzionato anche, ma non ho verificato. –

2

Facendo seguito a commenti in altra risposta, sì, qui è la prova che colpisce solo digitare double colonne (NA di integer e character colonne sono 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 

IL problema è stato risolto DI MATTHEW Dowle IN V.1.8.7

1

Alcune informazioni che possono essere utili:

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