2014-04-09 26 views
82

Tôi có một data.frame như thế này -Remove nhân đôi hàng sử dụng dplyr

set.seed(123) 
df = data.frame(x=sample(0:1,10,replace=T),y=sample(0:1,10,replace=T),z=1:10) 
> df 
    x y z 
1 0 1 1 
2 1 0 2 
3 0 1 3 
4 1 1 4 
5 1 0 5 
6 0 1 6 
7 1 0 7 
8 1 0 8 
9 1 0 9 
10 0 1 10 

Tôi muốn loại bỏ các hàng trùng lặp dựa trên hai cột đầu tiên. Sản lượng dự kiến ​​-

df[!duplicated(df[,1:2]),] 
    x y z 
1 0 1 1 
2 1 0 2 
4 1 1 4 

Tôi đang tìm kiếm giải pháp sử dụng gói dplyr.

Trả lời

87
library(dplyr) 
set.seed(123) 
df <- data.frame(
    x = sample(0:1, 10, replace = T), 
    y = sample(0:1, 10, replace = T), 
    z = 1:10 
) 

Một cách tiếp cận sẽ được nhóm, và sau đó chỉ giữ nhóm với một hàng duy nhất:

df %>% group_by(x, y) %>% filter(row_number(z) == 1) 

## Source: local data frame [3 x 3] 
## Groups: x, y 
## 
## x y z 
## 1 0 1 1 
## 2 1 0 2 
## 3 1 1 4 

(Trong dplyr 0.2 bạn sẽ không cần z biến dummy và sẽ chỉ được có thể viết row_number() == 1)

Tôi cũng đã suy nghĩ về việc thêm một hàm slice() sẽ hoạt động như:

df %>% group_by(x, y) %>% slice(from = 1, to = 1) 

Hoặc có thể là một biến thể của unique() mà sẽ cho phép bạn chọn những biến để sử dụng:

df %>% unique(x, y) 
+3

@dotcomken Cho đến lúc đó cũng có thể chỉ cần sử dụng 'df%>% group_by (x, y)%>% làm (người đứng đầu (1)) ' –

+12

@MahbubulMajumder sẽ hoạt động nhưng khá chậm. dplyr 0.3 sẽ có 'khác biệt()' – hadley

+1

@hadley Tôi thích hàm duy nhất() và khác biệt(), tuy nhiên, tất cả chúng đều loại bỏ bản sao thứ 2 khỏi khung dữ liệu. nếu tôi muốn có tất cả các cuộc gặp gỡ đầu tiên của giá trị trùng lặp bị xóa thì sao? Làm thế nào điều này có thể được thực hiện? Cảm ơn vì bất kì sự giúp đỡ! – FlyingDutch

132

Đây là một giải pháp sử dụng dplyr 0.3.

library(dplyr) 
set.seed(123) 
df <- data.frame(
    x = sample(0:1, 10, replace = T), 
    y = sample(0:1, 10, replace = T), 
    z = 1:10 
) 

> df %>% distinct(x, y) 
    x y z 
    1 0 1 1 
    2 1 0 2 
    3 1 1 4 

Cập nhật cho dplyr 0,5

phiên bản dplyr hành vi 0,5 mặc định chỉ distinct() lợi nhuận cột quy định tại ... tranh cãi.

Để đạt được kết quả ban đầu, bây giờ bạn phải sử dụng:

df %>% distinct(x, y, .keep_all = TRUE) 
+1

Giải pháp này có vẻ nhanh hơn nhiều (10 lần trong trường hợp của tôi) so với giải pháp do Hadley cung cấp. – Calimo

+71

Về mặt kỹ thuật này cũng là một giải pháp được cung cấp bởi Hadley :-) –

16

Đối với đầy đủ lợi ích, sau đây cũng làm việc:

df %>% group_by(x) %>% filter (! duplicated(y)) 

Tuy nhiên, tôi thích các giải pháp sử dụng distinct, và tôi nghi ngờ nó cũng nhanh hơn.

0

Khi chọn cột trong R cho tập dữ liệu giảm, bạn thường có thể kết thúc bằng các bản sao.

Hai dòng này cho cùng một kết quả. Mỗi kết quả đầu ra một dữ liệu thiết lập độc đáo chỉ có hai cột chọn:.

distinct(mtcars, cyl, hp); 

summarise(group_by(mtcars, cyl, hp)); 
Các vấn đề liên quan