2011-10-27 16 views
14

Tengo una pregunta sobre el data.table idioma para "non-joins", inspirado en Iterator's question. He aquí un ejemplo:no se une con 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) 

Los data.table s ven así

> 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 

Para saber qué filas en dt2 tienen la misma clave en dt1, establece la which opción de TRUE:

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

Matthew sugirió en este answer, que una expresión "sin unión"

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

al subconjunto dt1 a las filas que tienen índices que no aparecen en dt2. En mi máquina con data.table v1.7.1 consigo un error:

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

En cambio, con la opción nomatch=0, los "no se unen" funciona

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

¿Es este comportamiento destinado?

+2

Acaba de agregarse a v1.8.3 la sintaxis _not-join_. En este caso, 'dt1 [! Dt2]'. Se agregará una respuesta detallada ... –

Respuesta

5

Por lo que yo sé, esto es una parte de la base 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 

El mensaje de error textual indica que es comportamiento previsto.

Aquí es mi mejor estimación de qué que es el comportamiento previsto:

Por la forma en que tratan a NA 's en otros lugares (por ejemplo, normalmente por defecto a na.rm=FALSE), parece que los diseñadores de R Ver NA' s como llevando información importante, y son reacios a dejar eso sin algunas instrucciones explícitas para hacerlo. (Afortunadamente, el establecimiento de nomatch=0 da una forma limpia para pasar esa instrucción a lo largo!)

En este contexto, los diseñadores preferencia probablemente explica por qué NA 'son aceptadas s para la indexación positiva, pero no para la indexación negativa:

# 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 Nice answer! Sí, es desde la base. [FR # 1384] (https://r-forge.r-project.org/tracker/index.php?func=detail&aid=1384&group_id=240&atid=978) es hacer que la sintaxis 'X [-Y]' signifique 'no' unirse'. Mientras tanto 'which = TRUE, nomatch = 0' es necesario. –

2

Nuevo en la versión 1.7.3 del data.table:

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

+3

Ese cambio podría ayudar un poco, pero no fue pensado para 'no unirse' realmente. [FR # 1384] (https://r-forge.r-project.org/tracker/index.php?func=detail&aid=1384&group_id=240&atid=978) aún está por hacer.Es bueno ver que alguien lee NOTICIAS, aunque :) –

17

Nuevo en 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