Filtro di dplyr (con una qualsiasi delle righe)

Aug 18 2020

Sono nuovo nel mondo R, in questi giorni ho problemi con la funzione di filtro di dplyr.Ho un df e un devo filtrare i valori maggiori di un numero, ma in alcune righe ho valori multipli (separati da; ). Ad esempio ho questo 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

Il mio filtro è se uno o più in value1 è maggiore o uguale a 3. Uso la funzione filter di dplyr perché ho bisogno di realizzare altri filtri per df. Questo è il mio codice.

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

Ma in questo caso la funzione any considera tutti i valori di df (non per riga, come pensavo), quindi ottengo tutto df e questo non è corretto.

Ho bisogno di ottenere una riga con ID 1,2 e 4 per questo esempio.

Penso che dovrei controllare per riga e separare per; , ma non so come farlo con la funzione di filtro di dplyr.

Grazie mille!

Risposte

1 akrun Aug 18 2020 at 02:00

Un'opzione potrebbe essere quella di dividere il "valore1" con separate_rowsda tidyr, raggruppato per "ID", i filtergruppi con anyelemento in "valore1" maggiore o uguale a 3, quindi summarisele colonne pasteing e ottenendo l' firstelemento di "valore2"

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

O usando mapconstrsplit

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

dati

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