使用regexp选择R dataframe中的行

时间:2012-03-01 17:19:21

标签: regex r 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

例如,我想要一个仅包含ADN列中包含bName的行的数据框。其次,我希望列ADN中包含bName的所有行与列2011-02-10_R2中的pName匹配。

我尝试使用函数grep()agrep()等更多但没有成功......

7 个答案:

答案 0 :(得分:29)

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

注意“&” (而不是“&&”没有矢量化)和“==”(而不是“=”,这是作业)。

请注意,您可以使用:

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

...并且在内部函数中使用时可能更好,但是,对于dat $ pName为NA的任何行,它将返回NA值。可以通过向逻辑表达式添加& !is.na(dat$pName)来删除该缺陷(某些人认为是一个特性)。

答案 1 :(得分:8)

你走了。

首先重新创建数据:

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)

接下来,使用grepl构建匹配的逻辑索引:

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

现在使用&运算符的子集:

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 :(得分:3)

根据Andrie的建议纠正。我希望这应该有效。 :)

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

答案 3 :(得分:0)

我使用Expresso进行了测试并使用了.Net风格的正则表达式;你可能需要调整你的正则表达式的味道。为了便于阅读,我还留下了空白;删除或使用正则表达式选项标记忽略。

捕获所有行的基本正则表达式是:

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

由此,您只需调整适当的命名捕获组的正则表达式,以仅提取所需的行。使用您给出的标准捕获的修改版本(bName包含“ADN”和pName =“2011-02-10_R2”)是:

(?<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\.-]+ ) 

答案 4 :(得分:0)

使用dplyr和magrittr这是一个非常小的解决方案,我认为这就是你所追求的:

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)
  

列bName中包含ADN的行。

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

其次,我希望列bName中包含ADN的所有行   并且在列pName中匹配2011-02-10_R2。

dat %>%
  filter(str_detect(bName, "ADN") & pName == "2011-02-10_R2") 

答案 5 :(得分:-1)

与上面相同的逻辑

df %>% 
  filter(grepl("ADN", bName) & grepl("2011-02-10_R2", pName))
#     aName      bName         pName call alleles  logRatio     strength
# 1 AX-11086564 D04_ADN103 2011-02-10_R2   BB      GG -1.898088 9.872966

答案 6 :(得分:-2)

为什么不呢:

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

你也可以这样做:

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