Righe univoche, considerando due colonne, in R, senza ordine

A differenza delle domande che ho trovato, voglio ottenere l’unicità di due colonne senza ordine.

Ho un df:

df df [,1] [,2] [1,] "a" "b" [2,] "b" "d" [3,] "c" "e" [4,] "b" "a" 

In questo caso, la riga 1 e la riga 4 sono “duplicati” nel senso che ba è uguale a ba.

So come trovare univoco delle colonne 1 e 2, ma troverei ogni riga unica sotto questo approccio.

Ci sono molti modi per farlo, eccone uno:

 unique(t(apply(df, 1, sort))) duplicated(t(apply(df, 1, sort))) 

Uno dà le righe univoche, l’altro dà la maschera.

Se sono solo due colonne, puoi anche usare pmin e pmax , in questo modo:

 library(data.table) unique(as.data.table(df)[, c("V1", "V2") := list(pmin(V1, V2), pmax(V1, V2))], by = c("V1", "V2")) # V1 V2 # 1: ab # 2: bd # 3: ce 

Un approccio simile usando “dplyr” potrebbe essere:

 library(dplyr) data.frame(df, stringsAsFactors = FALSE) %>% mutate(key = paste0(pmin(X1, X2), pmax(X1, X2), sep = "")) %>% distinct(key) # X1 X2 key # 1 ab ab # 2 bd bd # 3 ce ce 

Puoi usare igraph per creare un grafo non orientato e poi riconvertire in un data.frame

 unique(get.data.frame(graph.data.frame(df, directed=FALSE),"edges")) 

Se tutti gli elementi sono stringhe (diamine, anche se non lo sono e puoi costringerli), un trucco è crearlo come data.frame e usare alcuni trucchi di dplyr su di esso.

 library(dplyr) df < - data.frame(v1 = c("a","b","c","b"), v2 = c("b","d","e","a")) df$key <- apply(df, 1, function(s) paste0(sort(s), collapse='')) head(df) ## v1 v2 key ## 1 ab ab ## 2 bd bd ## 3 ce ce ## 4 ba ab 

La colonna $key dovrebbe ora dirti le ripetizioni.

 df %>% group_by(key) %>% do(head(., n = 1)) ## Source: local data frame [3 x 3] ## Groups: key ## v1 v2 key ## 1 ab ab ## 2 bd bd ## 3 ce ce