10.3 Filtrace a detekce prvků vektorů
Balík purrr implementuje i několik funkcí určených k filtraci hodnot vektorů.
Funkce keep(.x, .p, ...)
vrací ty prvky vektoru .x
, pro které predikátová funkce .p()
vrací hodnotu TRUE
.
Naopak funkce discard(.x, .p, ...)
vrací ty prvky vektoru .x
, pro které predikátová funkce .p()
vrací hodnotu FALSE
, tj. zahazuje prvky, pro které podmínka platí.
Funkce head_while(.x, .p, ...)
a tail_while(.x, .p, ...)
vrací všechny prvky od začátku nebo od konce, pro které funkce .p()
souvisle vrací hodnotu TRUE
. Ve všech těchto funkcích nemusí být .p
funkce: může to být i logický vektor stejné délky jako .x
nebo pravostranná formule, která vrací logickou hodnotu. Jejich použití ukazuje následující příklad:
<- 1:10
v <- function(x) x %% 2 != 0 # vrací TRUE, když je číslo liché
is.odd keep(v, is.odd) # výběr lichých hodnot z vektoru v
## [1] 1 3 5 7 9
keep(v, ~ . %% 2 != 0) # totéž pomocí pravostranné formule
## [1] 1 3 5 7 9
discard(v, is.odd) # vrácení vektoru v bez lichých hodnot
## [1] 2 4 6 8 10
head_while(v, ~ . < 5) # vrácení prvních hodnot menších než 5
## [1] 1 2 3 4
Funkce compact(.x, .p = identity)
umožňuje ze seznamu vypustit ty prvky, které mají buď hodnotu NULL
nebo nulovou délku.
compact(list(a = 1, b = 2, c = NULL, d = 4, e = numeric(0)))
## $a
## [1] 1
##
## $b
## [1] 2
##
## $d
## [1] 4
Parametr .p
umožňuje zadat funkci nebo formuli. Pokud tato funkce vrátí NULL
nebo prázdný vektor, pak funkce compact()
vynechá odpovídající prvek. Zbývající hodnoty však nejsou funkcí .p
nijak transformované. Použití ukazuje triviální příklad:
compact(1:5, .p = ~ .[. < 4]) # zachová pouze prvky menší než 4
## [1] 1 2 3
Funkce detect(.x, .f, ..., .dir = c("forward", "backward"), .default = NULL)
vrací první položku vektoru .x
, pro kterou vrací .f
hodnotu TRUE
. Funkce detect_index(.x, .f, ..., .dir = c("forward", "backward"))
vrací index této položky. Stejně jako výše může .f
být funkce nebo pravostranná formule, která vrací logickou hodnotu.
detect(v, is.odd) # první lichá hodnota ve vektoru v
## [1] 1
detect(v, ~ . > 1) # první hodnota větší než 1
## [1] 2
detect_index(v, is.odd) # index prvního lichého prvku vektoru v
## [1] 1
detect_index(v, ~ . > 1) # index prvního prvku většího než 1
## [1] 2
Dva zbývající parametry určují směr, odkud se budou hodnoty hledat (parametr .dir
, implicitně zepředu), a jaká hodnota se vrátí, pokud žádný prvek vektoru nesplňuje zadaný predikát (parametr .default
).
Funkce every(.x, .p, ...)
a some(.x, .p, ...)
zobecňují logické funkce all()
a any()
. every()
vrací TRUE
, pokud zadaná predikátová funkce .p
vrací pro každý prvek vektoru .x
hodnotu TRUE
; funkce some()
vrací TRUE
, pokud .f
vrací TRUE
aspoň pro jeden prvek .x
. Pomocí těchto funkcí můžeme např. otestovat, zda tabulka df
obsahuje aspoň jeden numerický sloupec (some()
) nebo jen numerické sloupce (every()
):
%>% some(is.numeric) # obsahuje df aspoň jeden numerický sloupec? df
## [1] TRUE
%>% every(is.numeric) # obsahuje df pouze numerické sloupce? df
## [1] FALSE
Funkce has_element(.x, .y)
zobecňuje operátor %in%
. Vrací TRUE
, pokud vektor .x
obsahuje objekt .y
.
<- list(1:5, "a") # prvky x jsou vektory 1:5 a "a"
x has_element(x, 1:5)
## [1] TRUE
has_element(x, 3)
## [1] FALSE
Balík purrr nabízí i užitečnou funkci negate()
, která transformuje zadanou funkci tak, že vrací její negaci. Pokud bychom chtěli pomocí keep()
a naší funkce is.odd()
vybrat sudé prvky, museli bychom použít formuli:
keep(1:10, ~ !is.odd(.))
## [1] 2 4 6 8 10
Pomocí funkce negate()
však můžeme negovat celou predikátovou funkci is.odd()
:
keep(1:10, negate(is.odd))
## [1] 2 4 6 8 10