Tengo una tabla data.table
con aproximadamente 2,5 millones de filas. Hay dos columnas Quiero eliminar las filas que están duplicadas en ambas columnas. Previamente para un data.frame lo hubiera hecho: df -> unique(df[,c('V1', 'V2')])
pero esto no funciona con data.table. He intentado con unique(df[,c(V1,V2), with=FALSE])
pero parece que solo funciona en la clave de data.table y no en toda la fila.
¿Alguna sugerencia?
Saludos, Davy
Ejemplo
>dt V1 V2 [1,] AB [2,] AC [3,] AD [4,] AB [5,] BA [6,] CD [7,] CD [8,] EF [9,] GG [10,] AB
en la tabla de datos anterior, donde V2
es la clave de la tabla, solo se eliminarán las filas 4, 7 y 10.
> dput(dt) structure(list(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G")), .Names = c("V1", "V2"), row.names = c(NA, -10L), class = c("data.table", "data.frame"), .internal.selfref = , sorted = "V2")
Prior v1.9.8
Desde ?unique.data.table
, está claro que la llamada unique
en una tabla de datos solo funciona en la clave. Esto significa que debe restablecer la clave en todas las columnas antes de realizar una llamada unique
.
library(data.table) dt <- data.table( V1=LETTERS[c(1,1,1,1,2,3,3,5,7,1)], V2=LETTERS[c(2,3,4,2,1,4,4,6,7,2)] )
Llamada unique
con una columna como clave:
setkey(dt, "V2") unique(dt) V1 V2 [1,] BA [2,] AB [3,] AC [4,] AD [5,] EF [6,] GG
Para v1.9.8 +
From ?unique.data.table
De forma predeterminada, se están utilizando todas las columnas (lo que es coherente con ?unique.data.frame
)
unique(dt) V1 V2 1: AB 2: AC 3: AD 4: BA 5: CD 6: EF 7: GG
O usando el argumento by
para obtener combinaciones únicas de columnas específicas (como se usaron las claves anteriores)
unique(dt, by = "V2") V1 V2 1: AB 2: AC 3: AD 4: BA 5: EF 6: GG
Con su ejemplo data.table …
> dt<-data.table(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G")) > setkey(dt,V2)
Considere las siguientes pruebas:
> haskey(dt) # obviously dt has a key, since we just set it [1] TRUE > haskey(dt[,list(V1,V2)]) # ... but this is treated like a "new" table, and does not have a key [1] FALSE > haskey(dt[,.SD]) # note that this still has a key [1] TRUE
Entonces, puede enumerar las columnas de la tabla y luego tomar el unique()
de eso, sin necesidad de configurar la clave en todas las columnas o soltarla (estableciéndola en NULL
) como lo requiere la solución de @Andrie (y editado por @MatthewDowle). Las soluciones sugeridas por @Pop y @Rahul no funcionaron para mí.
Consulte la Prueba 3 a continuación, que es muy similar a su bash inicial. Tu ejemplo no estaba claro, así que no estoy seguro de por qué no funcionó. También fue hace unos meses cuando publicaste la pregunta, por lo que quizás se actualizó data.table
?
> unique(dt) # Try 1: wrong answer (missing V1=C and V2=D) V1 V2 1: BA 2: AB 3: AC 4: AD 5: EF 6: GG > dt[!duplicated(dt)] # Try 2: wrong answer (missing V1=C and V2=D) V1 V2 1: BA 2: AB 3: AC 4: AD 5: EF 6: GG > unique(dt[,list(V1,V2)]) # Try 3: correct answer; does not require modifying key V1 V2 1: BA 2: AB 3: AC 4: AD 5: CD 6: EF 7: GG > setkey(dt,NULL) > unique(dt) # Try 4: correct answer; requires key to be removed V1 V2 1: BA 2: AB 3: AC 4: AD 5: CD 6: EF 7: GG
unique(df)
funciona en tu ejemplo.