Выберите строки, слова которых более одного раза соответствуют элементам данного массива - PullRequest
0 голосов
/ 12 марта 2020

У меня есть следующий массив строк символов:

text = c("not just #solar #wind, #geothermal but also now ocean power from waves", 
"Therefore we do not celebrate together Thanksgiving", "We obviously don't and cannot")

Я хотел бы получить два массива из text, то есть text1 и text2. Первый должен содержать только строки text, которые более одного раза соответствуют элементам в mydata:

mydata = c("No", "Not", "Don't", "cannot", "do not")

Например, text1 должен содержать:

We obviously don't and cannot

Вместо этого text2 должен содержать все остальные строки. Тогда:

not just #solar #wind, #geothermal but also now ocean power from waves, 
Therefore we do not celebrate together Thanksgiving

Я мог бы использовать grep, но:

grep(mydata,text)

возвращает:

integer(0)
Warning message:
 In grep(mydata, text) :
  argument 'pattern' has length > 1 and only the first element will be used

1 Ответ

3 голосов
/ 12 марта 2020

Вы подразумеваете, что в вашем вопросе не учитывается регистр.

text = c("not just #solar #wind, #geothermal but also now ocean power from waves", 
"Therefore we do not celebrate together Thanksgiving", "We obviously don't and cannot")

mydata <- paste("\\b(", paste(c("No", "Not", "Don't", "cannot", "do not"), collapse = "|"), ")\\b")

lens <- lengths(regmatches(text, gregexpr(mydata, text, ignore.case = TRUE)))

text[lens > 1]
# [1] "We obviously don't and cannot"
text[lens <= 1]
# [1] "not just #solar #wind, #geothermal but also now ocean power from waves"
# [2] "Therefore we do not celebrate together Thanksgiving"                   

Разница между gregexpr (вместе с regmatches) и gsub или grep заключается в том, что первое извлекает совпадения как отдельные строки, в то время как другие просто указывают на наличие каких-либо (без учета). Чтобы увидеть, что они делают:

gregexpr(mydata, text, ignore.case = TRUE)
# [[1]]
# [1] 1
# attr(,"match.length")
# [1] 3
# attr(,"index.type")
# [1] "chars"
# attr(,"useBytes")
# [1] TRUE
# [[2]]
# [1] 14
# attr(,"match.length")
# [1] 7
# attr(,"index.type")
# [1] "chars"
# attr(,"useBytes")
# [1] TRUE
# [[3]]
# [1] 14 24
# attr(,"match.length")
# [1] 5 6
# attr(,"index.type")
# [1] "chars"
# attr(,"useBytes")
# [1] TRUE

Это немного сложно переварить. Основной номер (не в атрибуте) указывает позицию в строке, которой соответствует шаблон; обратите внимание, что в [[3]] есть два совпадения. Атрибуты определяют длину совпадения.

Мы можем извлечь совпадения с помощью regmatches:

regmatches(text, gregexpr(mydata, text, ignore.case = TRUE))
# [[1]]
# [1] "not"
# [[2]]
# [1] "do not "
# [[3]]
# [1] "don't"  "cannot"

И отсюда lengths дает нам относительную длину каждого из них, представляя количество совпадений в каждой строке text.

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