11

このウィキペディアの記事SQL 結合に従って、data.table と結合する方法を明確に理解したいと思いました。その過程で、NA に参加する際のバグを発見した可能性があります。ウィキの例を挙げる:

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.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 のバグと思われるものを表示します。

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 同じように見える

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

インナー(ナチュラル)ジョイン

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
4

3 に答える 3

8

はい、キーのNAに関連する(恥ずかしい)新しいバグのように見えます。キーのNAが不可能であるという他の議論がありましたが、私はそれがそのように混乱する可能性があることに気づいていませんでした。調査します。ありがとう ...

#2453ダブルキー列のNAが結合を台無しにする(整数と文字のNAはOK)

NEWSの1.8.7(commit 780)で修正されました:

double型の結合列のNAにより、X [Y]とmerge(X、Y)の両方が誤った結果#2453を返す可能性があります。ISNA(x)であるはずのCソースのx==NA_REALが誤っているため。キー付き結合でのダブルのサポートは、data.tableに比較的最近追加されたものですが、まったく同じように恥ずかしいものです。修正され、テストが追加されました。徹底的で再現性のあるレポートを提供してくれたstatquantに感謝します。

于 2012-12-28T23:16:59.257 に答える
3

他の回答のコメントをフォローアップします。はい、これはタイプ列にのみ影響するという証拠ですdouble(NA inintegerと列characterは問題ありません)。

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 で Matthew Dowle によって修正されました

于 2012-12-29T00:11:26.203 に答える
1

役立つ情報:

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
于 2013-01-11T10:24:29.370 に答える