2012-03-01 31 views
21

Tôi đang cố gắng để chọn hàng trong một dataframe nơi chuỗi chứa trong một cột phù hợp hoặc là một biểu hiện thường xuyên hoặc một chuỗi con:Sử dụng regexp để chọn hàng trong R dataframe

dataframe:

aName bName pName call alleles logRatio strength 
AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 

Ví dụ: tôi muốn một khung dữ liệu chỉ chứa các hàng có chứa ADN trong cột bName. Thứ hai, tôi muốn tất cả các hàng có chứa ADN trong cột bName và khớp với 2011-02-10_R2 trong cột pName.

tôi đã cố gắng sử dụng các hàm grep(), agrep() và nhiều hơn nữa nhưng không thành công ...

Trả lời

25
subset(dat, grepl("ADN", bName) & pName == "2011-02-10_R2") 

Note "&" (chứ không phải "& &" được không vector) và rằng "==" (chứ không phải "=", đó là nhiệm vụ).

Lưu ý rằng bạn có thể đã sử dụng:

dat[ with(dat, grepl("ADN", bName) & pName == "2011-02-10_R2") , ] 

... và đó có thể là một lợi thế khi sử dụng bên trong chức năng, tuy nhiên, điều đó sẽ trở lại giá trị NA cho bất kỳ dòng nơi dat $ pName là NA. Lỗi đó (mà một số liên quan đến tính năng) có thể được loại bỏ bằng cách thêm & !is.na(dat$pName) vào biểu thức logic.

-2

Tại sao không chỉ:

grep 'ADN'|grep '2011-02-10_R2' 

Bạn cũng có thể làm điều này:

grep -P '\t.{4}(ADN).*(2011-02-10_R2).*' 
+8

Bởi vì ngôn ngữ là [tag: R] – Andrie

+1

Xin lỗi, không chú ý đến 'r'. Tôi đoán bạn chỉ có thể sao chép regexp của tôi sau đó –

8

Ở đây bạn đi .

Đầu tiên tái tạo dữ liệu của bạn:

dat <- read.table(text=" 
aName bName pName call alleles logRatio strength 
AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 
", header=TRUE) 

Tiếp theo, sử dụng grepl để xây dựng một chỉ số logic của trận đấu:

index1 <- with(dat, grepl("ADN", bName)) 
index2 <- with(dat, grepl("2011-02-10_R2", pName)) 

Bây giờ tập con bằng cách sử dụng & điều hành:

dat[index1 & index2, ] 
     aName  bName   pName call alleles logRatio strength 
7 AX-11086564 D04_ADN103 2011-02-10_R2 BB  GG -1.898088 9.872966 
2

Corrected theo lời khuyên của Andrie. Tôi hy vọng điều này sẽ làm việc. :)

df[grepl("ADN", df$bName),] 
df[grepl("ADN", df$bName) & df$pName == "2011-02-10_R2",] 
+0

Cả hai báo cáo trả về một dataframe trống, không phải là hàng mong muốn 1 và 7. – Andrie

+0

Có, thực sự, bạn là đúng. Tôi cần nghỉ ngơi. :) – DrDom

0

Tôi đã thử nghiệm sử dụng Expresso và được sử dụng các kiểu regex kiểu .Net; bạn có thể phải tinh chỉnh hương vị regex của mình. Tôi cũng để lại khoảng trắng để dễ đọc; loại bỏ hoặc sử dụng cờ tùy chọn regex để bỏ qua.

Các regex cơ bản để nắm bắt tất cả các dòng là:

(?<aName> [\w-]+) \s+ (?<bName> [\w_]+) \s+ (?<pName> [\w-_]+) \s+ (?<call> \w+) \s+ (?<alleles> \w+) \s+ (?<logRatio> [\d\.-]+) \s+ (?<strength> [\d\.-]+) 

Từ đó, bạn chỉ cần tinh chỉnh regex cho thích hợp đặt tên nhóm chụp (s) để trích xuất chỉ đường mà bạn muốn.Các phiên bản sửa đổi để nắm bắt cách sử dụng các tiêu chí mà bạn đã cung cấp (bname chứa "ADN" và pName = "2011-02-10_R2") là:

(?<aName> [\w-]+) \s+ (?<bName> [\w_]*ADN[\w_]*) \s+ (?<pName> 2011-02-10_R2) \s+ (?<call> \w+) \s+ (?<alleles> \w+) \s+ (?<logRatio> [\d\.-]+) \s+ (?<strength> [\d\.-]+) 
0

Đây là một giải pháp khá tối thiểu sử dụng dplyr và magrittr mà tôi nghĩ là những gì bạn đang sau:

Data: 
library(magrittr) 
library(stringr) 
dat <- read.table(text=" 
aName bName pName call alleles logRatio strength 
        AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
        AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
        AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
        AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
        AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
        AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
        AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
        AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 
        ", header=TRUE) 

hàng có chứa ADN trong cột bname.

dat %>% 
    filter(str_detect(bName, "ADN") == TRUE) 

secondarily, tôi muốn tất cả các hàng có chứa ADN trong cột bname và rằng trận đấu 2011-02-10_R2 trong cột pName.

dat %>% 
    filter(str_detect(bName, "ADN") & pName == "2011-02-10_R2") 
Các vấn đề liên quan