2015-02-18 15 views
5

Không giống như các câu hỏi tôi đã tìm thấy, tôi muốn nhận được duy nhất của hai cột không có thứ tự.Hàng duy nhất, xem xét hai cột, trong R, không có thứ tự

Tôi có một df:

df<-cbind(c("a","b","c","b"),c("b","d","e","a")) 
> df 
    [,1] [,2] 
[1,] "a" "b" 
[2,] "b" "d" 
[3,] "c" "e" 
[4,] "b" "a" 

Trong trường hợp này, dòng 1 và dòng 4 là "bản sao" theo nghĩa là b-a là giống như b-a.

Tôi biết cách tìm duy nhất các cột 1 và 2 nhưng tôi sẽ tìm thấy mỗi hàng duy nhất theo cách tiếp cận này.

+0

Đó không phải là data.frame mà là ma trận; nếu nó là một df, 'unique (df)' sẽ thực hiện thủ thuật. Hãy thử 'df <-data.frame (c (" a "," b "," c "," b "), c (" b "," d "," e "," a "))' trước tiên. – Frank

+2

Tôi không nghĩ vậy, 'unique (df)' không kiểm tra các cột để thấy rằng 'c ('a', 'b')' có hiệu quả giống như 'c ('b', 'a') '(và tại sao phải không?). Làm việc nhiều hơn một chút ... – r2evans

Trả lời

6

Có rất nhiều nhân cách để làm điều này, đây là một trong:

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

Một mang lại cho các hàng độc đáo, khác cung cấp cho các mặt nạ.

+0

Cách tiếp cận này trả về lần xuất hiện đầu tiên duy nhất của một hàng (hàng 1,2,3) nhưng nó không trả lại hàng trùng lặp (hàng 1,4)/hàng duy nhất (2,3) như được xác định bởi poster gốc. – atreju

0

Nếu tất cả các phần tử là chuỗi (heck, ngay cả khi không và bạn có thể ép buộc chúng), thì một mẹo là tạo nó dưới dạng data.frame và sử dụng một số mẹo của dplyr trên đó.

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 a b ab 
## 2 b d bd 
## 3 c e ce 
## 4 b a ab 

Cột $key giờ đây sẽ cho bạn biết lặp lại.

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

Đây không phải là cách sử dụng 'dplyr' tốt. Tôi sẽ đề nghị xem xét 'khác biệt' nếu bạn muốn đi tuyến đường này. Trên một tập dữ liệu nhỏ (100k hàng), phương pháp này hiện đang mất> 4 giây trên hệ thống của tôi trong khi phương pháp tiếp cận cơ sở R mất ~ 1,3 giây và cách tiếp cận data.table mất ~ 0,03 giây. – A5C1D2H2I1M1N2O1R2T1

+1

Sử dụng 'pmin' và' pmax' là nơi tốc độ xuất hiện. Một biến thể 'dplyr' của câu trả lời' data.table' của tôi chạy ở ~ 0,05 giây. Để tham khảo, biến thể tôi đang đề cập đến trông giống như sau: 'data.frame (df, stringsAsFactors = FALSE)%>% biến đổi (key = paste0 (pmin (X1, X2), pmax (X1, X2), sep = ""))%>% riêng biệt (khóa) ' – A5C1D2H2I1M1N2O1R2T1

+0

Mã của bạn chắc chắn là ấn tượng. Tôi vẫn đang học cách hiểu về 'dplyr', điều này có vẻ hiển nhiên đối với bạn. – r2evans

5

Nếu nó chỉ là hai cột, bạn cũng có thể sử dụng pminpmax, như thế này:

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: a b 
# 2: b d 
# 3: c e 

Một cách tiếp cận tương tự như sử dụng "dplyr" có thể là:

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

Bạn có thể sử dụng igraph để tạo biểu đồ không bị chiếu xạ và sau đó chuyển đổi về dữ liệu.frame

unique(get.data.frame(graph.data.frame(df, directed=FALSE),"edges")) 
Các vấn đề liên quan