11  Práce s řádky

Obdobně jako je funkce select() neocenitelným pomocníkem pro práci se sloupci dataframů, její příbuzná filter() nám dobře poslouží pro filtrování řádků. Tato kapitola je věnována právě jí, ale také rodině funkcí slice() a funkci arrange().

11.1 Filtrování řádků

Pro filtrování řádků je třeba trocha výrokové logiky. Základními logickými operátory v R jsou == (EQUAL), | (OR) a & (AND). Nepřekvapivě, pro HIGHER THAN používám >=, naopak pro LOWER THAN slouží <=. Negace se provádí pomocí vykřičníku, tedy například NOT EQUAL je !=.

Vybaveni těmito znalostmi, filtrování řádků není obtížný úkol. Hlavní funkcí je zde filter():

filter(countries, postsoviet == "yes" & gdp > 100000)
# A tibble: 5 × 17
  country code       gdp popula…¹   area eu_me…² posts…³ life_…⁴ uni_prc pover…⁵
  <chr>   <chr>    <dbl>    <dbl>  <dbl> <chr>   <chr>     <dbl>   <dbl>   <dbl>
1 Czechia CZ     207772. 10610055  78867 yes     yes        79.2   0.217   0.122
2 Germany DE    3386000  82792351 357022 yes     yes        81     0.252   0.19 
3 Hungary HU     131935.  9778371  93028 yes     yes        76     0.217   0.256
4 Poland  PL     496462. 37976687 312685 yes     yes        77.8   0.272   0.195
5 Romania RO     202884. 19530631 238391 yes     yes        75.2   0.155   0.357
# … with 7 more variables: material_dep <dbl>, hdi <dbl>,
#   foundation_date <date>, maj_belief <chr>, dem_index <dbl>, di_cat <chr>,
#   hd_title_name <chr>, and abbreviated variable names ¹​population,
#   ²​eu_member, ³​postsoviet, ⁴​life_exp, ⁵​poverty_risk

Podmínky filtrování lze kombinovat, například vyfiltrovat pouze postsovětské země s hrubým domácím produktem větším než 100 000 miliónů euro.

%in% místo |

Občas je naším cílem vyfiltrovat řádky obsahující některou z vybraných hodnot kategoriální proměnné, například všechny náboženské skupiny spadající pod křesťanství. Jednou možností je:

filter(countries, maj_belief == "catholic" | maj_belief == "orthodox" | maj_belief == "protestantism")

Tento přístup funguje, je ale zbytečně květnatý. Místo něj je možné aplikovat operátor %in%, pomocí kterého můžeme vyfiltrovat všechny hodnoty objevující se ve zvoleném vektoru:

filter(countries, maj_belief %in% c("catholic", "orthodox", "protestantism"))

Oba tyto příkazy vedou ke stejnému výsledku, ten druhý je ale výrazně kompaktnější.

Jak si jistě dokážete představit, funkce select() a filter() jsou často využívané dohromady:

countries %>% 
  filter(postsoviet == "yes") %>% 
  select(country, postsoviet, life_exp)
# A tibble: 16 × 3
   country                postsoviet life_exp
   <chr>                  <chr>         <dbl>
 1 Bulgaria               yes            74.8
 2 Czechia                yes            79.2
 3 Germany                yes            81  
 4 Estonia                yes            77.8
 5 Croatia                yes            78.3
 6 Latvia                 yes            75  
 7 Lithuania              yes            75  
 8 Hungary                yes            76  
 9 Poland                 yes            77.8
10 Romania                yes            75.2
11 Slovenia               yes            80.9
12 Slovakia               yes            77.4
13 North Macedonia        yes            75.9
14 Albania                yes            76.4
15 Serbia                 yes            76.3
16 Bosnia and Herzegovina yes            77.3

11.2 Řezání dataframů

V některých případech budeme chtít filtrovat na základě pořadí řádků dataframů. K tomu nám poslouží rodina funkcí slice z balíčku dplyr.

Prvním členem této rodiny je funkce slice(). Její aplikace je velmi podobná klasickému indexování pomocí hranatých závorek. Například výběr prvního řádku v dataframu:

slice(countries, 1)

Je ekvivalentní countries[1, ] a vrátí první řádek dataframu. Obdobně podobné jsou i funkce slice(countries, -1) a countries[-1, ], které vrátí všechny řádky kromě prvního. Funkce slice() je však pouze základem pro řadu dalších užitečných funkcí.

Další dvě funkce, které nám již svým fungováním budou povědomé jsou slice_head() a slice_tail(). Ty, obdobně jako funkce head() a tail(), vrátí prvních n řádků v dataframů. Na rozdíl od svých příbuzných ze základní instalace R, ovšem slice funkce umožňují vybrat nejen absolutní, ale i relativní počet řádků. Například pro vybrání prvních deseti procent dataframu:

