Фильтровать / искать в разных строках в r, которые сгруппированы по определенному столбцу

#r #search #filter #dplyr

#r #Поиск #Фильтр #dplyr

Вопрос:

У меня есть набор данных, похожий на приведенный ниже repex, где у каждого субъекта есть более одной строки для их хобби, любимой еды и специальности.

Я пытаюсь определить, например, тех, у кого походы — хобби, а мясо — еда. (тот, который соответствует этому критерию, является объектом c в примере ниже).

Есть ли способ сделать это в dplyr или другом пакете?

 
dd = structure(list(ID = c("a", "a", "a", "a", "b", "b", "b", "b", 
                      "b", "b", "c", "c", "c", "c", "c", "c"), itemType = c("hobby", 
                                                                            "hobby", "study", "food", "hobby", "hobby", "study", "study", 
                                                                            "food", "food", "hobby", "hobby", "study", "study", "study", 
                                                                            "food"), details = c("hiking, bike", "reading", "math, art", 
                                                                                                 "cheese, bread", "writing", "computer", "english", "science", 
                                                                                                 "meat, rice", "cheese", "reading", "swimming, hiking", "math, philosophy", 
                                                                                                 "computer", "social", "pasta, meat")), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                            -16L))


  

Если я просто попробую простой фильтр dplyr, как показано ниже, он, конечно, не будет работать, он не возвращает никаких элементов. есть ли еще один аргумент или что-то, что я могу добавить, чтобы заставить его работать?

Я никогда не использовал пакет базы данных, но будет ли это полезно в этом контексте?

 dd %>% 
  filter( str_detect( details, "hiking") amp;
            str_detect(details, "meat"))
  

Ответ №1:

Если нам нужно подмножество «ID», содержащее как «походы», «мясо» в «деталях», сделайте group_by «ID», а затем примените str_detect для обоих «походы», «мясо», оберните с any помощью) и используйте amp; или ,

 library(dplyr)
library(stringr)
dd %>%
  group_by(ID) %>%
  filter(any(str_detect(details, 'hiking')), any(str_detect(details, 'meat')))
  

-вывод

 # A tibble: 6 x 3
# Groups:   ID [1]
#  ID    itemType details         
#  <chr> <chr>    <chr>           
#1 c     hobby    reading         
#2 c     hobby    swimming, hiking
#3 c     study    math, philosophy
#4 c     study    computer        
#5 c     study    social          
#6 c     food     pasta, meat     
  

Обновить

Если мы хотим дополнительно выполнить обнаружение на основе подгруппы, одним из вариантов является подмножество столбца == и применение str_detect только этих элементов

 dd %>% 
     group_by(ID) %>%
     filter(any(str_detect(details[itemType == 'hobby'], 'hiking')),
            any(str_detect(details[itemType == 'food'], 'meat')))
# A tibble: 6 x 3
# Groups:   ID [1]
#  ID    itemType details         
#  <chr> <chr>    <chr>           
#1 c     hobby    reading         
#2 c     hobby    swimming, hiking
#3 c     study    math, philosophy
#4 c     study    computer        
#5 c     study    social          
#6 c     food     pasta, meat     
 
  

Или base R с помощью ave и grepl

 subset(dd, as.logical(ave(details, ID, 
  FUN = function(x) any(grepl('hiking', x)) amp; any(grepl('meat', x)))))
  

Причина, по которой он не вернул ни одной строки, заключается в том, что ни один элемент в «деталях» не имеет как «походов», так и «мяса», поскольку amp; выполняется поэлементное сравнение. Вместо этого нам нужно использовать amp; включение any элементов в «деталях» для каждого «идентификатора»

Комментарии:

1. Спасибо. group_by работает и возвращает объект c, который соответствует обоим критериям. Знаете ли вы о способе указать, что я ищу строку «походы» в разделе хобби и строку «мясо» в разделе еда? в этом повторном выражении это не будет иметь большого значения, но в данных, которые у меня есть, это поможет, если я смогу указать. еще раз спасибо за ответ.

2. большое спасибо. это именно то, что я пытался сделать.