Tidy data: jak si ušetřit mnoho zbytečných starostí

Na motivy Hadley Wickham: Tidy data, Journal of Statistical Software, August 2014, Volume 59, Issue 10.

K této kapitole jsou zpracovány velice hezké „taháky“: http://www.rstudio.com/resources/cheatsheets/ (Data tidying with tidyr a Data transformation with dplyr). Jsou též dostupné přímo z RStudia z menu Help, Cheatsheets.

Všechny potřebné knihovny (dplyr, tidyr a readr) lze instalovat v rámci jednoho zastřešujícího balíčku tidyverse:

install.packages("tidyverse")

Před použitím knihoven je potřeba je nejdříve zavést příkazem (nutné vždy po startu R)

library(tidyverse)

Případně je možné obdobným způsobem instalovat jednotlivé knihovny…

Tidy Data je obecný koncept nezávislý na použitých programech.

Raw Data → Processing Script → Tidy data + Codebook → Data Analysis → Data Communication.

Raw Data: surová data, zaznamenaná v jakémkoliv prvotním (často neuspořádaném) formátu (klidně i jen poznámky na papíře).

Reprodukovatelnost: celý řetězec zpracování jednoznačně popsán skripty – na první pohled je jasný postup a lze ho jednoduše zopakovat. V případě ručních mezikroků detailně zaznamenat (verze programu, nastavení, jak co pojmenovat a jak uložit).

Codebook: informace o proměnných, jejich jednotkách a možných hodnotách. Slouží k tomu, aby se v datech vyznal a mohl s nimi pracovat i ten, kdo nebyl u jejich pořízení.

Tidy data

  1. Každá proměnná v samostatném sloupci.
  2. Každé pozorování v samostatném řádku.
  3. Každý druh pozorované záležitosti v samostatné tabulce.

Poznámka k bodu 3: pokud máme např. tabulku s průběžnými body studentů během jejich studia, jedná se o jednu záležitost. Osobní informace o jednotlivých studentech (datum narození, adresa, telefon) uložíme do samostatné tabulky.

V případě více tabulek je nutný sloupec, dle kterého je lze propojit – ID pozorování – identifikační číslo, řetězec apod.

Čitelné pojmenování sloupců – raději AgeAtDiagnosis než AgeDx.

Uložení dat: co tabulka, to jeden soubor (záložkám v Excelu se vyhýbat). A rozhodně neukládat do jedné záložky více tabulek! Zbytečně si tím v extrémní míře znesnadňujeme následné automatické zpracování.

Messy data: vše ostatní.

  1. Hlavičky sloupců jsou hodnoty, nikoliv jména proměnných.
  2. Více proměnných v rámci jednoho sloupce.
  3. Proměnné uloženy jak v řádcích, tak ve sloupcích.
  4. Více pozorovaných záležitostí uložených ve stejné tabulce.
  5. Jedna pozorovaná záležitost uložena ve více tabulkách.

Pokud jsou data v tidy formátu, můžeme využívat efektivních knihoven pro jejich další zpracování, například dplyr pro souhrnné statistiky a manipulace podle různých kritérií (viz dále v této kapitole) nebo ggplot2 pro efektivní tvorbu pokročilých grafů (viz kapitola Grammar of Graphics (ggplot2)).

Nyní se podívejme na data v nevhodném formátu a jak je převést na tidy data.

Messy data a jejich převod na tidy data pomocí knihovny tidyr

Příklad 1

Tabulka obsahuje průměrnou hodnotu základní frekvence kmitání hlasivek (F0) u 3 žen a 3 mužů při 2 různých úkolech. Čím jsou porušena pravidla tidy data?

