#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. большое спасибо. это именно то, что я пытался сделать.