Найти документы с двумя словами в заданной близости в R - PullRequest
0 голосов
/ 01 октября 2019

У меня есть фрейм данных с переменной text, которая включает в себя стенограммы новостей. Я хочу идентифицировать стенограммы, которые включают слово «республиканец» ИЛИ «демократ» И одно из списка слов в заданной близости (скажем, в пределах 5 слов). Например, если одним из списка слов является «Конгресс», я хочу подобрать следующие стенограммы:

  • «Республиканцы в Конгрессе сегодня проголосовали по законопроекту». (близость <5) </li>
  • «Демократы в Конгрессе сегодня проголосовали по законопроекту». (близость <5) </li>

И я НЕ хочу брать эти стенограммы:

  • «Сегодня республиканцы приняли законопроект о выделении средств Конгрессу». (близость> 5)
  • «Сегодня демократы приняли законопроект о выделении средств Конгрессу». (близости> 5)

Я могу сопоставить список слов без ограничения близости следующим образом:

transcripts <- data.frame(text=c("Republicans in congress today voted on a bill","Republicans today passed a bill to allocate funds for Congress")
dictionary <- data.frame(word=c("Congress","Capitol"))

transcripts_subset <- transcripts %>%
  filter(grepl(paste(dictionary$word, collapse="|"), text))

, и я попытался найти регулярное выражение, чтобы сделать это правильно, новыдает ошибку:

transcripts_subset <- transcripts %>%
   filter(grepl("\b(paste(dictionary$dehumanizing, collapse="|"))(?:\\W+\\w+){0,5}?\\W+(Republican|Democrat)\b", text))
Error in "\b ..." : 
  operations are possible only for numeric, logical or complex types

Как я могу сделать эту работу?

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Ваш dplyr код фильтра выглядит нормально, так что вот только бит регулярного выражения:

dictionary <- data.frame(word=c("Congress","Capitol"), stringsAsFactors = FALSE)

pattern_after  <- paste0("\\b(", paste0(dictionary$word, collapse="|"), ")\\W+(?:\\w+\\W+){0,5}?(Republican(s)*|Democrat(s)*)")
pattern_before <- paste0("\\b(Republican(s)*|Democrat(s)*)\\W+(?:\\w+\\W+){0,5}?", paste0(dictionary$word, collapse="|"), collapse="|")
pattern <- paste0(c(pattern_after, pattern_before), collapse="|")
pattern
#> [1] "\\b(Congress|Capitol)\\W+(?:\\w+\\W+){0,5}?(Republican(s)*|Democrat(s)*)|\\b(Republican(s)*|Democrat(s)*)\\W+(?:\\w+\\W+){0,5}?Congress|Capitol"


grepl(pattern, "Republicans in congress today voted on a bill", perl = TRUE, ignore.case = TRUE)
#> [1] TRUE

grepl(pattern, "Democrats today passed a bill to allocate funds for Congress", perl = TRUE, ignore.case = TRUE)
#> [1] FALSE

grepl(pattern, "A Democrat in Congress", perl = TRUE, ignore.case = TRUE)
#> [1] TRUE

Создано в 2019-10-01 пакетом Представить (v0.3.0)

Чтобы разобраться в этом, регулярное выражение для поиска двух слов, разделенных от 0 до 5 других слов в R, равно

"\\bword1\\W+(?:\\w+\\W+){0,5}word2"

  • \\b - это граница слова, означающая пробел, пунктуацию или конец строки.
  • \\W+ - это один или несколько несловесных символов (т. Е. Границы слова или что-то еще)
  • \\w+ означает слово один или несколько символов, то есть последовательность букв или цифр
  • (?:\\w+\\W+) - это группа, состоящая из символов слова, за которыми следуют не слова (т. Е. Слова с пробелами)
  • {0,5} указывает, что группа соответствует от 0 до 5 раз

Вам необходимо установить perl = TRUE, чтобы это работало. "Republican(s)*" означает, что «республиканец» либо следует за «с», либо нет. Два отдельных шаблона должны убедиться, что он работает независимо от того, упоминается ли слово или республиканец / демократ первым.

1 голос
/ 01 октября 2019

Вы можете попробовать следующее, которое разбивает вашу строку и проверяет grep, где находятся слова в словаре. Если они <5 они выбраны.

transcripts[sapply(strsplit(as.character(transcripts$text), " "), grep
 , pattern=paste(dictionary$word, collapse="|"), ignore.case = TRUE) < 5,]
#[1] Republicans in congress today voted on a bill

#Or using sub to get the first 5 words
transcripts[sapply(sub("((\\S+\\s*){0,5}).*", "\\1", transcripts$text), grepl
 , pattern=paste(dictionary$word, collapse="|"), ignore.case = TRUE),]

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