5.6 Operátor trubka (|> a %>%)

Při datové analýze se často hodí používat operátor “trubka.” R má dnes dvě základní verze tohoto operátoru: operátor |>, který je součástí základního R (od verze 4.1) a operátor %>% definovaný v balíku magrittr (načtou jej však i některé další balíky, jako např. dplyr). RStudio zavádí pro “trubku” speciální klávesovou zkratku Ctrl-Shift-M. V menu Tools\(\rightarrow\)Global Options...\(\rightarrow\)Code\(\rightarrow\)Editing si můžete vybrat, zda se použije nativní verze, nebo verze z balíku magrittr.

Trubka umožňuje zapsat výraz se složitě zanořenými funkcemi poněkud čitelnějším způsobem. Řekněme, že chceme na proměnnou x aplikovat funkci f() a na výsledek funkci g(). Standardním způsobem bychom to zapsali takto:

g(f(x))

Operátor trubka umožní výraz přepsat do čitelnější podoby:

library(magrittr)
x |> f() |> g()  # nebo
x %>% f() %>% g()

Tato syntaxe lépe vystihuje to, co chceme provést. Doslova říká: vezmi proměnnou x a vlož ji jako první argument do funkce f(). Výsledek vlož jako první argument do funkce g(). Výrazy x |> f() a x %>% f() jsou tedy ekvivalentní výrazu f(x). Funkce f() a g() samozřejmě mohou obsahovat i další parametry. Ty se zařadí za proměnnou x, takže x |> mean(na.rm = TRUE) je ekvivalentní výrazu mean(x, na.rm = TRUE); stejně tak výraz s %>%.

Mnoho funkcí, se kterými budeme pracovat, je přizpůsobeno používání trubek, takže data do nich vstupují jako první argument. Některé funkce však berou data na jiné pozici. V takovém případě není možné použít základní operátor |>, který dosadí výraz na levé straně vždy na první pozici funkce na pravé straně. Verze %>% z balíku magrittr umožňuje toto omezení obejít pomocí speciální proměnné tečka (.). Do té trubka vloží vstupní data. Díky tomu je možné zapsat výraz f(y, x) jako x %>% f(y, .) a f(y, z = x) jako x %>% f(y, z = .).

Pozor- Pokud je specialni promenna tecka pouzita ve funkci primo, pak trubka nevlozi promennou x na prvni misto ve funkci (jak jsme to videli v predchozich pripadech). Pokud je vsak tecka pouzita jako soucast nejakeho vyrazu, pak trubka promennou x na prvni misto ve funkci vlozi! To znamena, ze x %>% f(y = nrow(.), z = ncol(.)) je ekvivalentni s f(x, y = nrow(x), z = ncol(x)). Pokud tomu chcete zabranit, musite funkci f() uzavrit do bloku. Takze f(y = nrow(x), z = ncol(x)) musime zapsat pomoci trubky jako x %>% {f(y = nrow(.), z = ncol(.))}.2

Podívejme se na typický příklad použití trubek. Řekněme, že máme tabulku df (zde si ji nasimulujeme) a chceme pro každou unikátní hodnotu identifikátoru x spočítat průměrné hodnoty proměnných y a z. To můžeme udělat např. takto:

library(tibble)
library(dplyr)
df <- tribble(
    ~x, ~y, ~z,
     1,  1,  1,
     1,  2,  3,
     2,  3,  5,
     2,  4,  6,
     3,  5,  7
)
df |> group_by(x) |> summarize(my = mean(y), mz = mean(z))
## # A tibble: 3 × 3
##       x    my    mz
##   <dbl> <dbl> <dbl>
## 1     1   1.5   2  
## 2     2   3.5   5.5
## 3     3   5     7

Výraz s použitím trubky %>% dá stejný výsledek:

df %>% group_by(x) %>% summarize(my = mean(y), mz = mean(z))

Detaily fungovani tohoto kodu si vysvetlime v kapitole 16. Nyní nás zajímá jen fungování trubek: proměnná df se nejdříve vloží do funkce group_by() a vyhodnotí se jako group_by(df, x). Výsledek této operace se pak vloží na první místo do funkce summarize() a vyhodnotí se jako summarize(., my = mean(y), mz = mean(z)), kde tečka označuje výsledek předchozího výpočtu, tj. funkce group_by().

Balik magrittr definuje i nektere dalsi operatory. Seznamit se s nimi muzete na webu baliku http://magrittr.tidyverse.org/ a v kapitole "Pipes" ve Wickham and Grolemund (2017) dostupne na http://r4ds.had.co.nz/pipes.html. Doporučuji však omezit se více méně jen na základní operátory |> a %>%.

References

Wickham, Hadley, and Garrett Grolemund. 2017. R forData Science. 1st ed. Sebastopol, California, USA- O'Reilly. http://r4ds.had.co.nz/.

  1. Nativni trubka |> je mene flexibilni, je vsak rychlejsi. Ve vetsine pripadu na tom nezalezi, protoze volani trubek trva v radu nano az mikrosekund. Pokud vsak opakovane simulujete velke mnozstvi vzorku dat, muze byt i takovy drobny rozdil uzitecny.↩︎