2012-12-20 29 views
82

Ho letto un file CSV in un file R dati.frame. Alcune delle righe hanno lo stesso elemento in una delle colonne. Vorrei rimuovere le righe che sono duplicati in quella colonna. Ad esempio:Rimuovi righe duplicate

platform_external_dbus   202   16      google  1 
platform_external_dbus   202   16   space-ghost.verbum  1 
platform_external_dbus   202   16     localhost  1 
platform_external_dbus   202   16   users.sourceforge  8 
platform_external_dbus   202   16     hughsie  1 

desidero solo una di queste righe poiché gli altri hanno gli stessi dati nella prima colonna.

+2

quale vuoi di più? solo il primo? in altre parole: vuoi mantenere 'google' o' localhost' o 'hughsie'? –

+0

Non ha importanza per questa parte della mia analisi statistica. Sto solo cercando di mettere in relazione il titolo del progetto (prima colonna), il numero di bug (seconda colonna) e il numero di organizzazioni sul progetto (terza colonna). – user1897691

+3

cool. gettare colonne inutili e utilizzare? unico –

risposta

114

basta isolare i frame di dati alle colonne è necessario, quindi utilizzare la funzione unica: D

# in the above example, you only need the first three columns 
deduped.data <- unique(yourdata[ , 1:3 ]) 
# the fourth column no longer 'distinguishes' them, 
# so they're duplicates and thrown out. 
+0

Sembra che funzionerà perfettamente. Puoi spiegarmi per favore cosa sta succedendo con la parte '[, 1: 3]' di quel codice? Sono nuovo di R, ed è per questo che sto chiedendo che cosa posso solo supporre sia una domanda ovvia. – user1897691

+6

@ user1897691 contrassegnalo come corretto quindi;) [guarda questo] (http://www.screenr.com/fCs8) e se ti piace, controlla [twotorials.com] (http://twotorials.com) –

110

Per le persone che sono venuti qui a cercare una risposta generale per la rimozione di righe duplicate, utilizzare !duplicated():

a <- c(rep("A", 3), rep("B", 3), rep("C",2)) 
b <- c(1,1,2,4,1,1,2,2) 
df <-data.frame(a,b) 

duplicated(df) 
[1] FALSE TRUE FALSE FALSE FALSE TRUE FALSE TRUE 

> df[duplicated(df), ] 
    a b 
2 A 1 
6 B 1 
8 C 2 

> df[!duplicated(df), ] 
    a b 
1 A 1 
3 A 2 
4 B 4 
5 B 1 
7 C 2 

risposta da: Removing duplicated rows from R data frame

+0

I vuoi creare un nuovo varibale che contrassegna se c'è un duplicato * su una certa variabile * quasi come df $ duplicati <- ifelse (questo valore di righe nella colonna a == valore di riga precedente nella colonna a, 1, 0) – jacob

+0

@ jacob vedi questa domanda http://stackoverflow.com/questions/12495345/find-indices-of-duplicated-rows –

+1

Questo mantiene il primo valore apparso e rimuove il resto dei duplicati, giusto? O rimuove i valori casualmente? – alphabetagamma

37

la funzione distinct() nel dplyr packa ge esegue la rimozione arbitraria dei duplicati, consentendo la specifica delle variabili duplicate (come in questa domanda) o considerando tutte le variabili.

dati:

dat <- data.frame(a = rep(c(1,2),4), b = rep(LETTERS[1:4],2)) 

rimuovere le righe in cui vengono duplicati colonne specificate:

library(dplyr) 
dat %>% distinct(a, .keep_all = TRUE) 

    a b 
1 1 A 
2 2 B 

rimuovere le righe che sono duplicati completi di altre righe:

dat %>% distinct 

    a b 
1 1 A 
2 2 B 
3 1 C 
4 2 D 
5

Con sqldf:

# Example by Mehdi Nellen 
a <- c(rep("A", 3), rep("B", 3), rep("C",2)) 
b <- c(1,1,2,4,1,1,2,2) 
df <-data.frame(a,b) 

Soluzione:

library(sqldf) 
    sqldf('SELECT DISTINCT * FROM df') 

uscita:

a b 
1 A 1 
2 A 2 
3 B 4 
4 B 1 
5 C 2 
21

Il pacchetto data.table ha anche unique e duplicated metodi di essa la propria con alcune funzionalità aggiuntive.

Sia il unique.data.table ei metodi duplicated.data.table hanno un by ulteriore argomento che permette di passare una character o integer vettore di nomi di colonna o le loro posizioni rispettivamente

library(data.table) 
DT <- data.table(id = c(1,1,1,2,2,2), 
       val = c(10,20,30,10,20,30)) 

unique(DT, by = "id") 
# id val 
# 1: 1 10 
# 2: 2 10 

duplicated(DT, by = "id") 
# [1] FALSE TRUE TRUE FALSE TRUE TRUE 

Un'altra importante caratteristica di questi metodi è una performance enorme guadagno per set di dati più grandi

library(microbenchmark) 
library(data.table) 
set.seed(123) 
DF <- as.data.frame(matrix(sample(1e8, 1e5, replace = TRUE), ncol = 10)) 
DT <- copy(DF) 
setDT(DT) 

microbenchmark(unique(DF), unique(DT)) 
# Unit: microseconds 
#  expr  min   lq  mean median  uq  max neval cld 
# unique(DF) 44708.230 48981.8445 53062.536 51573.276 52844.591 107032.18 100 b 
# unique(DT) 746.855 776.6145 2201.657 864.932 919.489 55986.88 100 a 


microbenchmark(duplicated(DF), duplicated(DT)) 
# Unit: microseconds 
#   expr  min   lq  mean  median  uq  max neval cld 
# duplicated(DF) 43786.662 44418.8005 46684.0602 44925.0230 46802.398 109550.170 100 b 
# duplicated(DT) 551.982 558.2215 851.0246 639.9795 663.658 5805.243 100 a 
2

Oppure è possibile nidificare i dati in colonne 4 e 5 in una riga singola con tidyr:

library(tidyr) 
df %>% nest(V4:V5) 

# A tibble: 1 × 4 
#      V1 V2 V3    data 
#     <fctr> <int> <int>   <list> 
#1 platform_external_dbus 202 16 <tibble [5 × 2]> 

Col 2 e 3 duplicati vengono rimossi per l'analisi statistica, ma hanno mantenuto la forcella 4 e 5 i dati in un Tibble e può ritornare al frame di dati originale in qualsiasi punto con unnest().

0

la risposta generale può essere ad esempio:

df <- data.frame(rbind(c(2,9,6),c(4,6,7),c(4,6,7),c(4,6,7),c(2,9,6)))) 



new_df <- df[-which(duplicated(df)), ] 

uscita:

 X1 X2 X3 
    1 2 9 6 
    2 4 6 7