Súčastou práce každého data analytika (štatistika) je aj príprava dát na analýzu alebo úprava do požadovaného tvaru. V praxi sa len zriedkavo stáva, že štatistik obdrží dáta pripravené na analýzu. Používatelia prostredia R si môžu prácu s dátami výrazne uľahčiť pomocou knižnice dplyr
.
library(dplyr) # inštalácia cez install.packages("dplyr")
V nasledujúcom texte predstavím “len” základné funkcie knižnice, ich osvojením dokážete upravovať dáta v jednoduchých krokoch do požadovanej formy prehľadnejšie a rýchlejšie ako za použitia base R príkazov. Funkcie sú pomenované rozumne podľa toho čo robia:
filter()
- filtruj riadky,arrange()
- zoraď riadky,select()
- vyber stĺpce,mutate()
- “mutuj” vytvor nový stĺpec,sumarize()
- “sumarizuj” spočítaj,group_by()
- zoskup do skupín.Práca s dátami vyžaduje aj použitie viacerých funkcií v naviazanosti za sebou. Používať funkcie naväzujúce v slede za sebou sa dá viacerými spôsobmi. Zameráme sa na tzv “pipeline” v značení %>%
, ktorá sa dá voľne interpretovať ako prepájaj funkcie z ľava do prava. Na poradí použitia funkcií záleží. Spôsob čítania %>%
kódu bude rozpísané v riadkoch kódu za #.
Na trénovanie a ukážku využijeme dáta mpg
z knižnice ggplot2
. Ktoré obsahujú údaje o autách a ich výrobcovi (manufacturer), modeli (model), objem motora (displ), rok výroby (year), počet valcov (cyt), prevodovka (trans), náhon (drv), dojazd v meste a na diaľnici (cty a hwy), palivo (fl) a trieda (class).
library(ggplot2) # inštalácia cez install.packages("ggplot2")
data(mpg) # zavoláme dáta
mpg # vypíšeme
## # A tibble: 234 x 11
## manufacturer model displ year cyl trans drv cty hwy fl
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr>
## 1 audi a4 1.80 1999 4 auto(l… f 18 29 p
## 2 audi a4 1.80 1999 4 manual… f 21 29 p
## 3 audi a4 2.00 2008 4 manual… f 20 31 p
## 4 audi a4 2.00 2008 4 auto(a… f 21 30 p
## 5 audi a4 2.80 1999 6 auto(l… f 16 26 p
## 6 audi a4 2.80 1999 6 manual… f 18 26 p
## 7 audi a4 3.10 2008 6 auto(a… f 18 27 p
## 8 audi a4 quat… 1.80 1999 4 manual… 4 18 26 p
## 9 audi a4 quat… 1.80 1999 4 auto(l… 4 16 25 p
## 10 audi a4 quat… 2.00 2008 4 manual… 4 20 28 p
## # ... with 224 more rows, and 1 more variable: class <chr>
V nasledujúcich častiach budeme pracovať s formátom tibble
. Pre užívateľa sa tento formát skoro v ničom nelíši od base R data.frame
. Výhoda nového formátu je skrytá vo vnútri, viacej detailov nájdete tu. Pre užívateľa je výhoda v zobrazení, po vypísaní ľahko môžete prečítať počet stĺpcov a riadkov, formát každého stĺpca a vidieť prvých 10 riadkov.
Asi najčastejšie potrebujeme len filtrovať, funkcia dovoľuje filtrovať aj za početných podmienok. Narpíklad. Chceme vybrať autá, ktoré boli vyrobené v roku 2008 a majú dojazd na diaľnici na galón paliva viacej ako 27 míľ.
filter(mpg, year == 2008, hwy > 27) # prvý argument sú dáta, potom môžete vkladať podmienky na filtrovanie.
## # A tibble: 33 x 11
## manufacturer model displ year cyl trans drv cty hwy fl
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr>
## 1 audi a4 2.00 2008 4 manual… f 20 31 p
## 2 audi a4 2.00 2008 4 auto(a… f 21 30 p
## 3 audi a4 quat… 2.00 2008 4 manual… 4 20 28 p
## 4 chevrolet malibu 2.40 2008 4 auto(l… f 22 30 r
## 5 chevrolet malibu 3.50 2008 6 auto(l… f 18 29 r
## 6 honda civic 1.80 2008 4 manual… f 26 34 r
## 7 honda civic 1.80 2008 4 auto(l… f 25 36 r
## 8 honda civic 1.80 2008 4 auto(l… f 24 36 c
## 9 honda civic 2.00 2008 4 manual… f 21 29 p
## 10 hyundai sonata 2.40 2008 4 auto(l… f 21 30 r
## # ... with 23 more rows, and 1 more variable: class <chr>
Ten istý kód môžeme urobiť cez base R príkaz.
filter[filter$year == 2008 & filter$hwy > 27, ] # prehladnejšie?
Alebo použime pipeline (%>%
).
mpg %>% # zober dáta mpg a potom
filter(year == 2008, hwy > 27) # filtruj rok rovný 2008 s dojazdom viacej ako 27 míl na diaľnici
Pri použití pipeline, funkcie za dátami už nemôžu obsahovať dáta v argumente (výhoda: šetrí to čas) tie sú zavolané na začiatku.
Rovnako aj funkcia na rozoradenie dovoľuje zoraďovať tiež početných podmienok. Zoraďme autá podľa vzdvižného objemu motora a potom podľa dojazdu na diaľnici.
arrange(mpg, displ, hwy) # zoraď dáta podľa vzdvižného objemu motora a tie podľa dojazdu
## # A tibble: 234 x 11
## manufacturer model displ year cyl trans drv cty hwy fl
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr>
## 1 honda civic 1.60 1999 4 manual… f 23 29 p
## 2 honda civic 1.60 1999 4 auto(l… f 24 32 r
## 3 honda civic 1.60 1999 4 manual… f 25 32 r
## 4 honda civic 1.60 1999 4 auto(l… f 24 32 r
## 5 honda civic 1.60 1999 4 manual… f 28 33 r
## 6 audi a4 quat… 1.80 1999 4 auto(l… 4 16 25 p
## 7 audi a4 quat… 1.80 1999 4 manual… 4 18 26 p
## 8 audi a4 1.80 1999 4 auto(l… f 18 29 p
## 9 audi a4 1.80 1999 4 manual… f 21 29 p
## 10 volkswagen passat 1.80 1999 4 manual… f 21 29 p
## # ... with 224 more rows, and 1 more variable: class <chr>
Tento syntax zachovávajú všetky funkcie zahrnuté v knižnici. Začnime využívať výhody pipeline zapisovania a vyfiltrujme si autá, ktoré boli vyrobené v roku 2008 a majú dojazd v meste viacej ako 30 míľ zoraďme ich podľa zdvižného objemu motora.
mpg %>% # zober dáta mpg a potom
filter(year == 2008, cty > 20) %>% # filtruj rok 2008 s dojazdom v meste viacej ako 20 míl v meste a potom
arrange(displ) # zoraď podľa zdvižného objemu motora.
## # A tibble: 23 x 11
## manufacturer model displ year cyl trans drv cty hwy fl
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr>
## 1 honda civic 1.80 2008 4 manual(… f 26 34 r
## 2 honda civic 1.80 2008 4 auto(l5) f 25 36 r
## 3 honda civic 1.80 2008 4 auto(l5) f 24 36 c
## 4 toyota corolla 1.80 2008 4 manual(… f 28 37 r
## 5 toyota corolla 1.80 2008 4 auto(l4) f 26 35 r
## 6 audi a4 2.00 2008 4 auto(av) f 21 30 p
## 7 honda civic 2.00 2008 4 manual(… f 21 29 p
## 8 volkswagen gti 2.00 2008 4 manual(… f 21 29 p
## 9 volkswagen gti 2.00 2008 4 auto(s6) f 22 29 p
## 10 volkswagen jetta 2.00 2008 4 auto(s6) f 22 29 p
## # ... with 13 more rows, and 1 more variable: class <chr>
Tak ako sa pracuje s riadkami, tak sa rovnako pracuje aj so stĺpcami. Výber umožňuje aj v závislosti na poradí pôvodných dát. Funkcia zároveň aj zoraďuje stĺpce podľa toho v akom poradí ich napíšete.
select(mpg, manufacturer, drv:hwy, year) # vyber z dát výrobcu, všetky stĺpce medzí typom prevodovky a dojazdom na dialnici, nakoniec pridaj rok
## # A tibble: 234 x 5
## manufacturer drv cty hwy year
## <chr> <chr> <int> <int> <int>
## 1 audi f 18 29 1999
## 2 audi f 21 29 1999
## 3 audi f 20 31 2008
## 4 audi f 21 30 2008
## 5 audi f 16 26 1999
## 6 audi f 18 26 1999
## 7 audi f 18 27 2008
## 8 audi 4 18 26 1999
## 9 audi 4 16 25 1999
## 10 audi 4 20 28 2008
## # ... with 224 more rows
Alebo funkcia sa dá použiť aj naopak, na “odobranie” stĺpca. Vezmime pipeline použitú vyššie a odoberme z neho na konci stĺpec s rokmi.
mpg %>% # zober dáta mpg a potom
filter(year == 2008, cty > 20) %>% # filtruj rok 2008 s dojazdom v meste viacej ako 20 míl a potom
arrange(displ) %>% # zoraď podľa zdvižného objemu motora a potom
select(-year) # odober stĺpec rok
## # A tibble: 23 x 10
## manufacturer model displ cyl trans drv cty hwy fl class
## <chr> <chr> <dbl> <int> <chr> <chr> <int> <int> <chr> <chr>
## 1 honda civic 1.80 4 manual… f 26 34 r subco…
## 2 honda civic 1.80 4 auto(l… f 25 36 r subco…
## 3 honda civic 1.80 4 auto(l… f 24 36 c subco…
## 4 toyota corolla 1.80 4 manual… f 28 37 r compa…
## 5 toyota corolla 1.80 4 auto(l… f 26 35 r compa…
## 6 audi a4 2.00 4 auto(a… f 21 30 p compa…
## 7 honda civic 2.00 4 manual… f 21 29 p subco…
## 8 volkswagen gti 2.00 4 manual… f 21 29 p compa…
## 9 volkswagen gti 2.00 4 auto(s… f 22 29 p compa…
## 10 volkswagen jetta 2.00 4 auto(s… f 22 29 p compa…
## # ... with 13 more rows
Pozor: Keby použijeme select na odobranie stĺpca rok, pred filtrovaním podľa roku, tak celá pipeline zlyhá. Takto môžeme jednoducho na seba vrstviť kroky logicky idúce po sebe.
Prvé dva stĺpce dát označujú výrobcu a model, použime funkciu na vytvorenie nového stĺpca obsahujúceho tieto informácie. Vytvorme ešte jeden nový stĺpec kde spočítame priemerný dojazd na jeden galón paliva z dojazdu v meste a na diaľnici. Nakoniec tabuľku zoradme podľa dojazdu.
mpg %>% # zober dáta mpg a potom
mutate(auto = paste(manufacturer, "-", model), dojazd = (cty + hwy)/2) %>% # vytvor nový stĺpec auto z názvu výrobcu a modelu, vytvor novy stĺpec dojazd ako priemer dojazdov a potom
select(auto, year, dojazd) %>% # nechaj stĺpce auto, year, dojazd a potom
arrange(desc(dojazd)) # zorať podľa dojazdu zostupne
## # A tibble: 234 x 3
## auto year dojazd
## <chr> <int> <dbl>
## 1 volkswagen - new beetle 1999 39.5
## 2 volkswagen - jetta 1999 38.5
## 3 volkswagen - new beetle 1999 35.0
## 4 toyota - corolla 2008 32.5
## 5 honda - civic 1999 30.5
## 6 honda - civic 2008 30.5
## 7 toyota - corolla 1999 30.5
## 8 toyota - corolla 2008 30.5
## 9 honda - civic 2008 30.0
## 10 honda - civic 2008 30.0
## # ... with 224 more rows
Funkciou desc()
viete zmeniť zoradenie na zostupne. Podľa dát najdlhší priemerný dojazd na galón paliva má “volkswagen - new beetle” z rokou 1999.
Okrem počítania so stĺpcami potrebujeme počítať aj v riadkoch. Poďme hlbšie, zaujíma nás, aký je priemerný a maximálný dojazd v meste a na diaľnci, áut vyrobených v roku 1999.
mpg %>% # zober dáta mpg a potom
filter(year == 1999) %>% # filtruj rok 1999 a potom
summarize(mean(cty), max(cty), mean(hwy), max(hwy)) # spočítaj priemerný a maximálny dojazd v meste a na dialnici.
## # A tibble: 1 x 4
## `mean(cty)` `max(cty)` `mean(hwy)` `max(hwy)`
## <dbl> <dbl> <dbl> <dbl>
## 1 17.0 35. 23.4 44.
Takto sme si rýchlo vyfiltrovali a spočítali čo nás zaujíma v dvoj krokovom slede funkcií.
Niekto vám povie aby ste spočítali priemerné hodnoty dojazdov, ale pre každý jeden typ motoru vzhľadom na počet valcov. Tak začnime napríklad:
for(ii in unique(mpg$cyl)){
mpg %>% # zober dáta mpg a potom
filter(year == 2008, cyl = ii) %>% # filtruj rok 2008 a počet valcov ii a potom
summarize(mean(cty), mean(hwy)) # spočítaj priemerný dojazd v meste a na dialnici.
}
Použitie cyklu nie je veľmi pohodlné a často kradne váš čas keď sa ku kódu vraciate s odstupom času. Navyše, čo by ste robili keby sa úloha zmení a potrebujete ešte spočítať v rámci počtu valcov aj hodnoty pre každý typ paliva zvlášť?
V pipeline stačí pridať jeden riadok a celá robota ide rýchlejšie, pričom výstup máte v jednej tabulke. Aby sme to mali prehladnejšie pomenujme si tieto nové stĺpce.
mpg %>% # zober dáta mpg a potom
filter(year == 2008) %>% # filtruj rok 2008 a potom
group_by(cyl, fl) %>% # rozdel do skupín podľa počtu valcov a druhu paliva a potom
summarize(priemer_mesto = mean(cty), priemer_dialnica = mean(hwy)) # spočítaj priemerný dojazd v meste a na dialnici.
## # A tibble: 11 x 4
## # Groups: cyl [?]
## cyl fl priemer_mesto priemer_dialnica
## <int> <chr> <dbl> <dbl>
## 1 4 c 24.0 36.0
## 2 4 p 20.2 27.7
## 3 4 r 21.8 30.2
## 4 5 r 20.5 28.8
## 5 6 d 17.0 22.0
## 6 6 e 11.0 17.0
## 7 6 p 17.2 25.1
## 8 6 r 16.3 23.2
## 9 8 e 9.57 12.7
## 10 8 p 14.4 21.9
## 11 8 r 13.1 18.2
Pritvrďme, chceme vedieť ešte aj koľko áut obsahuje každá skupina a zoraďme si ich od najväčšej skupiny.
mpg %>% # zober dáta mpg a potom
filter(year == 2008) %>% # filtruj rok 2008 a potom
group_by(cyl, fl) %>% # rozdel do skupín podľa počtu valcov a druhu paliva a potom
summarize(počet_v_skupine = n(), priemer_mesto = mean(cty), priemer_dialnica = mean(hwy)) %>% # spočítaj koľko áut je každej skupine, priemerný dojazd v meste a na dialnici a potom
arrange(desc(počet_v_skupine)) # zorať podľa početnosti skupín zostupne.
## # A tibble: 11 x 5
## # Groups: cyl [4]
## cyl fl počet_v_skupine priemer_mesto priemer_dialnica
## <int> <chr> <int> <dbl> <dbl>
## 1 8 r 28 13.1 18.2
## 2 6 r 23 16.3 23.2
## 3 4 r 20 21.8 30.2
## 4 4 p 15 20.2 27.7
## 5 6 p 9 17.2 25.1
## 6 8 p 8 14.4 21.9
## 7 8 e 7 9.57 12.7
## 8 5 r 4 20.5 28.8
## 9 4 c 1 24.0 36.0
## 10 6 d 1 17.0 22.0
## 11 6 e 1 11.0 17.0
Najpočetnejšia skupina áut v dátach sú osem-válce s typom paliva “r”, táto najpočetnejšia skupina má zároveň aj najmenší priemerný dojazd.
To bola posledná základná funkcia, ktorú by mal ovládať každý kto chce pracovať s dátami v prostredí R rýchlo a efektívne. Ostatné funkie dopĺňajú vlastnosti už predstavených a ich osvojenie chce len čas a cvik.
Pokúste sa pomocou pipeline spracovať dáta, tak aby ste zistili za každého výrobcu medián objemu motora pre autá s náhonom typu “f”. Výslednú tabuľku zoraďte podľa mediánu a v pipeline použite funkciu rename()
na pomenovanie stĺpca “Výrobca”. Výlsedok by mal vyzerať takto:
## # A tibble: 9 x 2
## Výrobca Medián
## <chr> <dbl>
## 1 honda 1.60
## 2 audi 2.00
## 3 volkswagen 2.00
## 4 hyundai 2.40
## 5 toyota 2.40
## 6 nissan 3.00
## 7 chevrolet 3.10
## 8 dodge 3.30
## 9 pontiac 3.80
Ak sa vám to podarilo, tak ste pripravený na vyšší level práce s dplyr
.
Medzi základné funkcie ešte patria napríklad funkcia na náhodný výber riadkov, alebo generátor náhodnej podmnožiny:
sample_n()
náhodne vyber n riadkov.sample_frac()
náhodne vyber podiel riadkov.Knižnica disponuje pár desiatkami užitočných funkcií, ako sú funkcie na agregovanie dátových tabuliek, prezhromaždovanie a podobne.
Využívaním pipeline písania sa približujete k v praxi používanej štruktúre SQL, zároveň jej príkazy sú veľmi podobné funkciám knižnice dplyr
.