Обнаружение нескольких строк с помощью dplyr и stringr

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

Вот несколько примеров данных:

test.data <- data.frame(item = c("Apple", "Bear", "Orange", "Pear", "Two Apples"))
fruit <- c("Apple", "Orange", "Pear")
test.data
        item
1      Apple
2       Bear
3     Orange
4       Pear
5 Two Apples

Я бы хотел использовать что-то вроде:

test.data <- test.data %>% mutate(is.fruit = str_detect(item, fruit))

и получить

        item is.fruit
1      Apple        1
2       Bear        0
3     Orange        1
4       Pear        1
5 Two Apples        1

Очень простой тест работает

> str_detect("Apple", fruit)
[1]  TRUE FALSE FALSE
> str_detect("Bear", fruit)
[1] FALSE FALSE FALSE

Но я не могу заставить это работать над столбцом фрейма данных даже без dplyr:

> test.data$is.fruit <- str_detect(test.data$item, fruit)
Error in check_pattern(pattern, string) : 
  Lengths of string and pattern not compatible

Кто-нибудь знает как это сделать?


person r.bot    schedule 30.10.2014    source источник


Ответы (2)


str_detect принимает только шаблон длины 1. Либо превратите его в одно регулярное выражение, используя paste(..., collapse = '|'), либо используйте any:

sapply(test.data$item, function(x) any(sapply(fruit, str_detect, string = x)))
# Apple       Bear     Orange       Pear Two Apples
#  TRUE      FALSE       TRUE       TRUE       TRUE

str_detect(test.data$item, paste(fruit, collapse = '|'))
# [1]  TRUE FALSE  TRUE  TRUE  TRUE
person Robert Krzyzanowski    schedule 30.10.2014

Этот простой подход отлично подходит для ТОЧНЫХ совпадений:

test.data %>% mutate(is.fruit = item %in% fruit)
# A tibble: 5 x 2
        item is.fruit
       <chr>    <lgl>
1      Apple     TRUE
2       Bear    FALSE
3     Orange     TRUE
4       Pear     TRUE
5 Two Apples    FALSE

Этот подход работает для частичного сопоставления (вот вопрос):

test.data %>% 
rowwise() %>% 
mutate(is.fruit = sum(str_detect(item, fruit)))

Source: local data frame [5 x 2]
Groups: <by row>

# A tibble: 5 x 2
        item is.fruit
       <chr>    <int>
1      Apple        1
2       Bear        0
3     Orange        1
4       Pear        1
5 Two Apples        1
person Henrik    schedule 16.12.2015
comment
Это работает только при наличии точных совпадений, и в этом случае использование str_detect вместо == или in излишне. - person Alex Gold; 31.08.2017
comment
Ах, ты прав, Алекс. Думаю, я прочитал вопрос немного быстро. Я обновил ответ. - person Henrik; 11.09.2017