Подтвердить что ты не робот

Использование regexp для выбора строк в 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

Например, я хочу, чтобы фреймворк данных содержал только строки, содержащие ADN в столбце bName. Во-вторых, я хотел бы, чтобы все строки, содержащие ADN в столбце bName и соответствующие 2011-02-10_R2 в столбце pName.

Я попытался использовать функции grep(), agrep() и многое другое, но без успеха...

4b9b3361

Ответ 1

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

Примечание "&" (а не "& &", который не является векторизованным) и что "==" (а не "=", которое является присвоением).

Обратите внимание, что вы могли бы использовать:

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

... и это может быть предпочтительнее при использовании внутри функций, однако, это вернет значения NA для любых строк, где $pName - NA. Этот дефект (который рассматривается как функция) может быть удален путем добавления & !is.na(dat$pName) к логическому выражению.

Ответ 2

Здесь вы идете.

Сначала заново создайте свои данные:

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

Ответ 3

Исправлено по совету Андри. Надеюсь, это сработает.:)

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

Ответ 4

Я тестировал с помощью Expresso и использовал регулярные выражения .Net; вам может потребоваться настроить для вашего регулярного выражения. Я также оставил пробелы для удобочитаемости; удалите или используйте флаг опции regex для игнорирования.

Основное регулярное выражение для захвата всех строк:

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

Ответ 5

Это довольно минимальное решение, использующее 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)

содержащие ADN в столбце bName.

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

Во-вторых, мне бы хотелось, чтобы все строки, содержащие ADN в столбце bName и которые соответствуют 2011-02-10_R2 в столбце pName.

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

Ответ 6

Почему не просто:

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

Вы также можете сделать это:

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