14.1 Práce s tidyverse
14.1.1 Trubky/pipes
S pomocí tidyverse je možné psát velmi dobře srozumitelný kód. Hadley Wickham, který stojí za vytvořením podstatné části tidyverse, při popisu balíků mluví o konceptu “gramatiky práce s daty” a “gramatice vizualizace dat.”
Průběh datové analýzy můžeme popsat jako sekvenci úkonů. Například:
- Načti data.
- Vezmi načtenou tabulku a vyber z ní několik sloupců.
- Vezmi upravenou tabulku a vyber pouze řádky, které splňují určité podmínky.
- Vezmi upravenou tabulku a na jejím základě vykresli obrázek.
- Výsledek ulož do proměnné
x.
Každý krok přitom využívá výsledek kroku předchozího. Pro podobné řetezení kroků využívá tidyverse speciální funkci %>% (tzv. trubku/pipe), které spojuje dva kroky. Výstup prvního kroku vkládá jako vstup do následujícího kroku. Předchozí sekvenci kroků bychom tedy mohli schématicky zapsat následujícím způsobem:
x <- read_tsv() %>% # Načti data
select() %>% # Vyber sloupce
filter() %>% # Vyber řádky
ggplot() # Vykresli dataUkázka kódu není funkční – funkce nemají zadané žádné parametry, ale ukazuje logiku celého přístupu. Výsledný kód svou strukturou připomíná strukturu psaného jazyka. Intrukce přehledně plyne zleva do prava, podobně jako text v knize.
Bez použití funkce %>% by postup vypadal následovně:
x <- read_tsv()
x <- select(x)
x <- filter(x)
x <- ggplot(x)Výsledek by byl zcela identický (a provedení kódu u velkých tabulek o maličko rychlejší). Výhodou trubek je však čitelnost a přehlednost. Praxe ukazuje, že mít jasný a čístý kód je v praxi datové analýzy často důležitější než marginální ztráta rychlosti.
V tomto kurzu budeme od této chvíle často používat funkci %>%. Pokud si oblíbíte používání trubek, můžete se podívat na balík magrittr, který kromě %>% implementuje i další trubkoidní funkce.
14.1.1.1 Placeholder “.”
Funkce %>% ja nastavená tak, že obsah, který ji protéká vždy umisťuje do prvního parametru přijímající funkce. To je skoro vždy žádoucí chování, ale ne vždy. Modifikovat je ho možné s použítím symbolu ., který určuje místo, na které má trubka přenášený obsah umístit.
Můžeme si například představit situaci, kdy máme vektory x a w. Chceme spočítát vážený průměr x, ale trubkou nám putuje vektor vah w. Požadovaného výsledku dosáhneme takto:
w %>% weighted.mean(x,.)14.1.2 Subsetování
tidyverse, konkrétně balík dplyr obsahuje funkce pro subsetování. Zběžně se nyní seznámí s funkcí select(), která slouží k výběru sloupců. Na jejím příkladě si ukážeme, jak se v tidyverse zachází se jmény sloupců.
Základní syntaxe select() je triviální:
select(.data, ...)Prvním parametrem je vstupní tabulka. V parametru ... jsou specifikovány sloupce.
Jako ukázkovou tabulku budeme používat us_rent_income z balíku tidyr:
us_rent_income## # A tibble: 104 × 5
## GEOID NAME variable estimate moe
## <chr> <chr> <chr> <dbl> <dbl>
## 1 01 Alabama income 24476 136
## 2 01 Alabama rent 747 3
## 3 02 Alaska income 32940 508
## 4 02 Alaska rent 1200 13
## 5 04 Arizona income 27517 148
## 6 04 Arizona rent 972 4
## 7 05 Arkansas income 23789 165
## 8 05 Arkansas rent 709 5
## 9 06 California income 29454 109
## 10 06 California rent 1358 3
## # … with 94 more rows
Poznámka: Speciální metody výběru sloupců jsou implementovány v balíku tidyselect, Ten si však nemusíte vždy loadovat. Balíky z tidyverse si vše vyřeší samy.
14.1.2.1 Non-standard evaluation a identifikace jménem sloupce
tidyverse používá tzv. nestandardní evaluaci. Ta je výhodná zvláště při interaktivní práci s daty. Praktickým dopadem je, že se jména sloupců píšou bez úvozovek. První možností jak identifikovat sloupec je tedy jménem bez úvozovek. Můžeme vybrat jeden:
us_rent_income %>%
select(variable)## # A tibble: 104 × 1
## variable
## <chr>
## 1 income
## 2 rent
## 3 income
## 4 rent
## 5 income
## 6 rent
## 7 income
## 8 rent
## 9 income
## 10 rent
## # … with 94 more rows
Nebo více sloupců:
us_rent_income %>%
select(variable,estimate)## # A tibble: 104 × 2
## variable estimate
## <chr> <dbl>
## 1 income 24476
## 2 rent 747
## 3 income 32940
## 4 rent 1200
## 5 income 27517
## 6 rent 972
## 7 income 23789
## 8 rent 709
## 9 income 29454
## 10 rent 1358
## # … with 94 more rows
14.1.2.2 Identifikace pozicí
Vedle jména je možné pro identifikaci sloupce použít číslo jeho pozice:
us_rent_income %>%
select(1,2,4)## # A tibble: 104 × 3
## GEOID NAME estimate
## <chr> <chr> <dbl>
## 1 01 Alabama 24476
## 2 01 Alabama 747
## 3 02 Alaska 32940
## 4 02 Alaska 1200
## 5 04 Arizona 27517
## 6 04 Arizona 972
## 7 05 Arkansas 23789
## 8 05 Arkansas 709
## 9 06 California 29454
## 10 06 California 1358
## # … with 94 more rows
14.1.2.3 Speciální funkce
Funkce, které potřebují specifikaci sloupců umí pracovat se speciálními funkcemi, které budou fungovat pouze v jejich rámci. Základní speciální funkce jsou dvě: - a :.
Funkce - umožňuje negativní výběr – “vyber všechno až na.” Následující volání funkce select() tak vrátí všechny sloupce až na GEOID a NAME:
us_rent_income %>%
select(-GEOID,-NAME)## # A tibble: 104 × 3
## variable estimate moe
## <chr> <dbl> <dbl>
## 1 income 24476 136
## 2 rent 747 3
## 3 income 32940 508
## 4 rent 1200 13
## 5 income 27517 148
## 6 rent 972 4
## 7 income 23789 165
## 8 rent 709 5
## 9 income 29454 109
## 10 rent 1358 3
## # … with 94 more rows
Funkce : umožňuje specifikovat rozsah sloupců. To lze využít pokud chceme například vybrat sloupce GEOID a všechny sloupce mezi variable a moe:
us_rent_income %>%
select(GEOID, variable:moe)## # A tibble: 104 × 4
## GEOID variable estimate moe
## <chr> <chr> <dbl> <dbl>
## 1 01 income 24476 136
## 2 01 rent 747 3
## 3 02 income 32940 508
## 4 02 rent 1200 13
## 5 04 income 27517 148
## 6 04 rent 972 4
## 7 05 income 23789 165
## 8 05 rent 709 5
## 9 06 income 29454 109
## 10 06 rent 1358 3
## # … with 94 more rows
Speciální funkce fungují i při identifikace sloupců jejich pozicí…
us_rent_income %>%
select(-1,-2)## # A tibble: 104 × 3
## variable estimate moe
## <chr> <dbl> <dbl>
## 1 income 24476 136
## 2 rent 747 3
## 3 income 32940 508
## 4 rent 1200 13
## 5 income 27517 148
## 6 rent 972 4
## 7 income 23789 165
## 8 rent 709 5
## 9 income 29454 109
## 10 rent 1358 3
## # … with 94 more rows
us_rent_income %>%
select(1,3:5)## # A tibble: 104 × 4
## GEOID variable estimate moe
## <chr> <chr> <dbl> <dbl>
## 1 01 income 24476 136
## 2 01 rent 747 3
## 3 02 income 32940 508
## 4 02 rent 1200 13
## 5 04 income 27517 148
## 6 04 rent 972 4
## 7 05 income 23789 165
## 8 05 rent 709 5
## 9 06 income 29454 109
## 10 06 rent 1358 3
## # … with 94 more rows
…a je možné je kombinovat
us_rent_income %>%
select(-variable:-moe)## # A tibble: 104 × 2
## GEOID NAME
## <chr> <chr>
## 1 01 Alabama
## 2 01 Alabama
## 3 02 Alaska
## 4 02 Alaska
## 5 04 Arizona
## 6 04 Arizona
## 7 05 Arkansas
## 8 05 Arkansas
## 9 06 California
## 10 06 California
## # … with 94 more rows
14.1.2.4 Funkce pomocníčci: select helpers
Balík tidyselect obshauje funkce, které umožňují identifikovat sloupce jinak než přímým zadáním jména nebo pozice:
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 sloupcelast_col()vrací poslední sloupec
Tyto funkce opět fungují jenom “uvnitř” kompatibilních funkcí. K subsetování se v mírně větším detailu vrátíme znovu v kapitole věnované balíku dplyr.