2014-10-30 55 views
3

我试图结合dplyr和stringr来检测数据框中的多个模式。我想使用dplyr,因为我想测试许多不同的列。用dplyr和stringr检测多个字符串

下面是一些样本数据:

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 

有谁知道如何做到这一点?

回答

11

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 
11

这个简单的方法能正常工作准确匹配:

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 
+0

这只适用于有精确匹配的情况,在这种情况下,使用'str_detect'而不是'=='或'in'是多余的。 – 2017-08-31 15:57:30

+0

啊,你说得对,Alex。我猜,我读了这个问题有点快。我已经更新了答案。 – Henrik 2017-09-11 13:50:51