16.1 Slovesa pracující s jednou tabulkou
16.1.1 Výběr řádků (pozorování)
Základní funkcí, která umožňuje výběr řádků je filter()
. Podobně jako většina funkcí z balíku dplyr má extrémně jednoduchou syntax:
Vstupem funkce je tabulka (.data
) a jeden nebo více logických predikátů. Výstupem funkce je podmnožina řádků, která splňuje všechny zadané predikáty.
Například se můžeme chtít podívat na letadla, která vyrobil Airbus nebo Boeing a mají více než dva motory:
## # A tibble: 2 x 9
## tailnum year type manufacturer model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N281AT NA Fixed wing mu… AIRBUS INDUST… A340-… 4 375 NA Turbo-…
## 2 N670US 1990 Fixed wing mu… BOEING 747-4… 4 450 NA Turbo-…
Vybrány byly pouze řádky splňující všechny podmínky najednou. Následující volání filter()
, které spojuje dvě výše použité podmínky do jedné logickým AND (&
) proto vrátí stejný výsledek:
## # A tibble: 2 x 9
## tailnum year type manufacturer model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N281AT NA Fixed wing mu… AIRBUS INDUST… A340-… 4 375 NA Turbo-…
## 2 N670US 1990 Fixed wing mu… BOEING 747-4… 4 450 NA Turbo-…
Podmínky použité ve funkci filter()
musí po vyhodnocení vracet logické hodnoty TRUE
/FALSE
. Ve filter()
tedy můžeme používat funkce, které vracejí logickou hodnotu.
Například nás mohou zajímat všechna letadla z rodiny A340. Budeme tedy chtít vybrat všechny řádky, u nichž proměnná model
začíná na “A340”. Kromě balíku dplyr budeme potřebovat i stringr:
## # A tibble: 1 x 9
## tailnum year type manufacturer model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N281AT NA Fixed wing mu… AIRBUS INDUST… A340-… 4 375 NA Turbo-…
Je možné používat i funkce, které nevracejí logické hodnoty. V takové případě je však nutné jejich výsledek na logickou proměnou transformovat. Řekněme, že by nás zajímala letadla, kde na jeden motor připadá méně než 10 sedadel:
## # A tibble: 39 x 9
## tailnum year type manufacturer model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N201AA 1959 Fixed wing s… CESSNA 150 1 2 90 Recipro…
## 2 N202AA 1980 Fixed wing m… CESSNA 421C 2 8 90 Recipro…
## 3 N315AT NA Fixed wing s… JOHN G HESS AT-5 1 2 NA 4 Cycle
## 4 N347AA 1985 Rotorcraft SIKORSKY S-76A 2 14 NA Turbo-s…
## 5 N350AA 1980 Fixed wing m… PIPER PA-31-… 2 8 162 Recipro…
## 6 N364AA 1973 Fixed wing m… CESSNA 310Q 2 6 167 Recipro…
## 7 N365AA 2001 Rotorcraft AGUSTA SPA A109E 2 8 NA Turbo-s…
## 8 N376AA 1978 Fixed wing s… PIPER PA-32R… 1 7 NA Recipro…
## 9 N377AA NA Fixed wing s… PAIR MIKE E FALCON… 1 2 NA Recipro…
## 10 N378AA 1963 Fixed wing s… CESSNA 172E 1 4 105 Recipro…
## # … with 29 more rows
Ve speciálních případech je užitečné vybírat řádky ne podle splnění určitých podmínek, ale podle jejich polohy. Pro tyto případy je v balíku dplyr obsažena funkce slice()
, která jako argument přijímá čísla řádku, nebo rozsah řádků:
## # A tibble: 5 x 9
## tailnum year type manufacturer model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N10156 2004 Fixed wing mu… EMBRAER EMB-1… 2 55 NA Turbo-…
## 2 N102UW 1998 Fixed wing mu… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 3 N103US 1999 Fixed wing mu… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 4 N104UW 1999 Fixed wing mu… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 5 N10575 2002 Fixed wing mu… EMBRAER EMB-1… 2 55 NA Turbo-…
16.1.2 Výběr sloupců (proměnných)
Pro výběr sloupců slouží funkce select()
. Syntax je podobná jako v případě filter()
:
Do select()
vstupuje tabulka a identifikace sloupců, které mají být vybrány. Například:
## # A tibble: 3,322 x 2
## tailnum manufacturer
## <chr> <chr>
## 1 N10156 EMBRAER
## 2 N102UW AIRBUS INDUSTRIE
## 3 N103US AIRBUS INDUSTRIE
## 4 N104UW AIRBUS INDUSTRIE
## 5 N10575 EMBRAER
## 6 N105UW AIRBUS INDUSTRIE
## 7 N107US AIRBUS INDUSTRIE
## 8 N108UW AIRBUS INDUSTRIE
## 9 N109UW AIRBUS INDUSTRIE
## 10 N110UW AIRBUS INDUSTRIE
## # … with 3,312 more rows
Příklad ukazuje první a základní možnost, jak identifikovat sloupec – a to jeho jménem. select()
však umožňuje specifikovat sloupec i pomocí čísla pozice.
Následující volání funkce select()
tak vrací stejný výsledek, jako tomu byl v případě identifikace sloupců jejich jménem.
## # A tibble: 3,322 x 2
## tailnum manufacturer
## <chr> <chr>
## 1 N10156 EMBRAER
## 2 N102UW AIRBUS INDUSTRIE
## 3 N103US AIRBUS INDUSTRIE
## 4 N104UW AIRBUS INDUSTRIE
## 5 N10575 EMBRAER
## 6 N105UW AIRBUS INDUSTRIE
## 7 N107US AIRBUS INDUSTRIE
## 8 N108UW AIRBUS INDUSTRIE
## 9 N109UW AIRBUS INDUSTRIE
## 10 N110UW AIRBUS INDUSTRIE
## # … with 3,312 more rows
## [1] "tailnum" "year" "type" "manufacturer" "model"
## [6] "engines" "seats" "speed" "engine"
16.1.2.1 Funkce select()
a speciální funkce
Při identifikaci sloupců je možné využít speciální funkce. Některé fungují pouze “uvnitř” select()
a některých dalších funkcí z tidyverse.
První taková funkce je :
. Umožňuje specifikovat rozsah sloupců, místo vypisování všech prvků. Všechny následující volání tak vrací stejný výsledek:
planes %>%
select(1,2,3,4,8)
planes %>%
select(tailnum, year, type, manufacturer, speed)
planes %>%
select(1:4, 8)
planes %>%
select(tailnum:manufacturer, speed)
Další speciální funkcí je -
(mínus). Tato funkce umožňuje “negativní” výběr. Při jejím použití není sloupec zahrnut, ale naopak vypuštěn:
## # A tibble: 3,322 x 4
## model engines seats engine
## <chr> <int> <int> <chr>
## 1 EMB-145XR 2 55 Turbo-fan
## 2 A320-214 2 182 Turbo-fan
## 3 A320-214 2 182 Turbo-fan
## 4 A320-214 2 182 Turbo-fan
## 5 EMB-145LR 2 55 Turbo-fan
## 6 A320-214 2 182 Turbo-fan
## 7 A320-214 2 182 Turbo-fan
## 8 A320-214 2 182 Turbo-fan
## 9 A320-214 2 182 Turbo-fan
## 10 A320-214 2 182 Turbo-fan
## # … with 3,312 more rows
Speciální funkce je možné kombinovat – je například možné vypustit sloupce identifikované rozsahem (:
):
## # A tibble: 3,322 x 4
## model engines seats engine
## <chr> <int> <int> <chr>
## 1 EMB-145XR 2 55 Turbo-fan
## 2 A320-214 2 182 Turbo-fan
## 3 A320-214 2 182 Turbo-fan
## 4 A320-214 2 182 Turbo-fan
## 5 EMB-145LR 2 55 Turbo-fan
## 6 A320-214 2 182 Turbo-fan
## 7 A320-214 2 182 Turbo-fan
## 8 A320-214 2 182 Turbo-fan
## 9 A320-214 2 182 Turbo-fan
## 10 A320-214 2 182 Turbo-fan
## # … with 3,312 more rows
Výsledné tabulky jsou pochopitelně shodné.
Obě tyto speciální funkce vyžadují přesnou specifikaci jména nebo pozice sloupce. V reálném životě občas pracujeme s poněkud vágnějším zadáním. Mohli bychom chtít například vybrat všechny sloupce, které obsahují informace o motorech. Ty jsou v tabulce planes
dva engine
(typ motoru) a engines
(počet motorů).
První možností je samozřejmě možné použít následující volání a vybrat sloupce jejich výčtem:
To však není praktické v případě, že pracujeme s větším množstvím sloupců, jejichž názvy jsou systematické. V tom případě je užitečné sáhnout po select helpers (funkcích pomocníčcích chcete-li). dplyr jich nabízí hned několik:
starts_with()
vybírá sloupce, jejichž jméno začíná na řetězec, který je argumentem funkcestarts_with()
ends_with()
vybírá sloupce, jejichž jméno končí na řetězec, který je argumentem funkceends_with()
contains()
vybírá sloupce, jejichž jméno obsahuje řetězec, který je argumentem funkcecontains()
matches()
vybírá sloupce, jejichž jméno odpovídá zadanému regulárnímu výrazunum_range()
slouží pro výběr sloupců, jejichž jméno je tvořeno kombinací řetězce a čísla – napříkladtrial_1
,trial_2
,…one_of()
vrátí sloupce, jejichž jména jsou obsažena ve vektoru, který je vstupem funkceeverything()
vrací všechny sloupce – užitečné zejména při řazení sloupců
Pro výběr proměnných se vztahem k motorům lze použít hned tři funkce:
planes %>%
select(starts_with("engine"))
planes %>%
select(contains("engine"))
planes %>%
select(matches("^engine"))
První a třetí varianta vybere všechny sloupce, které začínají na “engine”. Druhé variantě postačí k výběru, že řetězec “engine” se vyskytuje kdekoliv ve jméně sloupce.
Select helpers mohou být kombinováni se všemi ostatními způsoby identifikace sloupců:
## # A tibble: 3,322 x 3
## tailnum engines engine
## <chr> <int> <chr>
## 1 N10156 2 Turbo-fan
## 2 N102UW 2 Turbo-fan
## 3 N103US 2 Turbo-fan
## 4 N104UW 2 Turbo-fan
## 5 N10575 2 Turbo-fan
## 6 N105UW 2 Turbo-fan
## 7 N107US 2 Turbo-fan
## 8 N108UW 2 Turbo-fan
## 9 N109UW 2 Turbo-fan
## 10 N110UW 2 Turbo-fan
## # … with 3,312 more rows
Select helper s velmi specifickým využitím je everything()
, které slouží k vybrání všeho. Nebo lépe všeho ostatního. Pokud z nějakého důvodu chceme změnit pořadí sloupců v tabulce, potom se hodí právě everything()
.
## # A tibble: 3,322 x 9
## engine engines tailnum year type manufacturer model seats speed
## <chr> <int> <chr> <int> <chr> <chr> <chr> <int> <int>
## 1 Turbo-f… 2 N10156 2004 Fixed wing m… EMBRAER EMB-1… 55 NA
## 2 Turbo-f… 2 N102UW 1998 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 3 Turbo-f… 2 N103US 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 4 Turbo-f… 2 N104UW 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 5 Turbo-f… 2 N10575 2002 Fixed wing m… EMBRAER EMB-1… 55 NA
## 6 Turbo-f… 2 N105UW 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 7 Turbo-f… 2 N107US 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 8 Turbo-f… 2 N108UW 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 9 Turbo-f… 2 N109UW 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## 10 Turbo-f… 2 N110UW 1999 Fixed wing m… AIRBUS INDUS… A320-… 182 NA
## # … with 3,312 more rows
Změní pořadí sloupců tak, že na první pozici přesune engine
a engines
a následně do tabulky vyskládá všechny ostatní sloupce. Díky everything()
není nutné jejich jména vypisovat.
16.1.2.2 Výběr a přejmenování sloupce
Jednou ze speciálních funkcí je i =
. To slouží v select()
pro přejmenování. Například volání
## # A tibble: 3,322 x 2
## tailnum company
## <chr> <chr>
## 1 N10156 EMBRAER
## 2 N102UW AIRBUS INDUSTRIE
## 3 N103US AIRBUS INDUSTRIE
## 4 N104UW AIRBUS INDUSTRIE
## 5 N10575 EMBRAER
## 6 N105UW AIRBUS INDUSTRIE
## 7 N107US AIRBUS INDUSTRIE
## 8 N108UW AIRBUS INDUSTRIE
## 9 N109UW AIRBUS INDUSTRIE
## 10 N110UW AIRBUS INDUSTRIE
## # … with 3,312 more rows
vybere sloupce tailnum
a manufacturer
. Sloupec manufacturer
však zároveň přejmenuje na company
.
Speciálně pro přejmenovávání sloupců je v dplyr obsažena funkce rename()
(fakticky jde jen o lehkou mutaci select()
). Ta sloupce nevybírá, ale jen přejmenovává. Použití =
je v ní povinné:
## Error: All renaming inputs must be named.
Po opravě získáme správný výsledek:
## # A tibble: 3,322 x 9
## tailnum year type company model engines seats speed engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N10156 2004 Fixed wing mu… EMBRAER EMB-14… 2 55 NA Turbo-…
## 2 N102UW 1998 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 3 N103US 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 4 N104UW 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 5 N10575 2002 Fixed wing mu… EMBRAER EMB-14… 2 55 NA Turbo-…
## 6 N105UW 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 7 N107US 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 8 N108UW 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 9 N109UW 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## 10 N110UW 1999 Fixed wing mu… AIRBUS INDU… A320-2… 2 182 NA Turbo-…
## # … with 3,312 more rows
Tabulka obsahuje všechny sloupce, ale jeden z nich byl přejmenován.
16.1.2.3 Výběr a přejmenování sloupců podle jejich charakteristik
dplyr obsahuje dodatečné mutace funkce select()
. Zajímavé jsou zejména dva.
select_if()
umožňuje vybírat sloupce podle toho, zda splňují zadanou podmínku. V následujícím případě jsou vybrány pouze sloupce, které obsahují numerickou (tedy double nebo integer) proměnnou:
## # A tibble: 3,322 x 4
## year engines seats speed
## <int> <int> <int> <int>
## 1 2004 2 55 NA
## 2 1998 2 182 NA
## 3 1999 2 182 NA
## 4 1999 2 182 NA
## 5 2002 2 55 NA
## 6 1999 2 182 NA
## 7 1999 2 182 NA
## 8 1999 2 182 NA
## 9 1999 2 182 NA
## 10 1999 2 182 NA
## # … with 3,312 more rows
Parametrem select_if()
je funkce vracející logickou hodnotu (TRUE
/FALSE
), která je použita pro vyhodnocení. Klíčové je, že parametrem je funkce samotná a ne hodnota funkcí vrácená. Co to znamená v praxi napoví následující volání, které se od předchozího příkazu liší pouze minimálně:
## Error in is.numeric(): 0 arguments passed to 'is.numeric' which requires 1
Výsledek není tabulka s vybranými sloupci, ale chyba. Kde vznikl problém? V korektním volání byla funkce is.numeric
použita bez závorek. select_if()
si takto zadanou funkci vyhodnotí vnitřně a dodá očekávaný výsledek. V druhém případě se R nejprve pokusí is.numeric()
vyhodnotit a výsledek předat select_if()
. To nemůže fungovat – funkce neví, nad jakým sloupcem se má vyhodnotit.
V select_if()
je možné používat uživatelem definované funkce i lambda funkce – viz následující příklad ve kterém obě volání select_if()
budou vracet stejný výsledek: všechny sloupce tabulky planes
.
return_true <- function(x) return(TRUE)
planes %>%
select_if(return_true)
planes %>%
select_if(function(x) return(TRUE))
Kromě funkce, která rozhoduje o vybrání sloupce má select_if()
i další argument .funs
:
Tento argument slouží pro přejmenovávání a jeho použití není povinné. Je opět možné použít jméno funkce nebo lambda funkci.
Následující volání vybere všechny numerické sloupce a přejmenuje je – jména sloupců budou napsána velkými písmeny.
## # A tibble: 3,322 x 4
## YEAR ENGINES SEATS SPEED
## <int> <int> <int> <int>
## 1 2004 2 55 NA
## 2 1998 2 182 NA
## 3 1999 2 182 NA
## 4 1999 2 182 NA
## 5 2002 2 55 NA
## 6 1999 2 182 NA
## 7 1999 2 182 NA
## 8 1999 2 182 NA
## 9 1999 2 182 NA
## 10 1999 2 182 NA
## # … with 3,312 more rows
Dodatečné argumenty pro funkci, která provádí přejmenování lze předat přes ...
.
select_if()
má variantu rename_if()
, která vrátí všechny sloupce, ale jen ty, které odpovídají zadané podmínce jsou přejmenovány:
## # A tibble: 3,322 x 9
## tailnum YEAR type manufacturer model ENGINES SEATS SPEED engine
## <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
## 1 N10156 2004 Fixed wing m… EMBRAER EMB-1… 2 55 NA Turbo-…
## 2 N102UW 1998 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 3 N103US 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 4 N104UW 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 5 N10575 2002 Fixed wing m… EMBRAER EMB-1… 2 55 NA Turbo-…
## 6 N105UW 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 7 N107US 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 8 N108UW 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 9 N109UW 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## 10 N110UW 1999 Fixed wing m… AIRBUS INDUST… A320-… 2 182 NA Turbo-…
## # … with 3,312 more rows
Pokud je potřeba přejmenovat hromadně všechny sloupce a ne jen některé, potom je možné použít select_all()
nebo rename_all()
. Obě funkce jsou zaměnitelné.
Další užitečnou variantou select()
je select_at()
:
Funkce ze vstupní tabulky .tbl
vybere sloupce specifikované v parametru .var
. Pro specifikaci může být použit vektor řetězců jmen sloupců, vektor jejich pozic:
## # A tibble: 3,322 x 2
## tailnum year
## <chr> <int>
## 1 N10156 2004
## 2 N102UW 1998
## 3 N103US 1999
## 4 N104UW 1999
## 5 N10575 2002
## 6 N105UW 1999
## 7 N107US 1999
## 8 N108UW 1999
## 9 N109UW 1999
## 10 N110UW 1999
## # … with 3,312 more rows
Další variantou je specifikace sloupců pomocí seznamu (list) generovaného pomocí funkce vars()
. Tato varianta je zajímavá zejména pro pokročilejší uživatele a programátory.
Stejného výsledku jako u výše uvedeného příkladu využití select_at()
je možné dosáhnout například s pomocí select helper one_of()
:
select_at()
však přináší možnost vybrané sloupce hromadně přejmenovat s pomocí funkce definované v parametru .funs
.