2011-08-18 38 views
16

Tôi có một khung dữ liệu ví dụ .:Loại bỏ hàng cụ thể từ một dataframe

sub day 
1  1 
1  2 
1  3 
1  4 
2  1 
2  2 
2  3 
2  4 
3  1 
3  2 
3  3 
3  4 

và tôi muốn loại bỏ các hàng cụ thể mà có thể được xác định bởi sự kết hợp của sub và ngày. Ví dụ: tôi muốn xóa các hàng có sub = '1' và day = '2' và sub = 3 và day = '4'. Làm thế nào tôi có thể làm điều này? Tôi nhận ra rằng tôi có thể chỉ định số hàng, nhưng điều này cần phải được áp dụng cho một khung dữ liệu khổng lồ mà sẽ là tẻ nhạt để đi qua và ID mỗi hàng.

Trả lời

27
DF[ ! ((DF$sub ==1 & DF$day==2) | (DF$sub ==3 & DF$day==4)) , ] # note the ! (negation) 

Hoặc nếu phụ là một yếu tố theo đề xuất của bạn bằng cách sử dụng dấu ngoặc kép:

DF[ ! paste(sub,day,sep="_") %in% c("1_2", "3_4"), ] 

cũng có thể sử dụng tập hợp con:

subset(DF, ! paste(sub,day,sep="_") %in% c("1_2", "3_4")) 

(. Và tôi ủng hộ việc sử dụng which trong câu trả lời Dirk khi sử dụng "[" mặc dù một số tuyên bố nó là không cần thiết)

+0

Đó là vé. Cảm ơn. % In% có nghĩa là gì? –

+2

Nó là một ví dụ về một toán tử infix và nó trả về một vectơ logic cho bạn biết các phần tử nào trong đối số đầu tiên được chứa trong đối số thứ hai. Xem? Khớp với vị trí được xác định. –

+0

@BondedDust và ở đây cũng như –

16

này nắm để hai bước riêng biệt:

  1. Hình ra khi tình trạng của bạn là đúng, và do đó tính toán một vector của các phép toán luận, hoặc, như tôi thích, chỉ số của họ bằng cách gói nó vào which()
  2. Tạo một cập nhật data.frame bằng cách loại trừ các chỉ mục từ bước trước đó.

Dưới đây là một ví dụ:

R> set.seed(42) 
R> DF <- data.frame(sub=rep(1:4, each=4), day=sample(1:4, 16, replace=TRUE)) 
R> DF 
    sub day 
1 1 4 
2 1 4 
3 1 2 
4 1 4 
5 2 3 
6 2 3 
7 2 3 
8 2 1 
9 3 3 
10 3 3 
11 3 2 
12 3 3 
13 4 4 
14 4 2 
15 4 2 
16 4 4 
R> ind <- which(with(DF, sub==2 & day==3)) 
R> ind 
[1] 5 6 7 
R> DF <- DF[ -ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 0 1 0 3 
    2 1 0 0 0 
    3 0 1 3 0 
    4 0 2 0 2 
R> 

Và chúng ta thấy rằng sub==2 chỉ có một còn với day==1 nhập cảnh.

Sửa Điều kiện hợp chất có thể được thực hiện với một 'hoặc' như sau:

ind <- which(with(DF, (sub==1 & day==2) | (sub=3 & day=4))) 

và đây là một ví dụ hoàn mới

R> set.seed(1) 
R> DF <- data.frame(sub=rep(1:4, each=5), day=sample(1:4, 20, replace=TRUE)) 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 2 1 1 
    2 1 0 2 2 
    3 2 1 1 1 
    4 0 2 1 2 
R> ind <- which(with(DF, (sub==1 & day==2) | (sub==3 & day==4))) 
R> ind 
[1] 1 2 15 
R> DF <- DF[-ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 0 1 1 
    2 1 0 2 2 
    3 2 1 1 0 
    4 0 2 1 2 
R> 
+0

ok, tôi nghĩ rằng sẽ làm việc với một chút giúp đỡ thêm ... i cần phải id kéo dài nhiều ngày vì vậy tôi đã thử mã của bạn được sửa đổi một chút: ind <-which (với (Licor, day = c ('1', '16', '30', '37', '51', '52', '57 ', '58'))) nhưng nhận được thông báo lỗi. Bất kỳ ý tưởng? –

+0

Làm việc trên biểu thức để tính toán các indies, bạn có thể tìm thấy 'help (match)' hữu ích. –

+0

Câu trả lời này có giải thích về chiến lược cần thiết, cách áp dụng mã và mã nào để áp dụng, với các ví dụ. Điều này rất hữu ích. – Irwin

4

Dưới đây là một giải pháp cho bạn vấn đề sử dụng chức năng dplyr 's filter.

Mặc dù bạn có thể chuyển khung dữ liệu làm đối số đầu tiên cho bất kỳ chức năng dplyr nào, tôi đã sử dụng toán tử %>%, điều này giúp khung dữ liệu của bạn thành một hoặc nhiều hàm dplyr (chỉ lọc trong trường hợp này).

Khi bạn đã quen với dplyr, cheat sheet rất tiện dụng.

> print(df <- data.frame(sub=rep(1:3, each=4), day=1:4)) 
    sub day 
1 1 1 
2 1 2 
3 1 3 
4 1 4 
5 2 1 
6 2 2 
7 2 3 
8 2 4 
9 3 1 
10 3 2 
11 3 3 
12 3 4 
> print(df <- df %>% filter(!((sub==1 & day==2) | (sub==3 & day==4)))) 
    sub day 
1 1 1 
2 1 3 
3 1 4 
4 2 1 
5 2 2 
6 2 3 
7 2 4 
8 3 1 
9 3 2 
10 3 3 
2

một giải pháp đơn giản

cond1 <- df$sub == 1 & df$day == 2

cond2 <- df$sub == 3 & df$day == 4

df <- df[!cond1,]

df <- df[!cond2,]

Các vấn đề liên quan