Filtre de dplyr (avec l'une des lignes)

Aug 18 2020

Je suis nouveau dans le monde R, ces jours-ci, j'ai un problème avec la fonction de filtre de dplyr.J'ai un df et un je dois filtrer les valeurs supérieures à un nombre, mais dans certaines lignes, j'ai des valeurs multiples (séparées par; ). Par exemple j'ai ce 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

Mon filtre est si un ou plusieurs dans value1 est supérieur ou égal à 3. J'utilise la fonction filter de dplyr car j'ai besoin de réaliser d'autres filtres pour le df. Ceci est mon code.

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

Mais dans ce cas, la fonction any considère toutes les valeurs du df (pas par ligne, comme je le pensais), donc, j'obtein all df et ce n'est pas correct.

J'ai besoin d'obtenir une ligne avec les identifiants 1, 2 et 4 pour cet exemple.

Je pense que je devrais vérifier par ligne et séparer par; , mais je ne sais pas comment faire cela avec la fonction de filtre de dplyr.

Merci beaucoup!

Réponses

1 akrun Aug 18 2020 at 02:00

Une option serait de diviser la 'valeur1' avec separate_rowsde tidyr, regroupés par 'ID', les filtergroupes ayant l' anyélément dans 'valeur1' supérieur ou égal à 3, puis summariseles colonnes en pasteing et en obtenant l' firstélément de 'valeur2'

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

Ou en utilisant mapavecstrsplit

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

Les données

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))