2012-11-29 29 views
6

Tôi có một khung dữ liệu rất lớn mà tôi muốn lưu một tập hợp con dựa trên một tập con nhất định của một vectơ. Tóm lại, tôi có một cái gì đó như thế này:lập chỉ mục một khung dữ liệu dựa trên một tập hợp con vector

> id<-c("ID1","ID2","ID2","ID3","ID4","ID4","ID4","ID4","ID4") 
> status<-c("flag","flag","none","none","flag","flag","flag","none","flag") 
> misc1ofmany<-c("etc1","etc2","etc3","etc4","etc5","etc6","etc7","etc8","etc9") 
> df = data.frame(id, status, misc1ofmany) ; df 
    id status misc1ofmany 
1 ID1 flag  etc1 
2 ID2 flag  etc2 
3 ID2 none  etc3 
4 ID3 none  etc4 
5 ID4 flag  etc5 
6 ID4 flag  etc6 
7 ID4 flag  etc7 
8 ID4 none  etc8 
9 ID4 flag  etc9 

Tôi muốn có tất cả các hàng ID đã bị gắn cờ, bao gồm các phiên không được gắn cờ của chúng. Ngay bây giờ tôi đang cố gắng để có được chỉ số của các ID khác bằng grep và cắm lại vào một df mới. Trên thực tế như tôi đã viết này ra tôi đã tìm ra rằng grepl có thể được dễ dàng hơn để làm việc với:

> flaggedIDs <- unique(as.vector(df$id[grep("flag",df$status)])) 
> flaggedIDs.allStats.Index <- mapply(grepl,df$id,MoreArgs=list(x=flaggedIDs)) 
> flaggedIDs.allStats.Index 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
[2,] FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE 
[3,] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE 

tuy nhiên tôi chỉ muốn để có được ở đây:

> flaggedIDsdf <- df[flaggedIDs.allStats.Index] ; flaggedIDsdf 
    id status misc1ofmany 
1 ID1 flag  etc1 
2 ID2 flag  etc2 
3 ID2 none  etc3 
4 ID4 flag  etc5 
5 ID4 flag  etc6 
6 ID4 flag  etc7 
7 ID4 none  etc8 
8 ID4 flag  etc9 

tôi cảm thấy như thế này nên được đơn giản hơn tôi làm cho điều này ra được, tuy nhiên tôi đã thử một số khả năng để con số này ra vô ích. viết ra câu hỏi đã giúp điều này trở thành một vấn đề rõ ràng/đơn giản hơn trong tâm trí của tôi (có vẻ như tôi đang bỏ lỡ một bước bây giờ), nhưng bây giờ tôi cũng tự hỏi nếu có một cách hiệu quả hơn về việc này.

Trả lời

6

data.table là thực sự hữu ích ở đây cho nó là cú pháp tao nhã và hiệu quả bộ nhớ

library(data.table) 

DT <- data.table(df) 

setkey(DT, 'id') 

DT[DT[status=='flag', list(id = unique(id))]] 

    id status misc1ofmany 
1: ID1 flag  etc1 
2: ID2 flag  etc2 
3: ID2 none  etc3 
4: ID4 flag  etc5 
5: ID4 flag  etc6 
6: ID4 flag  etc7 
7: ID4 none  etc8 
8: ID4 flag  etc9 

Hoặc thậm chí gọn hơn

DT[J(unique(id[status=='flag']))] 

Hai phương pháp trên sử dụng thực tế là các thành phần i được đánh giá đầu tiên của data.table . Keying by id có nghĩa là chúng ta có thể tự tham gia để chỉ trích xuất những số ids trong đó status=='flag.


Hoặc, sử dụng by

DT[,if(any(status=='flag')){.SD} ,by=id] 

này trình bày các tập con của DT bởi id, và trả .SD (các data.table của tập hợp con) nếu any(status=='flag') (trong tập hợp con đó).

+0

rất thanh lịch! Cảm ơn bạn đã trả lời! – stites

1

Tôi tin rằng những gì bạn đang cố gắng làm có thể được xử lý trong một dòng

df[which(df$id %in% df$id[df$status=="flag"]), ] 

kết quả:

id status misc1ofmany 
1 ID1 flag  etc1 
2 ID2 flag  etc2 
3 ID2 none  etc3 
5 ID4 flag  etc5 
6 ID4 flag  etc6 
7 ID4 flag  etc7 
8 ID4 none  etc8 
9 ID4 flag  etc9 
+0

Anh ấy dường như muốn giữ id và hàng miễn là nó bị gắn cờ. Điều này chỉ giữ những người bị gắn cờ. –

+0

@Brandon Woops! cảm ơn cho làm rõ, Ill sửa đổi –

2

Điều này dường như làm việc:

df[df$id %in% df$id[df$status == "flag"],] 

Plain tiếng Anh: từ khung dữ liệu, chọn mỗi hàng có phần tử id nằm trong vectơ của các phần tử id có trạng thái được gắn cờ trong bất kỳ hàng nào.

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