2014-10-30 59 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