Rimozione duplicata per coppia dal dataframe

Questo sembra un problema semplice ma non riesco a capirlo. Mi piacerebbe rimuovere i duplicati da un dataframe (df) se due colonne hanno gli stessi valori, anche se quei valori sono nell’ordine inverso . Ciò che intendo è, diciamo che hai il seguente quadro di dati:

a <- c(rep("A", 3), rep("B", 3), rep("C",2)) b <- c('A','B','B','C','A','A','B','B') df <-data.frame(a,b) ab 1 AA 2 AB 3 AB 4 BC 5 BA 6 BA 7 CB 8 CB 

Se ora rimuovo i duplicati, ottengo il seguente frame di dati:

 df[duplicated(df),] ab 3 AB 6 BA 8 CB 

Tuttavia, vorrei anche rimuovere la riga 6 in questo frame di dati, poiché “A”, “B” è uguale a “B”, “A”. Come posso farlo automaticamente?

Idealmente, potrei specificare quali due colonne confrontare, dato che i frame di dati potrebbero avere colonne diverse e possono essere piuttosto grandi.

Grazie!

    Una soluzione è ordinare prima ogni riga di df :

     for (i in 1:nrow(df)) { df[i, ] = sort(df[i, ]) } df ab 1 AA 2 AB 3 AB 4 BC 5 AB 6 AB 7 BC 8 BC 

    A quel punto si tratta semplicemente di rimuovere gli elementi duplicati:

     df = df[!duplicated(df),] df ab 1 AA 2 AB 4 BC 

    Come la posta elettronica menzionata nei commenti, il tuo codice conserva i duplicati. Devi usarlo !duplicated per rimuoverli.

    Estendi la risposta di Ari, per specificare le colonne per verificare se ci sono anche altre colonne:

     a < - c(rep("A", 3), rep("B", 3), rep("C",2)) b <- c('A','B','B','C','A','A','B','B') df <-data.frame(a,b) df$c = sample(1:10,8) df$d = sample(LETTERS,8) df abcd 1 AA 10 B 2 AB 8 S 3 AB 7 J 4 BC 3 Q 5 BA 2 I 6 BA 6 U 7 CB 4 L 8 CB 5 V cols = c(1,2) newdf = df[,cols] for (i in 1:nrow(df)){ newdf[i, ] = sort(df[i,cols]) } df[!duplicated(newdf),] abcd 1 AA 8 X 2 AB 7 L 4 BC 2 P 

    Le altre risposte utilizzano un ciclo for per assegnare un valore per ogni riga. Anche se questo non è un problema se hai 100 righe, o anche mille, stai aspettando un po ‘di tempo se hai grandi dati dell’ordine di 1 milione di righe.

    Rubando dall’altra risposta collegata usando data.table , puoi provare qualcosa come:

     df[!duplicated(data.frame(list(do.call(pmin,df),do.call(pmax,df)))),] 

    Un benchmark comparativo con un set di dati più grande ( df2 ):

     df2 < - df[sample(1:nrow(df),50000,replace=TRUE),] system.time( df2[!duplicated(data.frame(list(do.call(pmin,df2),do.call(pmax,df2)))),] ) # user system elapsed # 0.07 0.00 0.06 system.time({ for (i in 1:nrow(df2)) { df2[i, ] = sort(df2[i, ]) } df2[!duplicated(df2),] } ) # user system elapsed # 42.07 0.02 42.09 

    L’utilizzo di apply sarà un’opzione migliore rispetto ai loop.

     newDf < - data.frame(t(apply(df,1,sort))) 

    Tutto quello che devi fare ora è rimuovere i duplicati.

     newDf < - newDf[!duplicated(newDf),]