2012-03-22 65 views
8

Soy un novato en R y estoy tratando de eliminar columnas duplicadas de un marco de datos bastante amplio (50K filas, 215 columnas). El marco tiene una mezcla de variables discretas continuas y categóricas.Identificación de columnas duplicadas en un marco de datos R

Mi enfoque ha sido generar una tabla para cada columna en el cuadro en una lista, a continuación, utilizar la función de duplicated() encontrar filas de la lista que son duplicados, de la siguiente manera:

age=18:29 
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5) 
gender=c("M","F","M","M","F","F","M","M","F","M","F","M") 
testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender) 

tables=apply(testframe,2,table) 
dups=which(duplicated(tables)) 
testframe <- subset(testframe, select = -c(dups)) 

Esto no es t muy eficiente, especialmente para grandes variables continuas. Sin embargo, he ido por este camino porque he sido incapaz de conseguir el mismo resultado utilizando resumen (nota, el siguiente asume un original testframe duplicados que contienen):

summaries=apply(testframe,2,summary) 
dups=which(duplicated(summaries)) 
testframe <- subset(testframe, select = -c(dups)) 

Si ejecuta este código podrás ver que solo elimina el primer duplicado encontrado. Supongo que es porque estoy haciendo algo mal. ¿Alguien puede señalar dónde estoy yendo mal o, mejor aún, señalarme una mejor manera de eliminar las columnas duplicadas de un marco de datos?

Respuesta

16

que puede hacer con lapply:

testframe[!duplicated(lapply(testframe, summary))] 

summary resume la distribución sin tener en cuenta el orden.

No es 100% pero me gustaría utilizar digerir si los datos son enormes:

library(digest) 
testframe[!duplicated(lapply(testframe, digest))] 
+2

Además de @kohske 's sugerencia de utilizar 'digest', podría ser suficiente usar' C' en lugar de 'su mmary' como la función 'lapply'. – BenBarnes

+1

Se debe tener en cuenta que el resumen de los vectores de caracteres producirá el mismo resumen aunque sean diferentes. Esto se debe a que el resumen en un vector de caracteres solo muestra la longitud del vector – hshihab

3
unique(testframe, MARGIN=2) 

no funciona, aunque creo que debería, a fin de tratar

as.data.frame(unique(as.matrix(testframe), MARGIN=2)) 

o si están preocupados por los números que se convierten en factores,

testframe[,colnames(unique(as.matrix(testframe), MARGIN=2))] 

que produce

age height gender 
1 18 76.1  M 
2 19 77.0  F 
3 20 78.1  M 
4 21 78.2  M 
5 22 78.8  F 
6 23 79.7  F 
7 24 79.9  M 
8 25 81.1  M 
9 26 81.2  F 
10 27 81.8  M 
11 28 82.8  F 
12 29 83.5  M 
10

¿Qué tal:

testframe[!duplicated(as.list(testframe))] 
+0

Este es, con mucho, el método más rápido que he usado para probar dups en un data.frame – Zelazny7

2

Un buen truco que se puede utilizar es transponer el marco de datos y luego comprobar si hay duplicados.

duplicated(t(testframe)) 
-1

realidad que sólo tendría que invertir el resultado duplicado en el código y podría pegarse a la utilización de subset (que es más fácil de leer en comparación con el soporte en mi humilde opinión notación)

require(dplyr) 
iris %>% subset(., select=which(!duplicated(names(.)))) 
0

Aquí es un simple comando eso funcionaría si las columnas duplicadas de su trama de datos tenían los mismos nombres:

testframe[names(testframe)[!duplicated(names(testframe))]] 
Cuestiones relacionadas