niet-joins met data.tables

Ik heb een vraag over het id-type data.table voor "niet-joins", geïnspireerd op de vraag a>. Hier is een voorbeeld:

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)

De data.table s zien er als volgt uit

> 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

Om te vinden welke rijen in dt2 dezelfde sleutel hebben in dt1 , stelt u de welke optie in op TRUE :

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

Matthew stelde in deze

antwoord , dat een" niet deelnemen "idioom is

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

om dt1 in te delen in die rijen met indexen die niet voorkomen in dt2 . Op mijn computer met data.table v1.7.1 krijg ik een foutmelding:

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

In plaats daarvan werkt de "niet-join" met de optie nomatch = 0

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

Is dit bedoeld gedrag?

14
Net toegevoegd aan v1.8.3 is de syntaxis not-join . In dit geval dt1 [! Dt2] . Zal een gedetailleerd antwoord toevoegen ...
toegevoegd de auteur Matt Dowle, de bron

3 antwoord

Nieuw in 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
17
toegevoegd

Voor zover ik weet, is dit een onderdeel van basis 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

Het tekstuele foutbericht geeft aan dat het is bedoeld gedrag.

Hier is mijn beste inschatting van waarom dat het bedoelde gedrag is:

Uit de manier waarop ze NA 's elders behandelen (bijvoorbeeld standaard instellen op na.rm = FALSE ), lijkt het erop dat de ontwerpers van R NA zien s als het dragen van belangrijke informatie, en zijn afkerig te laten vallen dat zonder enige expliciete instructie om dit te doen. (Gelukkig geeft het instellen van nomatch = 0 u een schone manier om die instructie door te geven!)

In deze context verklaart de voorkeur van de ontwerpers waarschijnlijk waarom NA 's worden geaccepteerd voor positieve indexering, maar niet voor negatieve indexering:

# 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)]
5
toegevoegd
+1 Leuk antwoord! Ja, het komt van de basis. FR # 1384 is om de X [-Y] syntaxis te maken, betekent 'niet deelnemen'. In de tussentijd is which = TRUE, nomatch = 0 nodig.
toegevoegd de auteur Matt Dowle, de bron

Nieuw in versie 1.7.3 van data.table:

Nieuwe optie datatable.nomatch staat de standaard voor nomatch toe   veranderd van NA in 0, ...

2
toegevoegd
Die verandering kan een beetje helpen, maar was niet bedoeld om echt niet mee te doen. FR # 1384 is nog te doen. Goed om te zien dat iemand NEWS leest :)
toegevoegd de auteur Matt Dowle, de bron