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:
<- read_tsv() %>% # Načti data
x select() %>% # Vyber sloupce
filter() %>% # Vyber řádky
ggplot() # Vykresli data
Uká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ě:
<- read_tsv()
x <- select(x)
x <- filter(x)
x <- ggplot(x) 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:
%>% weighted.mean(x,.) w
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.