Grep с использованием символьного вектора с несколькими шаблонами

Я пытаюсь использовать grep, чтобы проверить, присутствует ли вектор строк в другом векторе или нет, и выводить значения, которые присутствуют (соответствующие шаблоны).

У меня есть такой кадр данных:

FirstName Letter   
Alex      A1
Alex      A6
Alex      A7
Bob       A1
Chris     A9
Chris     A6

У меня есть вектор строк, который можно найти в столбцах "Letter", например: c("A1", "A9", "A6").

Я хотел бы проверить, присутствует ли какая-либо строка в векторе шаблона в столбце "Письмо". Если они есть, я хотел бы получить уникальные значения.

Проблема в том, что я не знаю, как использовать grep с несколькими шаблонами. Я пробовал:

matches <- unique (
    grep("A1| A9 | A6", myfile$Letter, value=TRUE, fixed=TRUE)
)

Но это дает мне 0 матчей, которые не соответствуют действительности, любые предложения?

Ответ 1

В дополнение к комментарию @Marek о том, что вы не включаете fixed==TRUE, вам также не нужно иметь пробелы в вашем регулярном выражении. Это должно быть "A1|A9|A6".

Вы также отмечаете, что существует множество шаблонов. Предполагая, что они находятся в векторе

toMatch <- c("A1", "A9", "A6")

Затем вы можете создать свое регулярное выражение непосредственно из этого.

matches <- unique (grep(paste(toMatch,collapse="|"), 
                        myfile$Letter, value=TRUE))

Ответ 2

Хорошие ответы, однако не забывайте о filter() от dplyr:

patterns <- c("A1", "A9", "A6")
>your_df
  FirstName Letter
1      Alex     A1
2      Alex     A6
3      Alex     A7
4       Bob     A1
5     Chris     A9
6     Chris     A6

result <- filter(your_df, grepl(paste(patterns, collapse="|"), Letter))

>result
  FirstName Letter
1      Alex     A1
2      Alex     A6
3       Bob     A1
4     Chris     A9
5     Chris     A6

Ответ 3

Вы пробовали функции match() или charmatch()?

Пример использования:

match(c("A1", "A9", "A6"), myfile$Letter)

Ответ 4

Основываясь на сообщении Брайана Дигга, вот две полезные функции для фильтрации списков:

#Returns all items in a list that are not contained in toMatch
#toMatch can be a single item or a list of items
exclude <- function (theList, toMatch){
  return(setdiff(theList,include(theList,toMatch)))
}

#Returns all items in a list that ARE contained in toMatch
#toMatch can be a single item or a list of items
include <- function (theList, toMatch){
  matches <- unique (grep(paste(toMatch,collapse="|"), 
                          theList, value=TRUE))
  return(matches)
}

Ответ 5

Не уверен, что этот ответ уже появился...

Для конкретного шаблона в вопросе вы можете просто сделать это с помощью одного вызова grep(),

grep("A[169]", myfile$Letter)

Ответ 6

Я предлагаю писать немного script и выполнять несколько запросов с помощью Grep. Я никогда не нашел способ поиска нескольких шаблонов и, поверьте, я посмотрел!

Итак, ваш файл оболочки со встроенной строкой:

 #!/bin/bash 
 grep *A6* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A7* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A8* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";

Затем запустите, набрав myshell.sh.

Если вы хотите передать строку в командной строке, сделайте это так, с аргументом оболочки - это bash notation btw:

 #!/bin/bash 
 $stingtomatch = "${1}";
 grep *A6* "${stingtomatch}";
 grep *A7* "${stingtomatch}";
 grep *A8* "${stingtomatch}";

И так далее.

Если имеется много шаблонов, вы можете поместить их в цикл for.

Ответ 7

Чтобы добавить к ответу Брайана Диггса.

другой способ использования grepl вернет фрейм данных, содержащий все ваши значения.

toMatch <- myfile$Letter

matches <- myfile[grepl(paste(toMatch, collapse="|"), myfile$Letter), ]

matches

Letter Firstname
1     A1      Alex 
2     A6      Alex 
4     A1       Bob 
5     A9     Chris 
6     A6     Chris

Может быть, немного чище... может быть?