Фильтр dplyr (с любой из строк)

#r #dplyr

#r #dplyr

Вопрос:

Я новичок в мире R, в эти дни у меня проблема с функцией фильтрации dplyr.У меня есть df и a, мне нужно отфильтровать значения, превышающие число, но в некоторых строках у меня есть кратные значения (разделенные символом ; ). Например, у меня есть этот df

 ID   value1    value2
1    1;0;3.4    4
2    3          5
3    0.5;2;1.3  0
4    5;0.1      3
  

Мой фильтр — это если одно или несколько значений в value1 больше или равно 3. Я использую функциональный фильтр dplyr, потому что мне нужно реализовать другие фильтры для df. Это мой код.

 filt <- df %>% filter(any(as.numeric(unlist(strsplit(value1,';',fixed=TRUE))) >=3))
  

Но в этом случае функция any учитывает все значения df (не по строкам, как я думал), поэтому я получаю все значения df, а это неверно.

Мне нужно получить строку с идентификаторами 1,2 и 4 для этого примера.

Я думаю, мне следует проверять по строке и разделять по ; , но я не знаю, как это сделать с помощью функции фильтрации dplyr.

Большое спасибо!

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

1. Используйте rowwise() перед фильтром, чтобы обработка производилась строка за строкой, или, что еще лучше, преобразуйте ваши данные в более «аккуратный» формат, используя что-то вроде tidyr::separate_rows

2. О, спасибо!! Мне действительно очень нравится это решение!

Ответ №1:

Вариантом было бы разделить ‘value1’ на separate_rows from tidyr , сгруппировать по ‘ID’, filter группы, имеющие any элемент в ‘value1’ больше или равный 3, затем summarise столбцы путем paste редактирования и получения first элемента ‘value2’

 library(dplyr)
library(tidyr)
df %>%
    separate_rows(value1, sep = ";", convert = TRUE) %>%
    group_by(ID) %>%
    filter(any(value1 >=3)) %>%
    summarise(value1 = str_c(value1, collapse=";"), value2 = first(value2))
# A tibble: 3 x 3
#     ID value1  value2
#  <int> <chr>    <int>
#1     1 1;0;3.4      4
#2     2 3            5
#3     4 5;0.1        3
  

Или использование map с strsplit

 library(purrr)
df %>% 
   filter(map_lgl(strsplit(value1, ";"), ~ any(as.numeric(.x) >=3)))
#   ID  value1 value2
#1  1 1;0;3.4      4
#2  2       3      5
#3  4   5;0.1      3
  

данные

 df <- structure(list(ID = 1:4, value1 = c("1;0;3.4", "3", "0.5;2;1.3", 
"5;0.1"), value2 = c(4L, 5L, 0L, 3L)), class = "data.frame", row.names = c(NA, 
-4L))