2012-03-22 20 views
8

Sono un novellino R e sto tentando di rimuovere le colonne duplicate da un ampio dataframe (50K righe, 215 colonne). Il frame ha un mix di variabili discrete continue e categoriali.Identificazione di colonne duplicate in un frame di dati R

Il mio approccio è stato quello di generare una tabella per ogni colonna nel fotogramma in un elenco, quindi utilizzare la funzione duplicated() per trovare le righe della lista che sono duplicati, come segue:

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)) 

Questo isn' molto efficiente, specialmente per grandi variabili continue. Tuttavia, ho intrapreso questa strada perché sono stato in grado di ottenere lo stesso risultato utilizzando sintesi (nota, il seguente assume un originale testframe contenenti duplicati):

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

Se si esegue il codice che avrete vederlo rimuove solo il primo duplicato trovato. Presumo questo perché sto facendo qualcosa di sbagliato. Qualcuno può indicare dove sto andando male o, ancora meglio, indicarmi la direzione di un modo migliore per rimuovere le colonne duplicate da un dataframe?

risposta

16

Si può fare con lapply:

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

summary riassume la distribuzione, ignorando l'ordine.

non al 100%, ma userei digerire se i dati è enorme:

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

Oltre a @kohske 's suggerimento di usare 'digest', potrebbe essere sufficiente utilizzare' C' invece di 'su mmary' come la funzione 'lapply'. – BenBarnes

+1

Va notato che il riepilogo per i vettori di caratteri produrrà lo stesso sommario anche se sono diversi. Questo perché il riassunto su un vettore di caratteri emette solo la lunghezza del vettore – hshihab

3
unique(testframe, MARGIN=2) 

non funziona, anche se penso che dovrebbe, in modo da provare

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

o se si sono preoccupati per i numeri che si trasformano in fattori,

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

che 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

ne dite:

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

Questo è di gran lunga il metodo più veloce che ho usato per testare i duplicati su un data.frame – Zelazny7

2

Un bel trucco che è possibile utilizzare è quello di trasporre la vostra struttura dati e quindi controllare i duplicati.

duplicated(t(testframe)) 
-1

In realtà è solo avrebbe bisogno di invertire il-risultato duplicato nel codice e potrebbe attenersi a utilizzare subset (che è più leggibile rispetto a staffa notazione imho)

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

Ecco un semplice comando che potrebbe funzionare se le colonne duplicate della cornice di dati avevano gli stessi nomi:

testframe[names(testframe)[!duplicated(names(testframe))]] 
Problemi correlati