slice_head(countries, prop = 0.1)

Pro vybrání absolutního počtu řádku slouží argument n.

O něco zajímavější jsou funkce slice_max() a slice_min(). Ty umožňují vybrat n řádků s nejvyšší, respektive nejnižší, hodnou dané proměnné. Pomocí těchto funkcí můžeme například jednoduše zjistit, které tři země v našem dataframu mají nejvyšší naději na dožití:

slice_max(countries, order_by = life_exp, n = 3) %>% 
  select(country, life_exp)
# A tibble: 3 × 2
  country     life_exp
  <chr>          <dbl>
1 Switzerland     83.3
2 Spain           83.1
3 France          82.9

a které naopak nejnižší:

slice_min(countries, order_by = life_exp, n = 3) %>% 
  select(country, life_exp)
# A tibble: 3 × 2
  country   life_exp
  <chr>        <dbl>
1 Bulgaria      74.8
2 Latvia        75  
3 Lithuania     75  

Funkce slice_max() a slice_min() jsem zde zkombinovaly s funkcí select(), abychom vybrali jen relevantní proměnné.

Posledním členem rodiny je funkce slice_sample(), která vybere náhodné řádky dataframu. Tato funkce najde uplatnění zejména v simulačních studiích a technikách.

slice_sample(countries, n = 3)

11.3 Group_by()

V tuto chvíli si možná někteří čtenáři říkají, jaké je využití slice funkcí oproti jejich klasickým variantám, jako je head() nebo tail(). Jednou z jejich velkých předností je možnost kombinovat je s funkcí group_by().

Funkce group_by() umožňuje rozdělit dataframe na podskupiny a aplikovat funkce z balíčku dplyr na každou z podskupin zvlášť. Podskupiny jsou definované kategorickou proměnnou v dataframu. Tímto způsobem můžeme zjistit nejen které země se těší nejvyšší naději na dožití obecně, ale i to, jak jsou na tom západní a postsovětské země zvlášť:

countries %>% 
  group_by(postsoviet) %>% 
  slice_max(order_by = life_exp, n = 3) %>% 
  select(country, postsoviet, life_exp)
# A tibble: 6 × 3
# Groups:   postsoviet [2]
  country     postsoviet life_exp
  <chr>       <chr>         <dbl>
1 Switzerland no             83.3
2 Spain       no             83.1
3 France      no             82.9
4 Germany     yes            81  
5 Slovenia    yes            80.9
6 Czechia     yes            79.2

Zatímco mezi západními zeměmi vedou Švýcarsko, Španělsko a Francie, v postsovětské skupině je to Německo, Slovinsko a Česká republika. Třídit je možné i pomocí většího počtu proměnných, například pro třídění podle postsovětské historie a členství v Evropské unii bychom použili group_by(postsoviet, eu_member). Jak jistě tušíte, funkce group_by() má mnoho využití a budeme se s ní setkávat opakovaně i následujících kapitolách.

11.4 Pořadí řádků

Posledním typem operace, kterou si v této kapitole představíme, je řazení řádků pomocí funkce arrange(). Pořadí zemí v dataframu countries podle naděje na dožití získáme jednoduše:

countries %>% 
  arrange(life_exp) %>% 
  select(country, life_exp)
# A tibble: 38 × 2
   country         life_exp
   <chr>              <dbl>
 1 Bulgaria            74.8
 2 Latvia              75  
 3 Lithuania           75  
 4 Romania             75.2
 5 North Macedonia     75.9
 6 Hungary             76  
 7 Serbia              76.3
 8 Albania             76.4
 9 Turkey              76.4
10 Montenegro          76.8
# … with 28 more rows

Při bližším pohledu zjistíme, že země jsou seřazený vzestupně. Nejhůře se vede Bulhrasko a Litva s Lotyšskem. Co kdyby nás ale zajímaly země s nejvyšší nadějí na dožití? Pro sestupné řazení zkombinujeme funkci arrange() s funkcí des():

countries %>% 
  arrange(desc(life_exp)) %>% 
  select(country, life_exp)
# A tibble: 38 × 2
   country     life_exp
   <chr>          <dbl>
 1 Switzerland     83.3
 2 Spain           83.1
 3 France          82.9
 4 Italy           82.8
 5 Norway          82.5
 6 Luxembourg      82.4
 7 Sweden          82.4
 8 Iceland         82.4
 9 Austria         81.9
10 Netherlands     81.6
# … with 28 more rows

Nejvyšší naději na dožití se těší Švýcarsko, se Španělskem v těsném závěsu.