Regex для сопоставления предложений с повторением смежных и несмежных слов в R - PullRequest
1 голос
/ 28 февраля 2020

У меня есть датафрейм с предложениями; в некоторых предложениях слова используются более одного раза:

df <- data.frame(Turn = c("well this is what the grumble about do n't they ?",
                          "it 's like being in a play-group , in n it ?",
                          "oh is that that steak i got the other night ?",
                          "well where have the middle sized soda stream bottle gone ?",
                          "this is a half day , right ? needs a full day",
                          "yourself , everybody 'd be changing your hair in n it ?",
                          "cos he finishes at four o'clock on that day anyway .",
                          "no no no i 'm dave and you 're alan .",
                          "yeah , i mean the the film was quite long though",
                          "it had steve martin in it , it 's a comedy",
                          "oh it is a dreary old day in n it ?",
                          "no it 's not mother theresa , it 's saint theresa .",
                          "oh have you seen that face lift job he wants ?",
                          "yeah bolshoi 's right so which one is it then ?"))

Я хочу сопоставить те предложения, в которых слово, любое слово повторяется один или несколько раз.

РЕДАКТИРОВАТЬ 1 :

Повторяющиеся слова ** могут * быть смежными, но это не обязательно. Вот почему Регулярное выражение для последовательных повторяющихся слов не дает ответа на мой вопрос.

У меня был скромный успех с этим кодом:

df[grepl("(\\w+\\b\\s)\\1{1,}", df$Turn),]
[1] well this is what the grumble about do n't they ?      
[2] it 's like being in a play-group , in n it ?           
[3] oh is that that steak i got the other night ?          
[4] this is a half day , right ? needs a full day          
[5] yourself , everybody 'd be changing your hair in n it ?
[6] no no no i 'm dave and you 're alan .                  
[7] yeah , i mean the the film was quite long though       
[8] it had steve martin in it , it 's a comedy             
[9] oh it is a dreary old day in n it ?

Успех просто скромный, потому что некоторые предложения совпадают, что не должно совпадать , например, yourself , everybody 'd be changing your hair in n it ?, в то время как другие не совпадают, что должно быть , например, no it 's not mother theresa , it 's saint theresa .. Как улучшить код для получения точных совпадений?

Ожидаемый результат :

df
                                                         Turn
2                it 's like being in a play-group , in n it ?
3               oh is that that steak i got the other night ?
5               this is a half day , right ? needs a full day
8                       no no no i 'm dave and you 're alan .
9            yeah , i mean the the film was quite long though
10                 it had steve martin in it , it 's a comedy
11                        oh it is a dreary old day in n it ?
12        no it 's not mother theresa , it 's saint theresa .

РЕДАКТИРОВАТЬ 2 :

Другой вопрос заключается в том, как определить точное количество повторных слов. Вышеупомянутое, несовершенное, регулярное выражение соответствует словам, которые повторяются по крайней мере один раз. Если я изменю квантификатор на {2}, таким образом, ища тройное вхождение слова, я получу этот код и такой результат:

df[grepl("(\\w+\\b\\s)\\1{2}", df$Turn),]
[1] no no no i 'm dave and you 're alan .         # "no" occurs 3 times

Но опять же совпадение несовершенно, поскольку ожидаемый результат будет:

[1] no no no i 'm dave and you 're alan .          # "no" occurs 3 times
[2] it had steve martin in it , it 's a comedy     # "it" occurs 3 times

Любая помощь очень ценится!

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Я бы предпочел сделать еще один проход для решения этой задачи. Сначала я добавил групповую переменную в исходный фрейм данных. Затем я посчитал, сколько раз каждое слово появляется в каждом предложении, и создал фрейм данных, который составляет mytemp.

library(tidyverse)

mutate(df, id = 1:n()) -> df

mutate(df, id = 1:n()) %>% 
mutate(word = strsplit(x = Turn, split = " ")) %>% 
unnest(word) %>% 
count(id, word, name = "frequency", sort = TRUE) -> mytemp  

. Используя этот фрейм данных, легко определить предложения. Я подгруппировал данные и получил id для предложений, в которых слово появляется три раза. Я так же идентифицировал слова, которые появлялись более одного раза и получали id. Наконец, я делю исходные данные, используя числа id в three и twice.

# Search words that appear 3 times 

three <- filter(mytemp, frequency == 3) %>% 
         pull(id) %>% 
         unique()

# Serach words that appear more than once.

twice <- filter(mytemp, frequency > 1) %>% 
         pull(id) %>% 
         unique()

# Go back to the original data and handle subsetting
filter(df, id %in% three)

  Turn                                          id
  <chr>                                      <int>
1 no no no i 'm dave and you 're alan .          8
2 it had steve martin in it , it 's a comedy    10

filter(df, id %in% twice)

  Turn                                                   id
  <chr>                                               <int>
1 it 's like being in a play-group , in n it ?            2
2 oh is that that steak i got the other night ?           3
3 this is a half day , right ? needs a full day           5
4 no no no i 'm dave and you 're alan .                   8
5 yeah , i mean the the film was quite long though        9
6 it had steve martin in it , it 's a comedy             10
7 oh it is a dreary old day in n it ?                    11
8 no it 's not mother theresa , it 's saint theresa .    12
1 голос
/ 29 февраля 2020

Опция для определения точного количества повторяющихся слов.

извлечение предложений, в которых одни и те же слова встречаются 3 раза

  1. change regex .

    (\ s? \ B \ w + \ b \ s) (. * \ 1) {2}

    (\ s? \ B \ w + \ b \ s), захваченный Группой 1

    • \ s? : пробел появляется ноль или один раз.
    • \ b \ w + \ b: точный символ слова.
    • \ s: пробел встречается один раз.

      (. * \ 1), захваченный Группой 2

      • (. * \ 1): любые символы, которые встречаются ноль или более раз, прежде чем группа 1 снова совпадет.

      • (. * \ 1) { 2}: группа 2 совпадает дважды.

Код

df$Turn[grepl("(\\s?\\b\\w+\\b\\s)(.*\\1){2}", df$Turn, perl = T)]
# [1] "no no no i 'm dave and you 're alan ."     
# [2] "it had steve martin in it , it 's a comedy"
Используйте strsplit(split="\\s") разбить предложения на слова.
  • используйте sapply и table для подсчета количества вхождений слов в каждом элементе списка, а затем выберите предложения, удовлетворяющие требованию.

Код

library(magrittr)
df$Turn %<>% as.character()
s<-strsplit(df$Turn,"\\s") %>% sapply(.,function(i)table(i) %>% .[.==3])
df$Turn[which(s!=0)]
# [1] "no no no i 'm dave and you 're alan ."     
# [2] "it had steve martin in it , it 's a comedy"

Надеюсь, это поможет вам:)

...