2012-03-22 5 views
8

Jestem nowicjuszem w wersji R i próbuję usunąć zduplikowane kolumny z dużej ramki danych (50 wierszy, 215 kolumn). Ramka zawiera mieszankę dyskretnych zmiennych ciągłych i kategorycznych.Identyfikowanie duplikatów kolumn w ramce danych R

Moje podejście było wygenerować tabelę dla każdej kolumny w ramce do listy, a następnie użyj funkcji duplicated() znaleźć wiersze w liście, które są duplikatami, co następuje:

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

Ten ISN” t bardzo wydajny, szczególnie w przypadku dużych zmiennych ciągłych. Jednak Poszedłem na dół tą drogą, ponieważ byłem w stanie uzyskać ten sam efekt przy użyciu Podsumowanie (uwaga dodaje zakłada oryginalną testframe zawierające duplikaty):

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

Po uruchomieniu tego kodu będziesz zobacz tylko usuwa pierwszy znaleziony duplikat. Zakładam, że dzieje się tak dlatego, że robię coś złego. Czy ktokolwiek może wskazać, gdzie idę źle, a nawet lepiej, wskazać mi w kierunku lepszego sposobu na usunięcie zduplikowanych kolumn z ramki danych?

Odpowiedz

16

Można zrobić z lapply:

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

summary podsumowuje dystrybucję ignorując rozkaz.

nie 100%, ale chciałbym używać strawienia jeśli dane jest ogromna:

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

oprócz @kohske „s sugestię użyć' digest', to może wystarczyć, aby używać 'C' zamiast' su mmary' jako funkcja 'lapply'. – BenBarnes

+1

Należy zauważyć, że podsumowanie dla wektorów znaków będzie generować to samo podsumowanie, nawet jeśli są różne. Dzieje się tak dlatego, że podsumowanie na wektorze znaków wyprowadza tylko długość wektora – hshihab

3
unique(testframe, MARGIN=2) 

nie działa, chociaż myślę, że powinien, więc spróbuj

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

lub jeśli Martwisz się liczbami zmieniającymi się w czynniki,

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

, która produkuje

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

Jak o:

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

Jest to zdecydowanie najszybsza metoda, której użyłem do testowania duplikatów na danych.frame – Zelazny7

2

Miła trik, który można użyć jest transpozycja ramki danych, a następnie sprawdzić duplikatów.

duplicated(t(testframe)) 
-1

Faktycznie po prostu musiałby odwrócić kopiowane rezultatu w kodzie i może trzymać się za pomocą subset (co jest bardziej czytelny w porównaniu do wspornika notacji imho)

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

Oto prosta komenda że będzie działać, jeśli zduplikowane kolumn ramki danych miały te same nazwy:

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