2012-12-28 18 views
9

このwikipediaの記事に続いてSQL join私はdata.tableとの結合方法を明確にしたいと思っていました。 このプロセスでは、NAsに参加するときにバグを発見した可能性があります。 LEFT OUTERがdata.table double型の結合列にNAを含む内外結合?

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ない出力に同じ結果を行うと、私はlign 2.

上のバグと思われるものを示してJOINを

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 

:ウィキの例を取ると

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は
を登録しよ

同じ

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 

のように見えるINNER(NATURAL)はい、それはに関連した(恥ずかしい)新しいバグのように見えます

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 

答えて

7

を登録しようキーはNAです。キーのNAに関する他の議論が可能ではありませんでしたが、私はそれがそのように混乱する可能性を認識していませんでした。調査します。

NA double型の結合列がX [Y]の両方を引き起こし、マージ可能性に:今NEWSから、(780コミット)1.8.7で修正されたおかげで...

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

(X、Y)を押して間違った結果を返します。#2453 ISNA(x)であったはずのCソースの間違ったx == NA_REALが原因です。キー付き結合の倍精度浮動小数点サポートは、data.tableへの比較的最近の追加ですが、すべて同じように恥ずかしがります。固定とテストが追加されました。徹底的で再現性のあるレポートのためのstatquantに多くのおかげです。

+0

を(実際にはコメントでした)、defid列が整数の場合、マージは正しく機能します。 –

+0

@MatthewLundberg面白い、ありがとう。なぜそれが削除された、有用な音!それはテストがそれを捕まえなかった理由を説明するでしょう - 私はおそらく整数を使ってNAをテストすることを考えただけです。 –

+0

私はそれに答えることはできませんが、ヒントなしで整数でマージを試みるかどうかはわかりませんでした。回答者はキャラクターも働いていると主張しましたが、私は確認しませんでした。 –

2

は、他の回答のコメントにフォローアップ、はい、ここではそれだけで(OKですintegercharacter列でNA)double列を入力影響を及ぼすことを証明しています。

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 

問題はV.1.8.7

1

マシューDOWLE BY役に立つことができますいくつかの情報修正されました:前に、削除された答えで報告されたとおり

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