Отфильтровать все строки со словом рядом с указанным словом в R - PullRequest
5 голосов
/ 13 февраля 2020

У меня есть столбец со строковым содержимым

temp <- c(NA, NA, "grocery pantry all offers", NA, "grocery offers today low price", 
"grocery offers today low price", "tide soap", "tide soap bar", 
"tide detergent powders 2kg", NA, "tide", "tide detergent powders 2kg", 
"liquid detergent tide brand")

Я хочу создать биграмму со словами, которые находятся рядом с Tide. Для этого мне нужно отфильтровать слова, которые находятся рядом с течением. Левая или правая сторона. Например, в приведенном выше выводе будет

tide soap
tide soap
tide detergent
tide detergent
detergent tide
tide brand

Любая помощь?

Ответы [ 5 ]

5 голосов
/ 13 февраля 2020

Если вы используете пакет quanteda, это просто. Вы указываете, на какое слово вы хотите нацелиться, и решаете, сколько слов на левой / правой стороне цели вы хотите.

library(quanteda)

kwic(x = temp, pattern = "tide", window = 1) %>% 
as.data.frame

  docname from to       pre keyword      post pattern
1   text7    1  1              tide      soap    tide
2   text8    1  1              tide      soap    tide
3   text9    1  1              tide detergent    tide
4  text11    1  1              tide              tide
5  text12    1  1              tide detergent    tide
6  text13    3  3 detergent    tide     brand    tide
2 голосов
/ 13 февраля 2020

Вы можете использовать пакет tidytext для разделения текста на биграммы и фильтрации для tide.

library(tidytext)
library(dplyr)
library(tibble)

temp %>% 
  enframe(name = "id") %>%
  filter(str_detect(value, "tide")) %>%
  unnest_tokens(bigrams, value, token = "ngrams", n = 2) %>%
  filter(str_detect(bigrams, "tide"))

# A tibble: 6 x 2
     id bigrams       
  <int> <chr>         
1     5 tide soap     
2     6 tide soap     
3     7 tide detergent
4    10 tide detergent
5    11 detergent tide
6    11 tide brand  
2 голосов
/ 13 февраля 2020

Это то, что вы хотите?

library(stringr)

str_extract(temp, "(tide [:alnum:]*)|([:alnum:]* tide)")

В основном говорится, что извлекаются строки, которые либо "tide", затем пробел , а затем комбинация букв и цифр ([:alnum:]) любой длины (*) или (|) наоборот ([:alnum:]* tide).

Кстати: если вы хотите, впоследствии вы можете удалить NA s с помощью

x <- str_extract(temp, "(tide [:alnum:]*)|([:alnum:]* tide)")
x[!is.na(x)]
0 голосов
/ 13 февраля 2020

Вот базовое решение R

r <- unlist(Filter(length,
                   t(do.call(cbind,
                             lapply(c("\\w+\\stide","tide\\s\\w+"), 
                                    function(p) regmatches(temp,gregexpr(p,temp)))))))

такое, что

> r
[1] "tide soap"      "tide soap"      "tide detergent" "tide detergent" "detergent tide" "tide brand"  
0 голосов
/ 13 февраля 2020

Это еще один вариант, использующий tidyverse, который захватывает что-либо до и / или после «прилива».

stringr::str_match_all(temp, "(\\w+)?\\s?tide\\s?(\\w+)?") %>%
   purrr::reduce(rbind) %>%
   as.data.frame %>%
   dplyr::filter_all(dplyr::any_vars(!is.na(.)))

                    V1        V2        V3
1            tide soap      <NA>      soap
2            tide soap      <NA>      soap
3       tide detergent      <NA> detergent
4                 tide      <NA>      <NA>
5       tide detergent      <NA> detergent
6 detergent tide brand detergent     brand
...