Как извлечь все совпадающие шаблоны (слова в строке) в столбце фрейма данных? - PullRequest
1 голос
/ 16 июня 2020

У меня есть два фрейма данных. one ( txt.df ) имеет столбец с текстом, из которого я хочу извлечь фразы ( текст ). Другой ( wrd.df ) имеет столбец с фразами ( фраза ). оба являются большими фреймами данных со сложными текстами и строками, но скажем:

txt.df <- data.frame(id = c(1, 2, 3, 4, 5),
                     text = c("they love cats and dogs", "he is drinking juice", 
                              "the child is having a nap on the bed", "they jump on the bed and break it",
                              "the cat is sleeping on the bed"))


wrd.df <- data.frame(label = c('a', 'b', 'c', 'd', 'e', 'd'),
                     phrase = c("love cats", "love dogs", "juice drinking", "nap on the bed", "break the bed",
                              "sleeping on the bed"))

то, что мне наконец нужно, это txt.df с другим столбцом, который содержит метки обнаруженных фраз.

то, что я пробовал, создавало столбец в wrd.df, в котором я токенизировал фразы, подобные этой

wrd.df$token <- sapply(wrd.df$phrase, function(x) unlist(strsplit(x, split = " ")))

, а затем пытался написать настраиваемую функцию для sapply по столбцу токенов с помощью grepl / str_detect получить имена (метки) тех, которые все были истинными

Extract.Fun <- function(text, df, label, token){
  for (i in token) {
  truefalse[i] <- sapply(token[i], function (x) grepl(x, text))
  truenames[i] <- names(which(truefalse[i] == T))
  removedup[i] <- unique(truenames[i])
  return(removedup)
}

, а затем добавить эту настраиваемую функцию в мой текст txt.df $, чтобы иметь новый столбец с метками.

txt.df$extract <- sapply(txt.df$text, function (x) Extract.Fun(x, wrd.df, "label", "token"))

но я плохо разбираюсь в пользовательских функциях и действительно застрял. Буду признателен за любую помощь. PS Было бы очень хорошо, если бы у меня были частичные совпадения, такие как «выпить сок» и «сломать кровать» ... но это не приоритет ... отлично с оригинальными.

1 Ответ

2 голосов
/ 16 июня 2020

Если вам нужно сопоставить точные фразы, regex_join() из пакета fuzzyjoin - это то, что вам нужно.

fuzzyjoin::regex_join( txt.df, wrd.df, by = c(text = "phrase"), mode = "left" )

  id                                 text label              phrase
1  1              they love cats and dogs     a           love cats
2  2                 he is drinking juice  <NA>                <NA>
3  3 the child is having a nap on the bed     d      nap on the bed
4  4    they jump on the bed and break it  <NA>                <NA>
5  5       the cat is sleeping on the bed     d sleeping on the bed

Если вы хотите сопоставить все слова, я думаю, вы можете построить регулярное выражение из фраз, описывающих такое поведение ...

update

#build regex for phrases
#done by splitting the phrases to individual words, and then paste the regex together
wrd.df$regex <- unlist( lapply( lapply( strsplit( wrd.df$phrase, " "), 
                                        function(x) paste0( "(?=.*", x, ")", collapse = "" ) ),
                                function(x) paste0( "^", x, ".*$") ) )


fuzzyjoin::regex_join( txt.df, wrd.df, by = c(text = "regex"), mode = "left" )

  id                                 text label              phrase                                        regex
1  1              they love cats and dogs     a           love cats                     ^(?=.*love)(?=.*cats).*$
2  1              they love cats and dogs     b           love dogs                     ^(?=.*love)(?=.*dogs).*$
3  2                 he is drinking juice     c      juice drinking                ^(?=.*juice)(?=.*drinking).*$
4  3 the child is having a nap on the bed     d      nap on the bed      ^(?=.*nap)(?=.*on)(?=.*the)(?=.*bed).*$
5  4    they jump on the bed and break it     e       break the bed            ^(?=.*break)(?=.*the)(?=.*bed).*$
6  5       the cat is sleeping on the bed     d sleeping on the bed ^(?=.*sleeping)(?=.*on)(?=.*the)(?=.*bed).*$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...