2011-10-27 8 views
14

Mam pytanie na temat idiomu data.table dla "non-joins", zainspirowane przez Iterator: question. Oto przykład:niezłączenia z data.tables

library(data.table) 

dt1 <- data.table(A1=letters[1:10], B1=sample(1:5,10, replace=TRUE)) 
dt2 <- data.table(A2=letters[c(1:5, 11:15)], B2=sample(1:5,10, replace=TRUE)) 

setkey(dt1, A1) 
setkey(dt2, A2) 

W data.table s wyglądać następująco

> dt1    > dt2 
     A1 B1    A2 B2 
[1,] a 1   [1,] a 2 
[2,] b 4   [2,] b 5 
[3,] c 2   [3,] c 2 
[4,] d 5   [4,] d 1 
[5,] e 1   [5,] e 1 
[6,] f 2   [6,] k 5 
[7,] g 3   [7,] l 2 
[8,] h 3   [8,] m 4 
[9,] i 2   [9,] n 1 
[10,] j 4   [10,] o 1 

Aby dowiedzieć się, jakie wiersze w dt2 mają ten sam klucz dt1 ustaw which opcja TRUE:

> dt1[dt2, which=TRUE] 
[1] 1 2 3 4 5 NA NA NA NA NA 

Matthew zasugerował w tym answer, że "non join" idiom

dt1[-dt1[dt2, which=TRUE]] 

do podzbioru dt1 do tych wierszy, które mają indeksy, które nie pojawiają się w dt2. Na moim komputerze z data.table v1.7.1 pojawia się błąd:

Error in `[.default`(x[[s]], irows): only 0's may be mixed with negative subscripts 

Zamiast tego, z opcją nomatch=0, że "non join" działa

> dt1[-dt1[dt2, which=TRUE, nomatch=0]] 
    A1 B1 
[1,] f 2 
[2,] g 3 
[3,] h 3 
[4,] i 2 
[5,] j 4 

Czy to ma zachowanie?

+2

Właśnie dodana do v1.8.3 jest składnia _not-join_. W tym przypadku 'dt1 [! Dt2]'. Czy doda szczegółową odpowiedź ... –

Odpowiedz

5

O ile mi wiadomo, jest to częścią bazową R.

# This works 
(1:4)[c(-2,-3)] 

# But this gives you the same error you described above 
(1:4)[c(-2, -3, NA)] 
# Error in (1:4)[c(-2, -3, NA)] : 
# only 0's may be mixed with negative subscripts 

tekstowy komunikat o błędzie wskazuje, że jest przeznaczone zachowanie.

Oto mój najlepszy przypuszczenie, aby dlaczego że jest to zamierzone zachowanie:

Od sposób traktują NA „s gdzie indziej (np typowo zalegających do na.rm=FALSE), wydaje się, że projektanci R widoku NA” s jako niosą ważne informacje i nie zrażą się nimi, bez wyraźnych instrukcji, aby to zrobić. (Na szczęście, ustawienie nomatch=0 daje czysty sposób przekazać tę instrukcję razem!)

W tym kontekście, projektantów preferencji prawdopodobnie wyjaśnia, dlaczego NA „s przyjmowane są do pozytywnego indeksowania, ale nie dla negatywnej indeksowania:

# Positive indexing: works, because the return value retains info about NA's 
(1:4)[c(2,3,NA)] 

# Negative indexing: doesn't work, because it can't easily retain such info 
(1:4)[c(-2,-3,NA)] 
+1

+1 Dobra odpowiedź! Tak, jest z bazy. [FR # 1384] (https://r-forge.r-project.org/tracker/index.php?func=detail&aid=1384&group_id=240&atid=978) polega na tworzeniu składni "X [-Y]" Przystąpić'. W międzyczasie potrzebujemy 'which = TRUE, nomatch = 0'. –

2

nowego w wersji 1.7.3 data.table:

New option datatable.nomatch allows the default for nomatch to be changed from NA to 0, ...

+3

Ta zmiana może trochę pomóc, ale nie była przeznaczona do "nie dołączania". [FR # 1384] (https://r-forge.r-project.org/tracker/index.php?func=detail&aid=1384&group_id=240&atid=978) jest nadal do zrobienia.Dobrze widzieć, że ktoś czyta NEWS chociaż :) –

17

nowego w v1.8.3:

A new "!" prefix on i signals 'not-join' (a.k.a. 'not-where'), #1384. 
    DT[-DT["a", which=TRUE, nomatch=0]] # old not-join idiom, still works 
    DT[!"a"]        # same result, now preferred. 
    DT[!J(6),...]       # !J == not-join 
    DT[!2:3,...]       # ! on all types of i 
    DT[colA!=6L | colB!=23L,...]   # multiple vector scanning approach 
    DT[!J(6L,23L)]      # same result, faster binary search 
'!' has been used rather than '-' : 
    * to match the 'not-join' and 'not-where' nomenclature 
    * with '-', DT[-0] would return DT rather than DT[0] and not be backwards 
    compatibile. With '!', DT[!0] returns DT both before (since !0 is TRUE in 
    base R) and after this new feature. 
    * to leave DT[+...] and DT[-...] available for future use