2011-10-19 10 views
6

[Actualización 1: Como señaló Matthew Dowle, estoy usando data.table versión 1.6.7 en R-Forge, no CRAN. No verá el mismo comportamiento con una versión anterior de data.table.]Transferencia de operaciones de conjunto de marcos de datos de R a tablas de datos: ¿Cómo identificar filas duplicadas?

Como fondo: transfiero algunas pequeñas funciones de utilidad para establecer operaciones en filas de un marco de datos o pares de marcos de datos (es decir, cada fila es un elemento en un conjunto), por ejemplo único: para crear un conjunto a partir de una lista, unión, intersección, diferencia de ajuste, etc. Estos imitan los intersect(...,'rows') de Matlab, setdiff(...,'rows'), etc., que no parecen tener contrapartidas en R (las operaciones de conjunto de R están limitadas a vectores y listas, pero no filas de matrices o marcos de datos). Ejemplos de estas pequeñas funciones están a continuación. Si esta funcionalidad para marcos de datos ya existe en algún paquete o base R, estoy abierto a sugerencias.

He estado migrando estos a tablas de datos y un paso necesario en el enfoque actual es encontrar filas duplicadas. Cuando se ejecuta duplicated(), se devuelve un error que indica que las tablas de datos deben tener claves. Este es un obstáculo desafortunado: además de establecer claves, que no es una solución universal y se suma a los costos computacionales, ¿hay alguna otra forma de encontrar objetos duplicados?

Aquí está un ejemplo reproducible:

library(data.table) 
set.seed(0) 
x <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4)) 
y <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4)) 

res3 <- dt_intersect(x,y) 

Ceder este mensaje de error:

Error in duplicated.data.table(z_rbind) : data table must have keys 

El código funciona tal cual para tramas de datos, a pesar de que he nombrado cada función con el patrón dt_operation .

¿Hay alguna forma de evitar este problema? Configurar teclas solo funciona para enteros, que es una restricción que no puedo asumir para los datos de entrada. Entonces, ¿tal vez me falta una forma inteligente de usar tablas de datos?


ejemplo de las funciones de operación, donde los elementos de los conjuntos son filas de datos:

dt_unique  <- function(x){ 
    return(unique(x)) 
} 

dt_union  <- function(x,y){ 
    z_rbind  <- rbind(x,y) 
    z_unique <- dt_unique(z_rbind) 
    return(z_unique) 
} 

dt_intersect <- function(x,y){ 
    zx   <- dt_unique(x) 
    zy   <- dt_unique(y) 

    z_rbind  <- rbind(zy,zx) 
    ixDupe  <- which(duplicated(z_rbind)) 
    z   <- z_rbind[ixDupe,] 
    return(z) 
} 

dt_setdiff  <- function(x,y){ 
    zx   <- dt_unique(x) 
    zy   <- dt_unique(y) 

    z_rbind  <- rbind(zy,zx) 
    ixRangeX <- (nrow(zy) + 1):nrow(z_rbind) 
    ixNotDupe <- which(!duplicated(z_rbind)) 
    ixDiff  <- intersect(ixNotDupe, ixRangeX) 
    diffX  <- z_rbind[ixDiff,] 
    return(diffX) 
} 

Nota 1: Uno de los usos destinados a estas funciones de ayuda es encontrar filas en las que los valores clave en x no están entre los valores clave en y. De esta forma, puedo encontrar dónde pueden aparecer NA al calcular x[y] o y[x]. Aunque este uso permite la configuración de claves para el objeto z_rbind, prefiero no restringirme solo a este caso de uso.

Nota 2: Para los puestos relacionados, here is a post en el funcionamiento unique en tramas de datos, con excelentes resultados para el funcionamiento con el data.table paquete actualizado. Y this is an earlier post al ejecutar unique en las tablas de datos.

Respuesta

6

duplicated.data.table necesita la misma corrección unique.data.table got [EDIT: Ahora hecho en v1.7.2]. Por favor levante otro informe de error: bug.report(package="data.table"). Para beneficio de los demás, ya está utilizando v1.6.7 desde R-Forge, no 1.6.6 en CRAN.

Pero, en la Nota 1, hay un 'no unirse a' expresión idiomática:

x[-x[y,which=TRUE]] 

Ver también FR#1384 (Nueva 'no' y los argumentos de whichna '?) Para hacer que más fácil para los usuarios, y que los enlaces al hilo keys that don't match que entra en más detalles.


actualización. Ahora en v1.8.3, no se ha implementado la unión.

DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom 
DT[!"a",...]       # same result, now preferred. 
+0

Gracias! Buen punto: olvidé mencionar que actualicé 'data.table'. Además, 'bug.report()' es nuevo para mí. – Iterator

+0

Matthew, ¿debería ser tu código 'x [-x [y, which = TRUE, nomatch = 0]]'? Sin el argumento 'nomatch = 0' obtengo este error:' Error en [.default (x [[s]], irows): solo los 0 pueden mezclarse con los subíndices negativos'. – Ryogi

+0

@RYogi. No es seguro. Necesito un ejemplo, por favor, quizás en una nueva pregunta. –

Cuestiones relacionadas