data <- read.table(header = TRUE, text = '
task male female
1    119  203
1    143  219
1    94   245
2    114  144
2    127  259
2    95   244
')

„Hlavičky některých sloupců jsou hodnoty, nikoliv jména proměnných.“

Hlavičky sloupců male a female ve skutečnosti nejsou 2 různé proměnné, ale jen 2 hodnoty téže proměnné (sex). Že to skutečně není vhodný formát tabulky, by bylo ještě zřejmější, pokud by se výzkumu zůčastnilo např. 5 žen a 3 muži.

Máme tedy 3 proměnné: task, sex a F0_mean. Opravu (sloučení sloupců) provedem pomocí funkce pivot_longer. Význam jejích parametrů je následující.

  • data: proměnná s daty (data.frame)
  • cols: které sloupce sloučit - lze též zadat everything(), starts_with(“počátečníPísmena”) a další frajeřiny
  • names_to: jak nazvat sloupec, jehož hodnoty se vyplní podle názvů slučovaných sloupců
  • values_to: jak nazvat sloupec hodnot ze sloučených sloupců
dataTidy <- pivot_longer(data, cols = c(male, female), names_to = "sex", values_to = "F0_mean")

Tímto zápisem říkáme: vezmi tabulku data, slučovat se budou sloupce male a female, z názvů slučovaných sloupců male a female se udělají hodnoty nového sloupce sex a čísla z těchto sloupců se převedou do nového sloupce s názvem F0_mean.

dataTidy
## # A tibble: 12 × 3
##     task sex    F0_mean
##    <int> <chr>    <int>
##  1     1 male       119
##  2     1 female     203
##  3     1 male       143
##  4     1 female     219
##  5     1 male        94
##  6     1 female     245
##  7     2 male       114
##  8     2 female     144
##  9     2 male       127
## 10     2 female     259
## 11     2 male        95
## 12     2 female     244

A máme krásný tidy data formát. Můžeme pak např. jednoduše pomocí grafické knihovny ggplot2 říct, ať zobrazí frekvence u jednotlivých úloh (task) a rozdělí se do skupin podle hodnot proměnné sex. Ale o tom až v další kapitole…

Poznámka: pro výběr slučovaných sloupců lze využít i zápisu se symbolem - značícím „vše kromě“, tedy sloučit všechny sloupce kromě sloupce task:

dataTidy <- pivot_longer(data, cols = -task, names_to = "sex", values_to = "F0_mean")

Příklad 2

Opět máme data z předchozího příkladu, ale v jiném tvaru. Čísla úkolů jsou součástí názvů sloupečků (_1 a _2). Čím jsou porušena pravidla tidy data?

data2 <- read.table(header = TRUE, text = '
male_1 male_2 female_1 female_2
119    114    203      144
143    127    219      259
94     95     245      244
')

Opět „hlavičky některých sloupců jsou hodnoty, nikoliv jména proměnných“, ale k tomu ještě „více proměnných v rámci jednoho sloupce“ (sex a task).

data2Tidy <- pivot_longer(data2, cols = everything(), names_to = "sex_task", values_to = "F0_mean") %>%
    separate(sex_task, c("sex", "task"), sep = "_")

První funkci pivot_longer jsme již poznali (parametr cols nyní říká, ať se sloučí všechny sloupce), vytváříme dočasný sloupec se dvěma proměnnými sex_task (zkuste si spustit samostatně jen tuto operaci a podívejte se na výsledek).

## # A tibble: 12 × 2
##    sex_task F0_mean
##    <chr>      <int>
##  1 male_1       119
##  2 male_2       114
##  3 female_1     203
##  4 female_2     144
##  5 male_1       143
##  6 male_2       127
##  7 female_1     219
##  8 female_2     259
##  9 male_1        94
## 10 male_2        95
## 11 female_1     245
## 12 female_2     244

Operátor %>% se nazývá pipeline (potrubí, spojení) a posílá výsledek z jedné funkce do druhé, takže není potřeba ukládat mezivýsledky do proměnných. Pokud je tento operátor použit, následující funkci nezadáváme 1. parametr (název proměnné s daty), protože data jsou jí právě přeposlána tímto operátorem.

Funkce separate rozdělí řetězec na více částí podle zvoleného oddělovače (sep) a výsledek uloží do nových sloupců, jejichž název jsme zvolili sex a task.

data2Tidy
## # A tibble: 12 × 3
##    sex    task  F0_mean
##    <chr>  <chr>   <int>
##  1 male   1         119
##  2 male   2         114
##  3 female 1         203
##  4 female 2         144
##  5 male   1         143
##  6 male   2         127
##  7 female 1         219
##  8 female 2         259
##  9 male   1          94
## 10 male   2          95
## 11 female 1         245
## 12 female 2         244

Příklad 3

Tabulka obsahuje trvání (duration) a průměrnou F0 u pěti různých úkolů. Ne všichni ale absolvovali všechny úkoly, proto tu máme spoustu chybějících hodnot NA (not available). Čím tabulka porušuje pravidla tidy data?

data3 <- read.table(header = TRUE, text = '
name   parameter task1 task2 task3 task4 task5
Eva    duration  4.8   NA    12.3  NA    NA
Eva    F0_mean   230   NA    222   NA    NA
Jiří   duration  NA    7.0   NA    5.9   NA
Jiří   F0_mean   NA    110   NA    113   NA
Zbyněk duration  NA    6.7   NA    NA    15.1
Zbyněk F0_mean   NA    127   NA    NA    118
Monika duration  NA    NA    10.9  6.2   NA
Monika F0_mean   NA    NA    240   235   NA
Patrik duration  5.1   NA    NA    NA    16.3
Patrik F0_mean   98    NA    NA    NA    95
')

„Proměnné uloženy jak v řádcích, tak ve sloupcích.“

Name je o.k., ale task1 až task5 jsou jen hodnoty jedné proměnné task (5 různých úkolů), duration a F0_mean jsou dvě proměnné související s konkrétním jedním pokusem, tudíž by měly tvořit 2 sloupce vždy pro stejný řádek.

data3_krok1 <- pivot_longer(data3, cols = task1:task5, names_to = "task", values_to = "value",
                            values_drop_na = TRUE)

V prvním kroku vezmeme tabulku data3, všechny názvy sloupců v rozsahu task1 až task5 budou hodnoty nové proměnné task a příslušné hodnoty ze sloupců uložíme do nové proměnné value. Všechny hodnoty NA (not available) zahodíme.

## # A tibble: 20 × 4
##    name   parameter task  value
##    <chr>  <chr>     <chr> <dbl>
##  1 Eva    duration  task1   4.8
##  2 Eva    duration  task3  12.3
##  3 Eva    F0_mean   task1 230  
##  4 Eva    F0_mean   task3 222  
##  5 Jiří   duration  task2   7  
##  6 Jiří   duration  task4   5.9
##  7 Jiří   F0_mean   task2 110  
##  8 Jiří   F0_mean   task4 113  
##  9 Zbyněk duration  task2   6.7
## 10 Zbyněk duration  task5  15.1
## 11 Zbyněk F0_mean   task2 127  
## 12 Zbyněk F0_mean   task5 118  
## 13 Monika duration  task3  10.9
## 14 Monika duration  task4   6.2
## 15 Monika F0_mean   task3 240  
## 16 Monika F0_mean   task4 235  
## 17 Patrik duration  task1   5.1
## 18 Patrik duration  task5  16.3
## 19 Patrik F0_mean   task1  98  
## 20 Patrik F0_mean   task5  95
data3_krok2 <- mutate(data3_krok1, task = parse_number(task))

Z hodnot proměnné task (které jsou task1, task2 atd.) extrahujeme jen číslo (funkcí parse_number z balíčku readr), to nám stačí.

## # A tibble: 20 × 4
##    name   parameter  task value
##    <chr>  <chr>     <dbl> <dbl>
##  1 Eva    duration      1   4.8
##  2 Eva    duration      3  12.3
##  3 Eva    F0_mean       1 230  
##  4 Eva    F0_mean       3 222  
##  5 Jiří   duration      2   7  
##  6 Jiří   duration      4   5.9
##  7 Jiří   F0_mean       2 110  
##  8 Jiří   F0_mean       4 113  
##  9 Zbyněk duration      2   6.7
## 10 Zbyněk duration      5  15.1
## 11 Zbyněk F0_mean       2 127  
## 12 Zbyněk F0_mean       5 118  
## 13 Monika duration      3  10.9
## 14 Monika duration      4   6.2
## 15 Monika F0_mean       3 240  
## 16 Monika F0_mean       4 235  
## 17 Patrik duration      1   5.1
## 18 Patrik duration      5  16.3
## 19 Patrik F0_mean       1  98  
## 20 Patrik F0_mean       5  95
data3Tidy <- pivot_wider(data3_krok2, names_from = parameter, values_from = value)

Z hodnot proměnné parameter vytvoříme nové proměnné (nové sloupce), jejichž hodnoty naplníme z proměné value (v nové tabulce tím tedy proměnné parameter a value zaniknou, o konkrétní hodnoty samozřejme nepřijdeme, jen budou přemístěny do jiného formátu).

data3Tidy
## # A tibble: 10 × 4
##    name    task duration F0_mean
##    <chr>  <dbl>    <dbl>   <dbl>
##  1 Eva        1      4.8     230
##  2 Eva        3     12.3     222
##  3 Jiří       2      7       110
##  4 Jiří       4      5.9     113
##  5 Zbyněk     2      6.7     127
##  6 Zbyněk     5     15.1     118
##  7 Monika     3     10.9     240
##  8 Monika     4      6.2     235
##  9 Patrik     1      5.1      98
## 10 Patrik     5     16.3      95

Celý postup by samozřejmě bylo možné zapsat najednou pomocí operátoru pipeline %>%. Zkuste si to.

Příklad 4

Čím jsou porušena pravidla tidy data?

data4 <- read.table(header = TRUE, text = '
id  name    sex  task  duration F0_mean
168 Eva     F    1     4.8      230
168 Eva     F    3     12.3     222
588 Jiří    M    2     7.0      110
588 Jiří    M    4     5.9      113
710 Monika  F    3     10.9     240
710 Monika  F    4     6.2      235
731 Patrik  M    1     5.1      98
731 Patrik  M    5     16.3     95
908 Zbyněk  M    2     6.7      127
908 Zbyněk  M    5     15.1     118
')

„Více pozorovaných záležitostí uložených ve stejné tabulce.“

Osobní informace o lidech (id, name, sex) – vše je 2x, to je jasná známka redundance (a ještě je tu riziko překlepu).

Data je vhodné rozdělit do 2 tabulek: idInfo a results. Obě tabulky budou propojeny přes id číslo.

idInfo <- data4 %>% select(id, name, sex) %>% unique

Z tabulky jsme funkcí select vybrali první 3 sloupce. Funkcí unique jsme zanechali jen unikátní řádky. Pokud se řádky opakují, ve výsledku budou zahrnuty pouze jednou.

idInfo
##    id   name sex
## 1 168    Eva   F
## 3 588   Jiří   M
## 5 710 Monika   F
## 7 731 Patrik   M
## 9 908 Zbyněk   M
results <- data4 %>% select(id, task, duration, F0_mean)

A opět vybíráme jen některé sloupce.

results
##     id task duration F0_mean
## 1  168    1      4.8     230
## 2  168    3     12.3     222
## 3  588    2      7.0     110
## 4  588    4      5.9     113
## 5  710    3     10.9     240
## 6  710    4      6.2     235
## 7  731    1      5.1      98
## 8  731    5     16.3      95
## 9  908    2      6.7     127
## 10 908    5     15.1     118

Mít takto oddělené záznamy je praktické. V případě potřeby je pak možné informace kdykoliv spojit.

right_join(idInfo, results, by = "id")
##     id   name sex task duration F0_mean
## 1  168    Eva   F    1      4.8     230
## 2  168    Eva   F    3     12.3     222
## 3  588   Jiří   M    2      7.0     110
## 4  588   Jiří   M    4      5.9     113
## 5  710 Monika   F    3     10.9     240
## 6  710 Monika   F    4      6.2     235
## 7  731 Patrik   M    1      5.1      98
## 8  731 Patrik   M    5     16.3      95
## 9  908 Zbyněk   M    2      6.7     127
## 10 908 Zbyněk   M    5     15.1     118

Pro další způsoby spojování tabulek viz tahák dostupný přímo z RStudia z menu Help, Cheatsheets, Data Manipulation v dplyr, tidyr. Druhá strana, sekce Combine Data Sets.

Příklad 5

Čím jsou zde porušena pravidla tidy data?

male <- read.table(header = TRUE, text = '
name   task duration F0_mean
Jiří   2    7        110
Jiří   4    5.9      113
Patrik 1    5.1      98
Patrik 5    16.3     95
Zbyněk 2    6.7      127
Zbyněk 5    15.1     118
')

female <- read.table(header = TRUE, text = '
name   task duration F0_mean
Eva    1    4.8      230
Eva    3    12.3     222
Monika 3    10.9     240
Monika 4    6.2      235
')

„Jedna pozorovaná záležitost uložena ve více tabulkách.“

Pokud se jedná o stejný experiment, obě tabulky má smysl sloučit a z male a female vytvořit jednu proměnnou sex.

male <- male %>% mutate(sex = "M")
female <- female %>% mutate(sex = "F")

Tímto jsme do tabulek přidali novou proměnnou sex s příslušnou hodnotou ve všech řádcích.

data5Tidy <- bind_rows(male, female)

A obě tabulky spojíme pod sebe.

data5Tidy
##      name task duration F0_mean sex
## 1    Jiří    2      7.0     110   M
## 2    Jiří    4      5.9     113   M
## 3  Patrik    1      5.1      98   M
## 4  Patrik    5     16.3      95   M
## 5  Zbyněk    2      6.7     127   M
## 6  Zbyněk    5     15.1     118   M
## 7     Eva    1      4.8     230   F
## 8     Eva    3     12.3     222   F
## 9  Monika    3     10.9     240   F
## 10 Monika    4      6.2     235   F

Untidy

Občas se při zpracování dat dostaneme do situace, kdy je potřeba tidy tabulku záměrně předělat do „messy“ tvaru. V následujícím příkladu jsme nahráli 3 osoby, každá přečetla jednu větu ve dvou stylech fonace, a sice normální (modal) a třepené (creaky). Vše bylo čteno dvakrát (sloupec order). Vypočteno bylo trvání a průměrná hodnota F0.

data <- read.table(header = TRUE, text = '
speaker phonation order duration F0_mean
1       modal     1     5.7      127
1       modal     2     5.3      135
1       creaky    1     8.5      110
1       creaky    2     7.4      105
2       modal     1     6.3      243
2       creaky    1     9.2      145
2       modal     2     5.8      219
2       creaky    2     9.3      162
3       modal     1     5.1      140
3       creaky    1     6.0      93
3       creaky    2     5.8      95
')

Rádi bychom vytvořili sloupce s jednotlivými vypočtenými parametry doplněné o index 1 nebo 2 odpovídající hodnotě ve sloupci order, aby pak bylo možné jednoduše vypočítat rozdíl mezi hodnotami prvního a druhého čtení té samé položky tou samou fonací.

messy <- pivot_wider(data, id_cols = c(speaker, phonation), # sloupce sloužící k identifikaci položky
                     names_from = "order",  # sloupec "order" udává pořadí, podle něj se očíslují nové sloupce
                     values_from = duration:F0_mean,   # výčet sloupců s naměřenými hodnotami
                     names_glue = "{.value}.{order}")  # jak slepit nové názvy - zde opět sloupec "order"
## # A tibble: 6 × 6
##   speaker phonation duration.1 duration.2 F0_mean.1 F0_mean.2
##     <int> <chr>          <dbl>      <dbl>     <int>     <int>
## 1       1 modal            5.7        5.3       127       135
## 2       1 creaky           8.5        7.4       110       105
## 3       2 modal            6.3        5.8       243       219
## 4       2 creaky           9.2        9.3       145       162
## 5       3 modal            5.1       NA         140        NA
## 6       3 creaky           6          5.8        93        95

Nyní můžeme vypočítat rozdíly parametrů mezi 1. a 2. čtením. Všimněme si, že bylo správně rozpoznáno, že u třetí osoby chybí druhé čtení v modální fonaci. Ani prohozené pořadí řádků u druhé osoby (vůči logice zbylých dvou osob) převod tabulky nijak nerozhodilo. Kdybychom tyto úpravy dělali ručně, riziko chyby by bylo vysoké.

tab <- messy %>% mutate(deltaDuration = duration.2 - duration.1, deltaF0_mean = F0_mean.2 - F0_mean.1) %>% 
    select(speaker, phonation, deltaDuration, deltaF0_mean)
## # A tibble: 6 × 4
##   speaker phonation deltaDuration deltaF0_mean
##     <int> <chr>             <dbl>        <int>
## 1       1 modal            -0.400            8
## 2       1 creaky           -1.1             -5
## 3       2 modal            -0.5            -24
## 4       2 creaky            0.100           17
## 5       3 modal            NA               NA
## 6       3 creaky           -0.200            2

Rozdíly jsou bezchybně určeny a správně chybí modální fonace třetí osoby, jelikož v datech není druhé čtení.

Kontingenční tabulky

Kontingenční tabulka, neboli tabulka se dvěma vstupy a souhrnnými počty také z principu odporuje formátu tidy data. Přesto je velmi užitečná právě pro zobrazení souhrnných počtů nebo pro statistické testy porovnávající četnosti.

Primární formát uchování dat by měl být tidy data (např. co řádek tabulky, to jeden náhodný výběr ze základního souboru) a převod na kontingenční tabulku pak již snadno provedeme funkcí table(), jak je uvedeno na příkladech v kapitole 15. Testy četností.

Souhrnné statistiky a manipulace pomocí knihovny dplyr

Nyní přichází ta zábavnější část. Předpokládejme, že máme tabulku ve správném formátu tidy data. Pak je radost s ní pracovat. Nejlepší je samozřejmě data hned od začátku ukládat do formátu tidy data, ušetříme si tím starosti. Pakliže ale tento formát nesplňují, musíme je na tidy data nejdříve převést, o čemž byla horní část této stránky.

Funkce v dplyr jsou určeny pro jednodušší a efektivnější spravování dat. Zápis těchto operací je oproti dřívějším knihovnám velice zjednodušen a implementace je vskutku bleskurychlá. Některé funkce jsme již poznali výše.

Knihovna dplyr implementuje „gramatiku“ pro manipulaci s daty (konkrétně slovesa).

  • rename: přejmenování názvů vybraných sloupců
  • arrange: seřadí řádky (podle velikosti jedné či více proměnných), pro sestupné řazení se doplní název proměnné funkcí desc
  • mutate: přidá novou proměnnou (sloupec) nebo transformuje existující proměnnou
  • select: vybere sloupce
  • filter: vybere řádky na základě logických podmínek
  • group_by: rozdělení řádků do skupin podle hodnot nějaké proměnné či kombinace hodnot více proměnných
  • summarize: generuje sumární statistiky různých proměnných, a to ve vrstvách podle skupin vytvořených funkcí group_by
  • group_modify: také umožňuje operace v rámci skupin vytvořených group_by, ale výstupem je opět celá tabulka. Příklad: rozdělíme tabulku na skupiny, v rámci každé provedeme samostatné vyhlazení měřených hodnot polynomiální křivkou.

Dále můžeme používat operátor %>% (pipeline), který jsme již poznali výše.

Příklady

Budeme pracovat s interním dataframe mtcars, seznamte se s ním proto pomocí funkcí View(mtcars) a nápovědy ?mtcars.

Všimněme si, že názvy automobilů jsou uloženy jen jako názvy řádků tabulky. Uděláme z nich „oficiální proměnnou“, tedy nový sloupec.

mtcars$car <- rownames(mtcars)

Seřadíme tabulku podle sloupce car.

mtcars <- mtcars %>% arrange(car)
mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
##                                     car
## AMC Javelin                 AMC Javelin
## Cadillac Fleetwood   Cadillac Fleetwood
## Camaro Z28                   Camaro Z28
## Datsun 710                   Datsun 710
## Dodge Challenger       Dodge Challenger
## Duster 360                   Duster 360
## Ferrari Dino               Ferrari Dino
## Fiat 128                       Fiat 128
## Fiat X1-9                     Fiat X1-9
## Ford Pantera L           Ford Pantera L
## Honda Civic                 Honda Civic
## Hornet 4 Drive           Hornet 4 Drive
## Hornet Sportabout     Hornet Sportabout
## Chrysler Imperial     Chrysler Imperial
## Lincoln Continental Lincoln Continental
## Lotus Europa               Lotus Europa
## Maserati Bora             Maserati Bora
## Mazda RX4                     Mazda RX4
## Mazda RX4 Wag             Mazda RX4 Wag
## Merc 230                       Merc 230
## Merc 240D                     Merc 240D
## Merc 280                       Merc 280
## Merc 280C                     Merc 280C
## Merc 450SE                   Merc 450SE
## Merc 450SL                   Merc 450SL
## Merc 450SLC                 Merc 450SLC
## Pontiac Firebird       Pontiac Firebird
## Porsche 914-2             Porsche 914-2
## Toyota Corolla           Toyota Corolla
## Toyota Corona             Toyota Corona
## Valiant                         Valiant
## Volvo 142E                   Volvo 142E

Používá to defaultní Locale našeho systému, což bývá např. Czech. Takže Chrysler je až a Hornet.

Sys.getlocale(category = "LC_ALL")   # zjisti nastavení Locale
## [1] "LC_COLLATE=Czech_Czechia.utf8;LC_CTYPE=Czech_Czechia.utf8;LC_MONETARY=Czech_Czechia.utf8;LC_NUMERIC=C;LC_TIME=Czech_Czechia.utf8"
Sys.setlocale(category = "LC_COLLATE", locale = "English")   # nastav Anglické Locale pro řazení
## [1] "English_United States.1252"
mtcars <- mtcars %>% arrange(car)
mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
##                                     car
## AMC Javelin                 AMC Javelin
## Cadillac Fleetwood   Cadillac Fleetwood
## Camaro Z28                   Camaro Z28
## Chrysler Imperial     Chrysler Imperial
## Datsun 710                   Datsun 710
## Dodge Challenger       Dodge Challenger
## Duster 360                   Duster 360
## Ferrari Dino               Ferrari Dino
## Fiat 128                       Fiat 128
## Fiat X1-9                     Fiat X1-9
## Ford Pantera L           Ford Pantera L
## Honda Civic                 Honda Civic
## Hornet 4 Drive           Hornet 4 Drive
## Hornet Sportabout     Hornet Sportabout
## Lincoln Continental Lincoln Continental
## Lotus Europa               Lotus Europa
## Maserati Bora             Maserati Bora
## Mazda RX4                     Mazda RX4
## Mazda RX4 Wag             Mazda RX4 Wag
## Merc 230                       Merc 230
## Merc 240D                     Merc 240D
## Merc 280                       Merc 280
## Merc 280C                     Merc 280C
## Merc 450SE                   Merc 450SE
## Merc 450SL                   Merc 450SL
## Merc 450SLC                 Merc 450SLC
## Pontiac Firebird       Pontiac Firebird
## Porsche 914-2             Porsche 914-2
## Toyota Corolla           Toyota Corolla
## Toyota Corona             Toyota Corona
## Valiant                         Valiant
## Volvo 142E                   Volvo 142E

Nyní je Chrysler před Datsun.

Seřadíme ji podle cyl (sestupně) a v případě více shodných hodnot budeme řadit ještě podle gear (normálně vzestupně).

mtcars <- mtcars %>% arrange(desc(cyl), gear)
mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
##                                     car
## AMC Javelin                 AMC Javelin
## Cadillac Fleetwood   Cadillac Fleetwood
## Camaro Z28                   Camaro Z28
## Chrysler Imperial     Chrysler Imperial
## Dodge Challenger       Dodge Challenger
## Duster 360                   Duster 360
## Hornet Sportabout     Hornet Sportabout
## Lincoln Continental Lincoln Continental
## Merc 450SE                   Merc 450SE
## Merc 450SL                   Merc 450SL
## Merc 450SLC                 Merc 450SLC
## Pontiac Firebird       Pontiac Firebird
## Ford Pantera L           Ford Pantera L
## Maserati Bora             Maserati Bora
## Hornet 4 Drive           Hornet 4 Drive
## Valiant                         Valiant
## Mazda RX4                     Mazda RX4
## Mazda RX4 Wag             Mazda RX4 Wag
## Merc 280                       Merc 280
## Merc 280C                     Merc 280C
## Ferrari Dino               Ferrari Dino
## Toyota Corona             Toyota Corona
## Datsun 710                   Datsun 710
## Fiat 128                       Fiat 128
## Fiat X1-9                     Fiat X1-9
## Honda Civic                 Honda Civic
## Merc 230                       Merc 230
## Merc 240D                     Merc 240D
## Toyota Corolla           Toyota Corolla
## Volvo 142E                   Volvo 142E
## Lotus Europa               Lotus Europa
## Porsche 914-2             Porsche 914-2

Přejmenujeme sloupec am na razeni.

mtcars <- mtcars %>% rename(razeni = am)
head(mtcars)
##                     mpg cyl disp  hp drat    wt  qsec vs razeni gear carb
## AMC Javelin        15.2   8  304 150 3.15 3.435 17.30  0      0    3    2
## Cadillac Fleetwood 10.4   8  472 205 2.93 5.250 17.98  0      0    3    4
## Camaro Z28         13.3   8  350 245 3.73 3.840 15.41  0      0    3    4
## Chrysler Imperial  14.7   8  440 230 3.23 5.345 17.42  0      0    3    4
## Dodge Challenger   15.5   8  318 150 2.76 3.520 16.87  0      0    3    2
## Duster 360         14.3   8  360 245 3.21 3.570 15.84  0      0    3    4
##                                   car
## AMC Javelin               AMC Javelin
## Cadillac Fleetwood Cadillac Fleetwood
## Camaro Z28                 Camaro Z28
## Chrysler Imperial   Chrysler Imperial
## Dodge Challenger     Dodge Challenger
## Duster 360                 Duster 360

Vybereme jen sloupce car a mpg (dojezd v mílích na gallon).

prehled <- mtcars %>% select(car, mpg)
head(prehled)
##                                   car  mpg
## AMC Javelin               AMC Javelin 15.2
## Cadillac Fleetwood Cadillac Fleetwood 10.4
## Camaro Z28                 Camaro Z28 13.3
## Chrysler Imperial   Chrysler Imperial 14.7
## Dodge Challenger     Dodge Challenger 15.5
## Duster 360                 Duster 360 14.3

Vybereme jen řádky, kde vs = 0 a carb >= 4, výsledek seřadíme podle názvu.

vyber <- mtcars %>% filter(vs == 0, carb >= 4) %>% arrange(car)
vyber
##                      mpg cyl disp  hp drat    wt  qsec vs razeni gear carb
## Cadillac Fleetwood  10.4   8  472 205 2.93 5.250 17.98  0      0    3    4
## Camaro Z28          13.3   8  350 245 3.73 3.840 15.41  0      0    3    4
## Chrysler Imperial   14.7   8  440 230 3.23 5.345 17.42  0      0    3    4
## Duster 360          14.3   8  360 245 3.21 3.570 15.84  0      0    3    4
## Ferrari Dino        19.7   6  145 175 3.62 2.770 15.50  0      1    5    6
## Ford Pantera L      15.8   8  351 264 4.22 3.170 14.50  0      1    5    4
## Lincoln Continental 10.4   8  460 215 3.00 5.424 17.82  0      0    3    4
## Maserati Bora       15.0   8  301 335 3.54 3.570 14.60  0      1    5    8
## Mazda RX4           21.0   6  160 110 3.90 2.620 16.46  0      1    4    4
## Mazda RX4 Wag       21.0   6  160 110 3.90 2.875 17.02  0      1    4    4
##                                     car
## Cadillac Fleetwood   Cadillac Fleetwood
## Camaro Z28                   Camaro Z28
## Chrysler Imperial     Chrysler Imperial
## Duster 360                   Duster 360
## Ferrari Dino               Ferrari Dino
## Ford Pantera L           Ford Pantera L
## Lincoln Continental Lincoln Continental
## Maserati Bora             Maserati Bora
## Mazda RX4                     Mazda RX4
## Mazda RX4 Wag             Mazda RX4 Wag

Zavedeme novou proměnnou (sloupec) udávající, zda mají auta nadprůměrně nízkou spotřebu.

mtcars <- mtcars %>% mutate(usporne = (mpg > mean(mpg)))
mtcars
##                      mpg cyl  disp  hp drat    wt  qsec vs razeni gear carb
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0      0    3    2
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0      0    3    4
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0      0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0      0    3    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0      0    3    2
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0      0    3    4
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0      0    3    2
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0      0    3    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0      0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0      0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0      0    3    3
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0      0    3    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0      1    5    4
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0      1    5    8
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1      0    3    1
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1      0    3    1
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0      1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0      1    4    4
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1      0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1      0    4    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0      1    5    6
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1      0    3    1
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1      1    4    1
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1      1    4    1
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1      1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1      1    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1      0    4    2
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1      0    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1      1    4    1
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1      1    4    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1      1    5    2
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0      1    5    2
##                                     car usporne
## AMC Javelin                 AMC Javelin   FALSE
## Cadillac Fleetwood   Cadillac Fleetwood   FALSE
## Camaro Z28                   Camaro Z28   FALSE
## Chrysler Imperial     Chrysler Imperial   FALSE
## Dodge Challenger       Dodge Challenger   FALSE
## Duster 360                   Duster 360   FALSE
## Hornet Sportabout     Hornet Sportabout   FALSE
## Lincoln Continental Lincoln Continental   FALSE
## Merc 450SE                   Merc 450SE   FALSE
## Merc 450SL                   Merc 450SL   FALSE
## Merc 450SLC                 Merc 450SLC   FALSE
## Pontiac Firebird       Pontiac Firebird   FALSE
## Ford Pantera L           Ford Pantera L   FALSE
## Maserati Bora             Maserati Bora   FALSE
## Hornet 4 Drive           Hornet 4 Drive    TRUE
## Valiant                         Valiant   FALSE
## Mazda RX4                     Mazda RX4    TRUE
## Mazda RX4 Wag             Mazda RX4 Wag    TRUE
## Merc 280                       Merc 280   FALSE
## Merc 280C                     Merc 280C   FALSE
## Ferrari Dino               Ferrari Dino   FALSE
## Toyota Corona             Toyota Corona    TRUE
## Datsun 710                   Datsun 710    TRUE
## Fiat 128                       Fiat 128    TRUE
## Fiat X1-9                     Fiat X1-9    TRUE
## Honda Civic                 Honda Civic    TRUE
## Merc 230                       Merc 230    TRUE
## Merc 240D                     Merc 240D    TRUE
## Toyota Corolla           Toyota Corolla    TRUE
## Volvo 142E                   Volvo 142E    TRUE
## Lotus Europa               Lotus Europa    TRUE
## Porsche 914-2             Porsche 914-2    TRUE

A nyní by mě zajímalo, kolik průměrně váží auta s nízkou spotřebou a kolik ta s vysokou.

mtcars %>% group_by(usporne) %>% summarize(wtPrumer = mean(wt))
## # A tibble: 2 × 2
##   usporne wtPrumer
##   <lgl>      <dbl>
## 1 FALSE       3.84
## 2 TRUE        2.42

Tak to vypadá, že úsporná auta jsou spíše ta lehčí (opět připomeňme, že souvislost neznamená nutně kauzalitu).

Zvládli bychom vypočítat i 95% konfidenční intervaly tohoto odhadu? V jednom sloupci může být vždy jen jedno číslo, takže interval bude ve dvou sloupcích (spodní a horní hodnota).

mtcars %>% group_by(usporne) %>% summarize(wtPrumer = mean(wt),
    confInt1 = t.test(wt)$conf.int[1], confInt2 = t.test(wt)$conf.int[2])
## # A tibble: 2 × 4
##   usporne wtPrumer confInt1 confInt2
##   <lgl>      <dbl>    <dbl>    <dbl>
## 1 FALSE       3.84     3.47     4.21
## 2 TRUE        2.42     2.09     2.75

A pojďme vymyslet složitější skupiny. Rozdělíme data podle převodovky (razeni), válců (cyl) a počtu karburátorů (carb). V těchto skupinách vypočteme průměr a směrodatnou odchylku z mpg a wt. Výsledky seřadíme od největší průměrné mpg po nejmenší.

Vidíme, že některé skupiny byly asi zastoupeny jen jednou položkou, a proto nebylo možné vypočítat směrodatnou odchylku.

mtcars %>% group_by(razeni, cyl, carb) %>%
    summarize(mpgPrumer = mean(mpg), mpgSD = sd(mpg), wtPrumer = mean(wt), wtSD = sd(wt)) %>%
    arrange(desc(mpgPrumer))
## `summarise()` has grouped output by 'razeni', 'cyl'. You can override using the
## `.groups` argument.
## # A tibble: 13 × 7
## # Groups:   razeni, cyl [6]
##    razeni   cyl  carb mpgPrumer  mpgSD wtPrumer    wtSD
##     <dbl> <dbl> <dbl>     <dbl>  <dbl>    <dbl>   <dbl>
##  1      1     4     1      29.1  5.06      2.07  0.226 
##  2      1     4     2      27.0  4.3       2.01  0.581 
##  3      0     4     2      23.6  1.13      3.17  0.0283
##  4      0     4     1      21.5 NA         2.46 NA     
##  5      1     6     4      21    0         2.75  0.180 
##  6      0     6     1      19.8  2.33      3.34  0.173 
##  7      1     6     6      19.7 NA         2.77 NA     
##  8      0     6     4      18.5  0.990     3.44  0     
##  9      0     8     2      17.2  2.09      3.56  0.194 
## 10      0     8     3      16.3  1.05      3.86  0.184 
## 11      1     8     4      15.8 NA         3.17 NA     
## 12      1     8     8      15   NA         3.57 NA     
## 13      0     8     4      12.6  2.09      4.69  0.903

A nyní chceme udělat nějaké výpočty pro každou skupinu z group_by() samostatně, ale výsledkem nemá být jen souhrnná statistika, ale normálně celá tabulka. K tomu slouží funkce group_modify(). Příklad: rozdělíme do skupin podle počtu válců (cyl), v každé skupině samostatně vypočteme průměrné mpg a vytvoříme nový sloupeček rozdilMPG vypočtený jako mpg mínus průměrMPG.

odectiPrumerMPG <- function(tabulka) {  # vstupem funkce je data.frame = vyrez radku z puvodni tabulky
                                        # odpovidajici konkretni skupine podle provedeneho group_by()
    
    tabulka$rozdilMPG <- tabulka$mpg - mean(tabulka$mpg)  # ...napr. vypocteme novy sloupecek...
    tabulka <- tabulka %>% select(-c(disp:carb))          # ...a treba odstranime nektere jine sloupce...
    
    return(tabulka) # vystupem funkce musi byt take data.frame
}

tabulkaRozdilu <- mtcars %>% group_by(cyl) %>% group_modify(.f = ~ odectiPrumerMPG(.x))
                                        # .x je docasne jmeno data.frame vzdy jedne skupiny z group_by()
print(tabulkaRozdilu, n = 32)
## # A tibble: 32 × 5
## # Groups:   cyl [3]
##      cyl   mpg car                 usporne rozdilMPG
##    <dbl> <dbl> <chr>               <lgl>       <dbl>
##  1     4  21.5 Toyota Corona       TRUE      -5.16  
##  2     4  22.8 Datsun 710          TRUE      -3.86  
##  3     4  32.4 Fiat 128            TRUE       5.74  
##  4     4  27.3 Fiat X1-9           TRUE       0.636 
##  5     4  30.4 Honda Civic         TRUE       3.74  
##  6     4  22.8 Merc 230            TRUE      -3.86  
##  7     4  24.4 Merc 240D           TRUE      -2.26  
##  8     4  33.9 Toyota Corolla      TRUE       7.24  
##  9     4  21.4 Volvo 142E          TRUE      -5.26  
## 10     4  30.4 Lotus Europa        TRUE       3.74  
## 11     4  26   Porsche 914-2       TRUE      -0.664 
## 12     6  21.4 Hornet 4 Drive      TRUE       1.66  
## 13     6  18.1 Valiant             FALSE     -1.64  
## 14     6  21   Mazda RX4           TRUE       1.26  
## 15     6  21   Mazda RX4 Wag       TRUE       1.26  
## 16     6  19.2 Merc 280            FALSE     -0.543 
## 17     6  17.8 Merc 280C           FALSE     -1.94  
## 18     6  19.7 Ferrari Dino        FALSE     -0.0429
## 19     8  15.2 AMC Javelin         FALSE      0.100 
## 20     8  10.4 Cadillac Fleetwood  FALSE     -4.7   
## 21     8  13.3 Camaro Z28          FALSE     -1.80  
## 22     8  14.7 Chrysler Imperial   FALSE     -0.400 
## 23     8  15.5 Dodge Challenger    FALSE      0.400 
## 24     8  14.3 Duster 360          FALSE     -0.800 
## 25     8  18.7 Hornet Sportabout   FALSE      3.6   
## 26     8  10.4 Lincoln Continental FALSE     -4.7   
## 27     8  16.4 Merc 450SE          FALSE      1.30  
## 28     8  17.3 Merc 450SL          FALSE      2.20  
## 29     8  15.2 Merc 450SLC         FALSE      0.100 
## 30     8  19.2 Pontiac Firebird    FALSE      4.1   
## 31     8  15.8 Ford Pantera L      FALSE      0.700 
## 32     8  15   Maserati Bora       FALSE     -0.100

© 13. 5. 2015, 27. 10. 2020 Tomáš Bořil,