{gapminder}


Po wczytaniu danych kolejnym etapem analizy jest czyszczenie zbioru danych, wykrywanie braków danych oraz przekształcanie zmiennych. Poznamy najpopularniejszy pakiet do przetwarzania danych - {dplyr}, będący obecnie standardem w świecie R-owym i jednocześnie elementem projektu {tidyverse}, czyli uniwersum pakietów rozwijanych przez RStudio (więcej informacji znajdziesz pod tym linkiem: https://www.tidyverse.org/).


Gapminder jest to zbiór danych stworzony przez fundację Gapminder, która zajmuje się walką z globalnymi błędnymi przekonaniami i promowaniem faktograficznego spojrzenia na świat. Zbiór Gapminder zawiera dane dotyczące różnych aspektów życia na całym świecie, takich jak oczekiwana długość życia, PKB na mieszkańca, populacja i wiele innych, z podziałem na kraje i kontynenty od 1952 do 2007 roku

strona: https://www.gapminder.org/data/

YT: https://www.youtube.com/watch?v=GmEKpKEakmQ

# install.packages("gapminder")
library(gapminder)
data(gapminder)


Filtrowanie obserwacji


“Source: DataCamp”
“Source: DataCamp”



Załóżmy filtr, żeby zbiór prezentował dane tylko dla roku 1997.

# Podstawowy R:
gapminder[gapminder$year == 1997, ]
## # A tibble: 142 × 6
##    country     continent  year lifeExp       pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>     <int>     <dbl>
##  1 Afghanistan Asia       1997    41.8  22227415      635.
##  2 Albania     Europe     1997    73.0   3428038     3193.
##  3 Algeria     Africa     1997    69.2  29072015     4797.
##  4 Angola      Africa     1997    41.0   9875024     2277.
##  5 Argentina   Americas   1997    73.3  36203463    10967.
##  6 Australia   Oceania    1997    78.8  18565243    26998.
##  7 Austria     Europe     1997    77.5   8069876    29096.
##  8 Bahrain     Asia       1997    73.9    598561    20292.
##  9 Bangladesh  Asia       1997    59.4 123315288      973.
## 10 Belgium     Europe     1997    77.5  10199787    27561.
## # ℹ 132 more rows
# lub
subset(gapminder, year == 1997) # alternatywnie uzywając funkcji subset()
## # A tibble: 142 × 6
##    country     continent  year lifeExp       pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>     <int>     <dbl>
##  1 Afghanistan Asia       1997    41.8  22227415      635.
##  2 Albania     Europe     1997    73.0   3428038     3193.
##  3 Algeria     Africa     1997    69.2  29072015     4797.
##  4 Angola      Africa     1997    41.0   9875024     2277.
##  5 Argentina   Americas   1997    73.3  36203463    10967.
##  6 Australia   Oceania    1997    78.8  18565243    26998.
##  7 Austria     Europe     1997    77.5   8069876    29096.
##  8 Bahrain     Asia       1997    73.9    598561    20292.
##  9 Bangladesh  Asia       1997    59.4 123315288      973.
## 10 Belgium     Europe     1997    77.5  10199787    27561.
## # ℹ 132 more rows
gapminder %>% # nowy znak, tzw. pipe
  filter(year == 1997) # filtrowanie dla konkretnego roku, numeric value
## # A tibble: 142 × 6
##    country     continent  year lifeExp       pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>     <int>     <dbl>
##  1 Afghanistan Asia       1997    41.8  22227415      635.
##  2 Albania     Europe     1997    73.0   3428038     3193.
##  3 Algeria     Africa     1997    69.2  29072015     4797.
##  4 Angola      Africa     1997    41.0   9875024     2277.
##  5 Argentina   Americas   1997    73.3  36203463    10967.
##  6 Australia   Oceania    1997    78.8  18565243    26998.
##  7 Austria     Europe     1997    77.5   8069876    29096.
##  8 Bahrain     Asia       1997    73.9    598561    20292.
##  9 Bangladesh  Asia       1997    59.4 123315288      973.
## 10 Belgium     Europe     1997    77.5  10199787    27561.
## # ℹ 132 more rows


Proszę przyciąć data frame, żeby prezentował dane tylko dla Wybrzeża Kości Słoniowej.

gapminder %>%
  filter(country == "Cote d'Ivoire") # filtrowanie konretnego kraju, string value
## # A tibble: 12 × 6
##    country       continent  year lifeExp      pop gdpPercap
##    <fct>         <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Cote d'Ivoire Africa     1952    40.5  2977019     1389.
##  2 Cote d'Ivoire Africa     1957    42.5  3300000     1501.
##  3 Cote d'Ivoire Africa     1962    44.9  3832408     1729.
##  4 Cote d'Ivoire Africa     1967    47.4  4744870     2052.
##  5 Cote d'Ivoire Africa     1972    49.8  6071696     2378.
##  6 Cote d'Ivoire Africa     1977    52.4  7459574     2518.
##  7 Cote d'Ivoire Africa     1982    54.0  9025951     2603.
##  8 Cote d'Ivoire Africa     1987    54.7 10761098     2157.
##  9 Cote d'Ivoire Africa     1992    52.0 12772596     1648.
## 10 Cote d'Ivoire Africa     1997    48.0 14625967     1786.
## 11 Cote d'Ivoire Africa     2002    46.8 16252726     1649.
## 12 Cote d'Ivoire Africa     2007    48.3 18013409     1545.


Proszę przyciąć data frame, żeby prezentował dane tylko dla Trynidadu i Tobago w roku 1997

# Podstawowy R:
gapminder[gapminder$year == 1997 & gapminder$country == "Trinidad and Tobago", ]
## # A tibble: 1 × 6
##   country             continent  year lifeExp     pop gdpPercap
##   <fct>               <fct>     <int>   <dbl>   <int>     <dbl>
## 1 Trinidad and Tobago Americas   1997    69.5 1138101     8793.
# dplyr
gapminder %>%
  filter(year == 1997, country == "Trinidad and Tobago") # filtrowanie na podstawie kilku zmiennych
## # A tibble: 1 × 6
##   country             continent  year lifeExp     pop gdpPercap
##   <fct>               <fct>     <int>   <dbl>   <int>     <dbl>
## 1 Trinidad and Tobago Americas   1997    69.5 1138101     8793.



Zadanie

Proszę sprawdzić najwcześniejszą datę w zbiorze i użyć jej do odfiltrowania ze zbioru tylko informacji dla tego roku.

Rozwiązanie

# Podstawowy R:
gapminder[gapminder$year == min(gapminder$year), ]
## # A tibble: 142 × 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Albania     Europe     1952    55.2  1282697     1601.
##  3 Algeria     Africa     1952    43.1  9279525     2449.
##  4 Angola      Africa     1952    30.0  4232095     3521.
##  5 Argentina   Americas   1952    62.5 17876956     5911.
##  6 Australia   Oceania    1952    69.1  8691212    10040.
##  7 Austria     Europe     1952    66.8  6927772     6137.
##  8 Bahrain     Asia       1952    50.9   120447     9867.
##  9 Bangladesh  Asia       1952    37.5 46886859      684.
## 10 Belgium     Europe     1952    68    8730405     8343.
## # ℹ 132 more rows
# dplyr
gapminder %>%
  filter(year == min(year))
## # A tibble: 142 × 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Albania     Europe     1952    55.2  1282697     1601.
##  3 Algeria     Africa     1952    43.1  9279525     2449.
##  4 Angola      Africa     1952    30.0  4232095     3521.
##  5 Argentina   Americas   1952    62.5 17876956     5911.
##  6 Australia   Oceania    1952    69.1  8691212    10040.
##  7 Austria     Europe     1952    66.8  6927772     6137.
##  8 Bahrain     Asia       1952    50.9   120447     9867.
##  9 Bangladesh  Asia       1952    37.5 46886859      684.
## 10 Belgium     Europe     1952    68    8730405     8343.
## # ℹ 132 more rows



Zadanie

Proszę sprawdzić jak prezentował się Jemen w roku 1967.

Rozwiązanie

gapminder %>%
    filter(country == "Yemen, Rep.", year == 1967)
## # A tibble: 1 × 6
##   country     continent  year lifeExp     pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>   <int>     <dbl>
## 1 Yemen, Rep. Asia       1967    37.0 6740785      862.



Zadanie

Jesteś analitykiem danych i chcesz znaleźć kraje, które mają oczekiwaną długość życia oraz PKB na mieszkańca powyżej średniej wartości dla wszystkich krajów w danym roku. Chcesz również wykluczyć kraje z populacją mniejszą niż 10 milionów.

Rozwiązanie

# Najpierw załaduj potrzebne pakiety
library(dplyr)
library(gapminder)

# Oblicz średnie wartości dla lifeExp i gdpPercap
average_lifeExp <- mean(gapminder$lifeExp)
average_gdpPercap <- mean(gapminder$gdpPercap)

# Podstawowy R
filtered_data <- gapminder[
  gapminder$lifeExp > average_lifeExp &
  gapminder$gdpPercap > average_gdpPercap &
  gapminder$pop > 10000000, ]

head(filtered_data)
## # A tibble: 6 × 6
##   country   continent  year lifeExp      pop gdpPercap
##   <fct>     <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Argentina Americas   1967    65.6 22934225     8053.
## 2 Argentina Americas   1972    67.1 24779799     9443.
## 3 Argentina Americas   1977    68.5 26983828    10079.
## 4 Argentina Americas   1982    69.9 29341374     8998.
## 5 Argentina Americas   1987    70.8 31620918     9140.
## 6 Argentina Americas   1992    71.9 33958947     9308.
# dplyr
filtered_data <- gapminder %>%
  filter(lifeExp > average_lifeExp, 
         gdpPercap > average_gdpPercap, 
         pop > 10000000) # Filtruj dane zgodnie z fabułą

# Wyświetl pierwsze kilka wierszy przefiltrowanych danych
head(filtered_data)
## # A tibble: 6 × 6
##   country   continent  year lifeExp      pop gdpPercap
##   <fct>     <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Argentina Americas   1967    65.6 22934225     8053.
## 2 Argentina Americas   1972    67.1 24779799     9443.
## 3 Argentina Americas   1977    68.5 26983828    10079.
## 4 Argentina Americas   1982    69.9 29341374     8998.
## 5 Argentina Americas   1987    70.8 31620918     9140.
## 6 Argentina Americas   1992    71.9 33958947     9308.


Sortowanie obserwacji

“Source: DataCamp”
“Source: DataCamp”


# Podstawowy R
gapminder[order(gapminder$lifeExp), ]
## # A tibble: 1,704 × 6
##    country      continent  year lifeExp     pop gdpPercap
##    <fct>        <fct>     <int>   <dbl>   <int>     <dbl>
##  1 Rwanda       Africa     1992    23.6 7290203      737.
##  2 Afghanistan  Asia       1952    28.8 8425333      779.
##  3 Gambia       Africa     1952    30    284320      485.
##  4 Angola       Africa     1952    30.0 4232095     3521.
##  5 Sierra Leone Africa     1952    30.3 2143249      880.
##  6 Afghanistan  Asia       1957    30.3 9240934      821.
##  7 Cambodia     Asia       1977    31.2 6978607      525.
##  8 Mozambique   Africa     1952    31.3 6446316      469.
##  9 Sierra Leone Africa     1957    31.6 2295678     1004.
## 10 Burkina Faso Africa     1952    32.0 4469979      543.
## # ℹ 1,694 more rows
# dplyr
gapminder %>%
  arrange(lifeExp) # malejąco po oczekiwanej długości życia
## # A tibble: 1,704 × 6
##    country      continent  year lifeExp     pop gdpPercap
##    <fct>        <fct>     <int>   <dbl>   <int>     <dbl>
##  1 Rwanda       Africa     1992    23.6 7290203      737.
##  2 Afghanistan  Asia       1952    28.8 8425333      779.
##  3 Gambia       Africa     1952    30    284320      485.
##  4 Angola       Africa     1952    30.0 4232095     3521.
##  5 Sierra Leone Africa     1952    30.3 2143249      880.
##  6 Afghanistan  Asia       1957    30.3 9240934      821.
##  7 Cambodia     Asia       1977    31.2 6978607      525.
##  8 Mozambique   Africa     1952    31.3 6446316      469.
##  9 Sierra Leone Africa     1957    31.6 2295678     1004.
## 10 Burkina Faso Africa     1952    32.0 4469979      543.
## # ℹ 1,694 more rows


# Podstawowy R
gapminder[order(gapminder$lifeExp, decreasing = TRUE), ]
## # A tibble: 1,704 × 6
##    country          continent  year lifeExp       pop gdpPercap
##    <fct>            <fct>     <int>   <dbl>     <int>     <dbl>
##  1 Japan            Asia       2007    82.6 127467972    31656.
##  2 Hong Kong, China Asia       2007    82.2   6980412    39725.
##  3 Japan            Asia       2002    82   127065841    28605.
##  4 Iceland          Europe     2007    81.8    301931    36181.
##  5 Switzerland      Europe     2007    81.7   7554661    37506.
##  6 Hong Kong, China Asia       2002    81.5   6762476    30209.
##  7 Australia        Oceania    2007    81.2  20434176    34435.
##  8 Spain            Europe     2007    80.9  40448191    28821.
##  9 Sweden           Europe     2007    80.9   9031088    33860.
## 10 Israel           Asia       2007    80.7   6426679    25523.
## # ℹ 1,694 more rows
# dplyr
gapminder %>%
  arrange(desc(gdpPercap)) # rosnąco po produkcie krajowych brutto na mieszkańca
## # A tibble: 1,704 × 6
##    country   continent  year lifeExp     pop gdpPercap
##    <fct>     <fct>     <int>   <dbl>   <int>     <dbl>
##  1 Kuwait    Asia       1957    58.0  212846   113523.
##  2 Kuwait    Asia       1972    67.7  841934   109348.
##  3 Kuwait    Asia       1952    55.6  160000   108382.
##  4 Kuwait    Asia       1962    60.5  358266    95458.
##  5 Kuwait    Asia       1967    64.6  575003    80895.
##  6 Kuwait    Asia       1977    69.3 1140357    59265.
##  7 Norway    Europe     2007    80.2 4627926    49357.
##  8 Kuwait    Asia       2007    77.6 2505559    47307.
##  9 Singapore Asia       2007    80.0 4553009    47143.
## 10 Norway    Europe     2002    79.0 4535591    44684.
## # ℹ 1,694 more rows


Filtr na roku 1997 a następnie sortowanie po zmiennej gdpPercap

# Podstawowy R
head(
  gapminder[gapminder$year == 1997, ][order(gapminder$gdpPercap[gapminder$year == 1997], decreasing = TRUE), ]
  ,3)
## # A tibble: 3 × 6
##   country       continent  year lifeExp       pop gdpPercap
##   <fct>         <fct>     <int>   <dbl>     <int>     <dbl>
## 1 Norway        Europe     1997    78.3   4405672    41283.
## 2 Kuwait        Asia       1997    76.2   1765345    40301.
## 3 United States Americas   1997    76.8 272911760    35767.
# dplyr
gapminder %>%
  filter(year == 1997) %>% # najpierw filtr na obserwacje z konkretnego roku a następnie
  arrange(desc(gdpPercap)) %>% # posortowanie rosnąco po produkcie krajowych brutto na mieszkańca
  head(3)
## # A tibble: 3 × 6
##   country       continent  year lifeExp       pop gdpPercap
##   <fct>         <fct>     <int>   <dbl>     <int>     <dbl>
## 1 Norway        Europe     1997    78.3   4405672    41283.
## 2 Kuwait        Asia       1997    76.2   1765345    40301.
## 3 United States Americas   1997    76.8 272911760    35767.



Zadanie

Proszę odfiltrować dwa kraje ze zbioru: Sudan i Chiny, a następnie posortować wartości względem zmiennej GDP (rosnąco).

Rozwiązanie

gapminder %>%
  filter(country %in% c("Sudan","China")) %>% # przypomnienie `%in%` z poprzednich zajęć
  arrange(gdpPercap)
## # A tibble: 24 × 6
##    country continent  year lifeExp        pop gdpPercap
##    <fct>   <fct>     <int>   <dbl>      <int>     <dbl>
##  1 China   Asia       1952    44    556263527      400.
##  2 China   Asia       1962    44.5  665770000      488.
##  3 China   Asia       1957    50.5  637408000      576.
##  4 China   Asia       1967    58.4  754550000      613.
##  5 China   Asia       1972    63.1  862030000      677.
##  6 China   Asia       1977    64.0  943455000      741.
##  7 China   Asia       1982    65.5 1000281000      962.
##  8 China   Asia       1987    67.3 1084035000     1379.
##  9 Sudan   Africa     1992    53.6   28227588     1492.
## 10 Sudan   Africa     1987    51.7   24725960     1508.
## # ℹ 14 more rows



Zadanie

Proszę pokazać zbiór tylko dla roku 1967 i posortować malejąco względem wielkości populacji danego kraju.

Rozwiązanie

gapminder %>%
  filter(year == 1967) %>%
  arrange(desc(pop))
## # A tibble: 142 × 6
##    country        continent  year lifeExp       pop gdpPercap
##    <fct>          <fct>     <int>   <dbl>     <int>     <dbl>
##  1 China          Asia       1967    58.4 754550000      613.
##  2 India          Asia       1967    47.2 506000000      701.
##  3 United States  Americas   1967    70.8 198712000    19530.
##  4 Indonesia      Asia       1967    46.0 109343000      762.
##  5 Japan          Asia       1967    71.4 100825279     9848.
##  6 Brazil         Americas   1967    57.6  88049823     3430.
##  7 Germany        Europe     1967    70.8  76368453    14746.
##  8 Bangladesh     Asia       1967    43.5  62821884      721.
##  9 Pakistan       Asia       1967    49.8  60641899      942.
## 10 United Kingdom Europe     1967    71.4  54959000    14143.
## # ℹ 132 more rows



Zadanie

Proszę zawęzić zbiór do lat między 1970-1980 i posortować rosnąco względem wielkości populacji danego kraju.

Rozwiązanie

gapminder %>%
  filter(between(year, 1970, 1980)) %>% # przypomnienie funkcji between() z poprzednich zajęć
  arrange(pop)
## # A tibble: 284 × 6
##    country               continent  year lifeExp    pop gdpPercap
##    <fct>                 <fct>     <int>   <dbl>  <int>     <dbl>
##  1 Sao Tome and Principe Africa     1972    56.5  76595     1533.
##  2 Sao Tome and Principe Africa     1977    58.6  86796     1738.
##  3 Djibouti              Africa     1972    44.4 178848     3694.
##  4 Equatorial Guinea     Africa     1977    42.0 192675      959.
##  5 Iceland               Europe     1972    74.5 209275    15798.
##  6 Iceland               Europe     1977    76.1 221823    19655.
##  7 Djibouti              Africa     1977    46.5 228694     3082.
##  8 Bahrain               Asia       1972    63.3 230800    18269.
##  9 Comoros               Africa     1972    48.9 250027     1938.
## 10 Equatorial Guinea     Africa     1972    40.5 277603      672.
## # ℹ 274 more rows


Tworzenie nowe zmiennej

“Source: DataCamp”
“Source: DataCamp”


Gdybyśmy chcieli wyrazić w milionach populację danego kraju?

# Podstawowy R
gapminder$pop_mln <- gapminder$pop / 1000000

# dplyr
gapminder %>%
  mutate(pop_mln = pop / 1000000)
## # A tibble: 1,704 × 7
##    country     continent  year lifeExp      pop gdpPercap pop_mln
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.    8.43
##  2 Afghanistan Asia       1957    30.3  9240934      821.    9.24
##  3 Afghanistan Asia       1962    32.0 10267083      853.   10.3 
##  4 Afghanistan Asia       1967    34.0 11537966      836.   11.5 
##  5 Afghanistan Asia       1972    36.1 13079460      740.   13.1 
##  6 Afghanistan Asia       1977    38.4 14880372      786.   14.9 
##  7 Afghanistan Asia       1982    39.9 12881816      978.   12.9 
##  8 Afghanistan Asia       1987    40.8 13867957      852.   13.9 
##  9 Afghanistan Asia       1992    41.7 16317921      649.   16.3 
## 10 Afghanistan Asia       1997    41.8 22227415      635.   22.2 
## # ℹ 1,694 more rows


Gdybyśmy chcieli policzyć pełne kwoty, nie na mieszkańca?

gapminder %>%
  mutate(gdp = gdpPercap * pop)
## # A tibble: 1,704 × 8
##    country     continent  year lifeExp      pop gdpPercap pop_mln          gdp
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>        <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.    8.43  6567086330.
##  2 Afghanistan Asia       1957    30.3  9240934      821.    9.24  7585448670.
##  3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   8758855797.
##  4 Afghanistan Asia       1967    34.0 11537966      836.   11.5   9648014150.
##  5 Afghanistan Asia       1972    36.1 13079460      740.   13.1   9678553274.
##  6 Afghanistan Asia       1977    38.4 14880372      786.   14.9  11697659231.
##  7 Afghanistan Asia       1982    39.9 12881816      978.   12.9  12598563401.
##  8 Afghanistan Asia       1987    40.8 13867957      852.   13.9  11820990309.
##  9 Afghanistan Asia       1992    41.7 16317921      649.   16.3  10595901589.
## 10 Afghanistan Asia       1997    41.8 22227415      635.   22.2  14121995875.
## # ℹ 1,694 more rows


Połączenie wszystkich poznanych właśnie komend w jednym zapytaniu.

# dplyr
gapminder %>%
  mutate(pop_tys = pop / 1000) %>% # tworzenie nowej zmiennej
  filter(year == 1997) %>% # filtr na zmiennej dotyczącej roku obserwacji
  arrange(desc(gdpPercap)) # sortowanie po nowo utworzonej zmiennej
## # A tibble: 142 × 8
##    country       continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##    <fct>         <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
##  1 Norway        Europe     1997    78.3   4405672    41283.    4.41   4406.
##  2 Kuwait        Asia       1997    76.2   1765345    40301.    1.77   1765.
##  3 United States Americas   1997    76.8 272911760    35767.  273.   272912.
##  4 Singapore     Asia       1997    77.2   3802309    33519.    3.80   3802.
##  5 Switzerland   Europe     1997    79.4   7193761    32135.    7.19   7194.
##  6 Netherlands   Europe     1997    78.0  15604464    30246.   15.6   15604.
##  7 Denmark       Europe     1997    76.1   5283663    29804.    5.28   5284.
##  8 Austria       Europe     1997    77.5   8069876    29096.    8.07   8070.
##  9 Canada        Americas   1997    78.6  30305843    28955.   30.3   30306.
## 10 Japan         Asia       1997    80.7 125956499    28817.  126.   125956.
## # ℹ 132 more rows
# Podstawowy R
gapminder$pop_tys <- gapminder$pop / 1000 # tworzenie nowej zmiennej
filtered <- gapminder[gapminder$year == 1997, ] # filtr na zmiennej dotyczącej roku obserwacji
sorted <- filtered[order(filtered$gdpPercap, decreasing = TRUE), ] # sortowanie po nowo utworzonej zmiennej
head(sorted, 3)
## # A tibble: 3 × 8
##   country       continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##   <fct>         <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
## 1 Norway        Europe     1997    78.3   4405672    41283.    4.41   4406.
## 2 Kuwait        Asia       1997    76.2   1765345    40301.    1.77   1765.
## 3 United States Americas   1997    76.8 272911760    35767.  273.   272912.
# w "jednej linijce"
gapminder_with_pop <- gapminder

gapminder_with_pop$pop_tys <- gapminder_with_pop$pop / 1000

gapminder_with_pop[gapminder_with_pop$year == 1997, ][order(gapminder_with_pop$gdpPercap[gapminder_with_pop$year == 1997], decreasing = TRUE),]
## # A tibble: 142 × 8
##    country       continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##    <fct>         <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
##  1 Norway        Europe     1997    78.3   4405672    41283.    4.41   4406.
##  2 Kuwait        Asia       1997    76.2   1765345    40301.    1.77   1765.
##  3 United States Americas   1997    76.8 272911760    35767.  273.   272912.
##  4 Singapore     Asia       1997    77.2   3802309    33519.    3.80   3802.
##  5 Switzerland   Europe     1997    79.4   7193761    32135.    7.19   7194.
##  6 Netherlands   Europe     1997    78.0  15604464    30246.   15.6   15604.
##  7 Denmark       Europe     1997    76.1   5283663    29804.    5.28   5284.
##  8 Austria       Europe     1997    77.5   8069876    29096.    8.07   8070.
##  9 Canada        Americas   1997    78.6  30305843    28955.   30.3   30306.
## 10 Japan         Asia       1997    80.7 125956499    28817.  126.   125956.
## # ℹ 132 more rows



Zadanie

Proszę stworzyć zmienną pod nazwą pop_mln, tak, żeby w zbiorze wyświetlała się populacja wyrażona w milionach, zaokrąglona do jednego miejsca po przecinku, a następnie wybierzmy ze zbioru najświeższy rok i posortujmy względem zmiennej pop_mln malejąco

Rozwiązanie

gapminder %>%
  mutate(pop_mln = round(pop / 1000000, 1)) %>% 
  filter(year == max(year)) %>% 
  arrange(desc(pop_mln)) 
## # A tibble: 142 × 8
##    country       continent  year lifeExp        pop gdpPercap pop_mln  pop_tys
##    <fct>         <fct>     <int>   <dbl>      <int>     <dbl>   <dbl>    <dbl>
##  1 China         Asia       2007    73.0 1318683096     4959.   1319. 1318683.
##  2 India         Asia       2007    64.7 1110396331     2452.   1110. 1110396.
##  3 United States Americas   2007    78.2  301139947    42952.    301.  301140.
##  4 Indonesia     Asia       2007    70.6  223547000     3541.    224.  223547 
##  5 Brazil        Americas   2007    72.4  190010647     9066.    190   190011.
##  6 Pakistan      Asia       2007    65.5  169270617     2606.    169.  169271.
##  7 Bangladesh    Asia       2007    64.1  150448339     1391.    150.  150448.
##  8 Nigeria       Africa     2007    46.9  135031164     2014.    135   135031.
##  9 Japan         Asia       2007    82.6  127467972    31656.    128.  127468.
## 10 Mexico        Americas   2007    76.2  108700891    11978.    109.  108701.
## # ℹ 132 more rows



Zadanie

Proszę stworzyć zmienną lifeExpMonths, wyrażającą tę samą informację co lifeExp ale w miesiącach.

Rozwiązanie

gapminder %>%
  mutate(lifeExpMonths = lifeExp * 12)
## # A tibble: 1,704 × 9
##    country     continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.    8.43   8425.
##  2 Afghanistan Asia       1957    30.3  9240934      821.    9.24   9241.
##  3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   10267.
##  4 Afghanistan Asia       1967    34.0 11537966      836.   11.5   11538.
##  5 Afghanistan Asia       1972    36.1 13079460      740.   13.1   13079.
##  6 Afghanistan Asia       1977    38.4 14880372      786.   14.9   14880.
##  7 Afghanistan Asia       1982    39.9 12881816      978.   12.9   12882.
##  8 Afghanistan Asia       1987    40.8 13867957      852.   13.9   13868.
##  9 Afghanistan Asia       1992    41.7 16317921      649.   16.3   16318.
## 10 Afghanistan Asia       1997    41.8 22227415      635.   22.2   22227.
## # ℹ 1,694 more rows
## # ℹ 1 more variable: lifeExpMonths <dbl>


Wybór kolumn i zmiana ich nazwy


Chcemy wybrać tylko rok 2007 i dwie interesujące nas kolumny

# Podstawowy R
gapminder[gapminder$year == 2007, c("country", "lifeExp")]
## # A tibble: 142 × 2
##    country     lifeExp
##    <fct>         <dbl>
##  1 Afghanistan    43.8
##  2 Albania        76.4
##  3 Algeria        72.3
##  4 Angola         42.7
##  5 Argentina      75.3
##  6 Australia      81.2
##  7 Austria        79.8
##  8 Bahrain        75.6
##  9 Bangladesh     64.1
## 10 Belgium        79.4
## # ℹ 132 more rows
# Podstawowy R
gapminder[gapminder$year == 2007, c(1,3)]
## # A tibble: 142 × 2
##    country      year
##    <fct>       <int>
##  1 Afghanistan  2007
##  2 Albania      2007
##  3 Algeria      2007
##  4 Angola       2007
##  5 Argentina    2007
##  6 Australia    2007
##  7 Austria      2007
##  8 Bahrain      2007
##  9 Bangladesh   2007
## 10 Belgium      2007
## # ℹ 132 more rows
# dplyr
gapminder %>%
  filter(year == 2007) %>% # tylko rok 2007
  select(country, lifeExp) # wybór tylko dwóch interesujących nas kolumn
## # A tibble: 142 × 2
##    country     lifeExp
##    <fct>         <dbl>
##  1 Afghanistan    43.8
##  2 Albania        76.4
##  3 Algeria        72.3
##  4 Angola         42.7
##  5 Argentina      75.3
##  6 Australia      81.2
##  7 Austria        79.8
##  8 Bahrain        75.6
##  9 Bangladesh     64.1
## 10 Belgium        79.4
## # ℹ 132 more rows


Stworzenie nowego zbioru z wyselekcjonowanymi informacjami

CountrieslifeExp_2007 <- gapminder %>%
  filter(year == 2007) %>%
  select(country, lifeExp) 

ls() # i pojawiła nam się w środowisku nowa ramka, można też View(CountrieslifeExp_2007)
## [1] "average_gdpPercap"     "average_lifeExp"       "CountrieslifeExp_2007"
## [4] "filtered"              "filtered_data"         "gapminder"            
## [7] "gapminder_with_pop"    "sorted"


# alternatywnie
gapminder %>%
  filter(year == 2007) %>% # wyrzućmy tylko zmienną rok np. poniższym sposobem
  select(names(gapminder)[-3]) -> CountrieslifeExp_2007 # takie przypisanie też zadziała
# być może jest nawet bardziej intuicyjne to podejście w kontekście pipe'owania w dplyr






I dyskretne wprowadzenie do pakietu ggplot2 (będzie omawiany na innych zajęciach)…

Stwórzmy wykres przedstawiający zależność między właśnie wyciągniętymi ze zbioru zmiennymi

# install.packages("ggplot2") # jeśli nie mamy
library(ggplot2) # załadowanie niezbędnej biblioteki

ggplot(data = CountrieslifeExp_2007, # dane
       aes(x = gdpPercap, # zmienna na osi ox
           y = lifeExp)) + # zmienna na osi oy i plus (nowość)
  geom_point() # typ wykresu

I dodajmy jeszcze informację z dwóch zmiennych, żeby uczynić nasz wykres super informatywnym

ggplot(data = CountrieslifeExp_2007,
       aes(x = gdpPercap, 
           y = lifeExp, 
           color = continent, # trzecia zmienna różnicuje nam punkty względem regionu świata -> kontynentu
           size = pop)) +  # czwarta przybliża wielkość kraju biorąc pod uwagę populację
  geom_point() 


A żeby wykorzystać wszystkie zmienne ze zbioru, stwórzmy ostatni wykres (wykresy!) przemnażając nasz uprzedni przez wszystkie dostępne w ramce lata. Spójrzmy…

ggplot(gapminder, 
       aes(x=gdpPercap,
           y=lifeExp, 
           color=continent,
           size=pop))+
  geom_point()+
  scale_x_log10()+
  facet_wrap(~year)

Zadanie

Czy potrafilibyście Państwo stworzyć podobny wykres za pomocą uprzednio poznanych funkcji z pakietu {graphics}?

Rozwiązanie

plot(x = gapminder$gdpPercap, 
     y = gapminder$lifeExp, 
     xlab = "Produkt krajowy brutto", 
     ylab = "Oczekiwana długość życia", 
     type = "p",
     frame.plot = T)

Wracajmy do dplyr’a…

Podsumowanie zmiennych


“Source: DataCamp”

Znają już Państwo znakomicie kilka funkcji z pakietu base, które mogą okazać się bardzo przydatne i efektywne w kontekście aktualnego tematu, przypomnijmy:

  • mean()
  • media()
  • sum()
  • min()
  • max()


Funkcja summarize() (lub summarise()) służy do tworzenia podsumowań danych — np. obliczania średnich, sum, median, liczebności, odchyleń standardowych itp.

Najczęściej używamy jej razem z funkcją group_by(), aby wykonać obliczenia dla każdej grupy osobno.


Obliczenie jednej statystyki dla całego zbioru

gapminder %>%
  summarise(srednia_dlugosc_zycia = mean(lifeExp))
## # A tibble: 1 × 1
##   srednia_dlugosc_zycia
##                   <dbl>
## 1                  59.5


Jaka była średnia długość życia ludzi w roku 1952?

gapminder %>%
filter(year == 1952) %>%
summarize(srednia_dlugosc_zycia = mean(lifeExp))
## # A tibble: 1 × 1
##   srednia_dlugosc_zycia
##                   <dbl>
## 1                  49.1

a z ciekawości jaka w 2007?

(gapminder %>%
   filter(year == 2007) %>% # wybór roku
   summarize(meanLifeExp = mean(lifeExp)) -> meanLifeExp) # oczekiwana średnia długość życia
## # A tibble: 1 × 1
##   meanLifeExp
##         <dbl>
## 1        67.0
# Sprawdźmy jaki tym danych zwrócił nam dplyr
str(meanLifeExp)
## tibble [1 × 1] (S3: tbl_df/tbl/data.frame)
##  $ meanLifeExp: num 67
# tibble'a, czyli de facto data.frame'a

# robiąc to "starym" sposobem otrzymalibyśmy
(meanLifeExp <- mean(gapminder$lifeExp[gapminder$year==2007]))
## [1] 67.00742
str(meanLifeExp) # pojedynczy skalar
##  num 67


Podsumowanie rożnych statystyk według kontynentu

gapminder %>%
  group_by(continent) %>%
  summarize(
    srednia_zycia = mean(lifeExp),
    mediana_zycia = median(lifeExp),
    liczba_krajow = n()
  )
## # A tibble: 5 × 4
##   continent srednia_zycia mediana_zycia liczba_krajow
##   <fct>             <dbl>         <dbl>         <int>
## 1 Africa             48.9          47.8           624
## 2 Americas           64.7          67.0           300
## 3 Asia               60.1          61.8           396
## 4 Europe             71.9          72.2           360
## 5 Oceania            74.3          73.7            24


Dodanie zaokrągleń i sortowania

gapminder %>%
  group_by(continent) %>%
  summarize(
    srednia_zycia = round(mean(lifeExp), 1),
    sredni_PKB = round(mean(gdpPercap), 0)
  ) %>%
  arrange(desc(srednia_zycia))
## # A tibble: 5 × 3
##   continent srednia_zycia sredni_PKB
##   <fct>             <dbl>      <dbl>
## 1 Oceania            74.3      18622
## 2 Europe             71.9      14469
## 3 Americas           64.7       7136
## 4 Asia               60.1       7902
## 5 Africa             48.9       2194


Podsumowanie dla każdej kombinacji kontynent–rok

gapminder %>%
  group_by(continent, year) %>%
  summarize(
    srednia_zycia = mean(lifeExp),
    sredni_PKB = mean(gdpPercap),
    .groups = "drop"  # opcjonalne – usuwa grupowanie po obliczeniu
  )
## # A tibble: 60 × 4
##    continent  year srednia_zycia sredni_PKB
##    <fct>     <int>         <dbl>      <dbl>
##  1 Africa     1952          39.1      1253.
##  2 Africa     1957          41.3      1385.
##  3 Africa     1962          43.3      1598.
##  4 Africa     1967          45.3      2050.
##  5 Africa     1972          47.5      2340.
##  6 Africa     1977          49.6      2586.
##  7 Africa     1982          51.6      2482.
##  8 Africa     1987          53.3      2283.
##  9 Africa     1992          53.6      2282.
## 10 Africa     1997          53.6      2379.
## # ℹ 50 more rows



Zadanie

Proszę policzyć dla roku 1962 zarówno oczekiwaną długość życia jak i całkowitą populację

Rozwiązanie

gapminder %>%
  filter(year == 1962) %>%
  summarize(meanLifeExp = round(mean(lifeExp),1),
            totalPop = sum(pop))
## # A tibble: 1 × 2
##   meanLifeExp   totalPop
##         <dbl>      <dbl>
## 1        53.6 2899782974


Grupowanie


“Source: DataCamp”
“Source: DataCamp”


Powtórzmy ćwiczenie z poprzedniego paragrafu (zadania), ale licząc długość życia i populację dla wszystkich lat w zbiorze

(gapminder %>%
  group_by(year) %>% # grupowanie po zmiennej z rokiem
  summarize(meanLifeExp = mean(lifeExp),
            totalPop = sum(pop)) -> lata)
## # A tibble: 12 × 3
##     year meanLifeExp   totalPop
##    <int>       <dbl>      <dbl>
##  1  1952        49.1 2406957150
##  2  1957        51.5 2664404580
##  3  1962        53.6 2899782974
##  4  1967        55.7 3217478384
##  5  1972        57.6 3576977158
##  6  1977        59.6 3930045807
##  7  1982        61.5 4289436840
##  8  1987        63.2 4691477418
##  9  1992        64.2 5110710260
## 10  1997        65.0 5515204472
## 11  2002        65.7 5886977579
## 12  2007        67.0 6251013179
# jakie wnioski? Zobaczmy na rysunku
plot(x = lata$year, y = lata$totalPop)

# alternatywny sposób
ggplot2::ggplot(lata,
                aes(x = year, 
                    y = totalPop)) +
  geom_point() +
  expand_limits(y = 0) # zabieg, żeby zacząć skalę od zera (nie oszukujmy oka, jak robią to niektóre media podając sondaże ;) )


# można również porównać oczekiwaną długość życia i wielkość populacji danego kraju
# między kontynentami dla konkretnego roku, spójrzmy na poniższy przykład
(gapminder %>%
   filter(year == 1972) %>%
   group_by(continent) %>%
   summarize(meanLifeExp = mean(lifeExp),
             totalPop = sum(pop)) -> kontynenty)
## # A tibble: 5 × 3
##   continent meanLifeExp   totalPop
##   <fct>           <dbl>      <dbl>
## 1 Africa           47.5  379879541
## 2 Americas         62.4  529384210
## 3 Asia             57.3 2150972248
## 4 Europe           70.8  500635059
## 5 Oceania          71.9   16106100
# tabela tabelą, ale rysunek nawet dziecko rozkmini
ggplot(kontynenty, 
       aes(x = continent, 
           y = meanLifeExp)) +
  geom_col() # tym razem barplot'a użyjmy

ggplot(kontynenty, 
       aes(x = continent, 
           y = totalPop)) +
  geom_col() # wiedząc ile potęg nuklearnych jest w Azji, oraz jak duża jest gospodarka chińska, ten rysunek, przypominający nieco gest środkowego palca, jest bardzo niepokojący

# po "staremu" {Graphics} byłoby...
barplot(kontynenty$meanLifeExp)

barplot(kontynenty$totalPop)


Nic nie stoi na przeszkodzie, żebyśmy podsumowanie zmiennych zrobili w dwóch przekrojach na przykład dla każdego kontynentu w kolejnych latach

(gapminder %>%
   group_by(year, continent) %>%
   summarize(totalPop = sum(pop),
             meanLifeExp = mean(lifeExp)) -> lata_kontynety)
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
## # A tibble: 60 × 4
## # Groups:   year [12]
##     year continent   totalPop meanLifeExp
##    <int> <fct>          <dbl>       <dbl>
##  1  1952 Africa     237640501        39.1
##  2  1952 Americas   345152446        53.3
##  3  1952 Asia      1395357351        46.3
##  4  1952 Europe     418120846        64.4
##  5  1952 Oceania     10686006        69.3
##  6  1957 Africa     264837738        41.3
##  7  1957 Americas   386953916        56.0
##  8  1957 Asia      1562780599        49.3
##  9  1957 Europe     437890351        66.7
## 10  1957 Oceania     11941976        70.3
## # ℹ 50 more rows

Który kontynent się najbardziej rozwija a któremu zabraknie na wypłatę rent i emerytur?

ggplot(lata_kontynety, 
       aes(x = year, 
           y = totalPop, 
           color = continent)) + # rozbicie na kontynenty
  geom_point() +
  expand_limits(y = 0) # od zera

# alternatywnie
ggplot(lata_kontynety, 
       aes(x = year, 
           y = meanLifeExp, 
           color = continent)) +
  geom_line() + # może liniowy?
  expand_limits(y = 0)


To jeszcze jedna wrzutka dotycząca ggplot2

ggplot(CountrieslifeExp_2007,
       aes(x = lifeExp)) +
  geom_histogram() # domyślamy się, że ten element odpowiada za narysowanie histogramu własnie
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

# po "staremu" {Graphics} byłoby...
hist(CountrieslifeExp_2007$lifeExp, breaks = 20)


ggplot(CountrieslifeExp_2007, 
       aes(x = continent, 
           y = lifeExp)) +
  geom_boxplot()



Zadanie

Podsumujmy medianą oczekiwaną długość życia i wyznaczmy najwyższy produkt krajowy brutto dla roku 1967

Rozwiązanie

gapminder %>%
  filter(year == 1967) %>%
  summarize(medianLifeExp = median(lifeExp),
            maxGdpPercap = max(gdpPercap))
## # A tibble: 1 × 2
##   medianLifeExp maxGdpPercap
##           <dbl>        <dbl>
## 1          53.8       80895.


Zadanie

Podsumujmy medianą oczekiwaną długość życia i wyznaczmy najwyższy produkt krajowy brutto dla wszystkich lat ze zbioru

Rozwiązanie

gapminder %>%
  group_by(year) %>%
  summarise(medianLifeExp = median(lifeExp),
            maxGdpPercap = max(gdpPercap))
## # A tibble: 12 × 3
##     year medianLifeExp maxGdpPercap
##    <int>         <dbl>        <dbl>
##  1  1952          45.1      108382.
##  2  1957          48.4      113523.
##  3  1962          50.9       95458.
##  4  1967          53.8       80895.
##  5  1972          56.5      109348.
##  6  1977          59.7       59265.
##  7  1982          62.4       33693.
##  8  1987          65.8       31541.
##  9  1992          67.7       34933.
## 10  1997          69.4       41283.
## 11  2002          70.8       44684.
## 12  2007          71.9       49357.


Zadanie

Proszę znaleźć medianę oczekiwanej długości życia, wraz z najwyższym produktem krajowym brutto w państwach w podziale na kontynenty w roku 1977

Rozwiązanie

gapminder %>%
  filter(year==1977) %>%
  group_by(continent) %>%
  summarise(medianLifeExp = median(lifeExp), 
            maxGdpPercap = max(gdpPercap))
## # A tibble: 5 × 3
##   continent medianLifeExp maxGdpPercap
##   <fct>             <dbl>        <dbl>
## 1 Africa             49.3       21951.
## 2 Americas           66.4       24073.
## 3 Asia               60.8       59265.
## 4 Europe             72.3       26982.
## 5 Oceania            72.9       18334.



Zadanie

Korzystając z danych gapminder, znajdź wszystkie kraje, w których średnia długość życia wzrosła o co najmniej 5 lat w okresie między rokiem 1997 a 2007. Wynik powinien zawierać dane tylko dla roku 2007 wraz z obliczoną różnicą.

Rozwiązanie

gapminder_diff <- gapminder %>%
  filter(year %in% c(1997, 2007)) %>% # tylko dane z lat 1997 i 2007
  arrange(country, year) %>% # Sortujemy dane według kraju, a następnie roku (zapewnia chronologiczną kolejność)
  group_by(country) %>% # grupujemy dane według kraju (operacje będą wykonywane osobno dla każdego kraju)
  mutate(lifeExp_1997 = lag(lifeExp, 1)) %>% # Tworzymy nową kolumnę z wartością długości życia z poprzedniego wiersza (czyli z 1997 roku)
  filter(year == 2007) %>% # Pozostawiamy tylko wiersze z roku 2007
  mutate(lifeExp_diff = lifeExp - lifeExp_1997) %>% # Obliczamy różnicę w długości życia między 2007 a 1997
  filter(!is.na(lifeExp_diff) & lifeExp_diff >= 5) # Filtrujemy kraje, gdzie: różnica nie jest wartością brakującą (NA) oraz różnica wynosi co najmniej 5 lat

# Wyświetlamy pierwsze kilka wierszy przefiltrowanych danych
head(gapminder_diff)
## # A tibble: 3 × 10
## # Groups:   country [3]
##   country continent  year lifeExp     pop gdpPercap pop_mln pop_tys lifeExp_1997
##   <fct>   <fct>     <int>   <dbl>   <int>     <dbl>   <dbl>   <dbl>        <dbl>
## 1 Niger   Africa     2007    56.9  1.29e7      620.   12.9   12895.         51.3
## 2 Rwanda  Africa     2007    46.2  8.86e6      863.    8.86   8861.         36.1
## 3 Uganda  Africa     2007    51.5  2.92e7     1056.   29.2   29170.         44.6
## # ℹ 1 more variable: lifeExp_diff <dbl>
# albo
gapminder_diff %>%
  head()
## # A tibble: 3 × 10
## # Groups:   country [3]
##   country continent  year lifeExp     pop gdpPercap pop_mln pop_tys lifeExp_1997
##   <fct>   <fct>     <int>   <dbl>   <int>     <dbl>   <dbl>   <dbl>        <dbl>
## 1 Niger   Africa     2007    56.9  1.29e7      620.   12.9   12895.         51.3
## 2 Rwanda  Africa     2007    46.2  8.86e6      863.    8.86   8861.         36.1
## 3 Uganda  Africa     2007    51.5  2.92e7     1056.   29.2   29170.         44.6
## # ℹ 1 more variable: lifeExp_diff <dbl>



Zadanie

Używając danych gapminder, zidentyfikuj kraje, które doświadczyły znaczącego pogorszenia sytuacji ekonomicznej między 1997 a 2007 rokiem. Znajdź wszystkie kraje, w których PKB per capita spadło o co najmniej 10%. Oblicz procentową zmianę i wyświetl wyniki.

Rozwiązanie

gapminder_diff_gdp <- gapminder %>% # # tylko dane z lat 1997 i 2007
  filter(year %in% c(1997, 2007)) %>%
  arrange(country, year) %>%
  group_by(country) %>%
  mutate(gdpPercap_1997 = lag(gdpPercap, 1)) %>%
  filter(year == 2007) %>%
  mutate(gdpPercap_diff = (gdpPercap - gdpPercap_1997) / gdpPercap_1997 * 100) %>% #  Oblicza procentową zmianę PKB per capita: Wzór: ((wartość 2007 - wartość 1997) / wartość 1997) × 100, Wynik ujemny = spadek, dodatni = wzrost
  filter(!is.na(gdpPercap_diff) & gdpPercap_diff <= -10)

# Wyświetl pierwsze kilka wierszy przefiltrowanych danych
head(gapminder_diff_gdp)
## # A tibble: 6 × 10
## # Groups:   country [6]
##   country          continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##   <fct>            <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
## 1 Comoros          Africa     2007    65.2   710960      986.   0.711    711.
## 2 Congo, Dem. Rep. Africa     2007    46.5 64606759      278.  64.6    64607.
## 3 Cote d'Ivoire    Africa     2007    48.3 18013409     1545.  18.0    18013.
## 4 Eritrea          Africa     2007    58.0  4906585      641.   4.91    4907.
## 5 Gabon            Africa     2007    56.7  1454867    13206.   1.45    1455.
## 6 Guinea-Bissau    Africa     2007    46.4  1472041      579.   1.47    1472.
## # ℹ 2 more variables: gdpPercap_1997 <dbl>, gdpPercap_diff <dbl>



Inne

Oprócz podstawowych funkcji transformujących dane, {dplyr} oferuje zestaw funkcji pomocniczych, które upraszczają typowe operacje analityczne. Są one szczególnie przydatne do szybkiej eksploracji danych i przygotowywania zestawów do dalszej analizy.


Funkcja count() to wygodny skrót, który łączy group_by() i summarise(n = n()) w jedną operację. Zamiast pisać dwie funkcje, wystarczy jedna - szczególnie przydatne podczas eksploracyjnej analizy danych.

Ile obserwacji mamy dla każdego kontynentu?

gapminder %>% 
  count(continent)
## # A tibble: 5 × 2
##   continent     n
##   <fct>     <int>
## 1 Africa      624
## 2 Americas    300
## 3 Asia        396
## 4 Europe      360
## 5 Oceania      24

Możemy zliczać według wielu zmiennych

gapminder %>% 
  count(continent, year)
## # A tibble: 60 × 3
##    continent  year     n
##    <fct>     <int> <int>
##  1 Africa     1952    52
##  2 Africa     1957    52
##  3 Africa     1962    52
##  4 Africa     1967    52
##  5 Africa     1972    52
##  6 Africa     1977    52
##  7 Africa     1982    52
##  8 Africa     1987    52
##  9 Africa     1992    52
## 10 Africa     1997    52
## # ℹ 50 more rows

Dodanie sort = TRUE od razu sortuje wyniki malejąco

gapminder %>% 
  count(continent, sort = TRUE)
## # A tibble: 5 × 2
##   continent     n
##   <fct>     <int>
## 1 Africa      624
## 2 Asia        396
## 3 Europe      360
## 4 Americas    300
## 5 Oceania      24

Porównajmy z dłuższym zapisem (daje ten sam rezultat co poprzedni przykład):

gapminder %>% 
  group_by(continent) %>% 
  summarise(n = n())
## # A tibble: 5 × 2
##   continent     n
##   <fct>     <int>
## 1 Africa      624
## 2 Americas    300
## 3 Asia        396
## 4 Europe      360
## 5 Oceania      24


Rodzina funkcji slice_*() pozwala wybierać wiersze na podstawie ich pozycji lub wartości w określonej kolumnie. To idealne narzędzie, gdy chcemy zobaczyć “top 5” lub “ostatnie 3” obserwacje (taki ekwiwalent funkcji head() i tail()).


Pierwsze 3 wiersze z całego zbioru

gapminder %>% 
  slice_head(n = 3)
## # A tibble: 3 × 8
##   country     continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.    8.43   8425.
## 2 Afghanistan Asia       1957    30.3  9240934      821.    9.24   9241.
## 3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   10267.


Ostatnie 5 wierszy

gapminder %>% 
  slice_tail(n = 5)
## # A tibble: 5 × 8
##   country  continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##   <fct>    <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
## 1 Zimbabwe Africa     1987    62.4  9216418      706.    9.22   9216.
## 2 Zimbabwe Africa     1992    60.4 10704340      693.   10.7   10704.
## 3 Zimbabwe Africa     1997    46.8 11404948      792.   11.4   11405.
## 4 Zimbabwe Africa     2002    40.0 11926563      672.   11.9   11927.
## 5 Zimbabwe Africa     2007    43.5 12311143      470.   12.3   12311.


3 kraje o najwyższej długości życia w 2007 roku

gapminder %>% 
  filter(year == 2007) %>% 
  slice_max(lifeExp, n = 3)
## # A tibble: 3 × 8
##   country          continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##   <fct>            <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
## 1 Japan            Asia       2007    82.6 127467972    31656. 127.    127468.
## 2 Hong Kong, China Asia       2007    82.2   6980412    39725.   6.98    6980.
## 3 Iceland          Europe     2007    81.8    301931    36181.   0.302    302.


5 krajów o najniższym PKB per capita w 2007

gapminder %>% 
  filter(year == 2007) %>% 
  slice_min(gdpPercap, n = 5)
## # A tibble: 5 × 8
##   country          continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##   <fct>            <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
## 1 Congo, Dem. Rep. Africa     2007    46.5 64606759      278.   64.6   64607.
## 2 Liberia          Africa     2007    45.7  3193942      415.    3.19   3194.
## 3 Burundi          Africa     2007    49.6  8390505      430.    8.39   8391.
## 4 Zimbabwe         Africa     2007    43.5 12311143      470.   12.3   12311.
## 5 Guinea-Bissau    Africa     2007    46.4  1472041      579.    1.47   1472.


Można też używać proporcji zamiast liczby (10% najlepszych)

gapminder %>% 
  filter(year == 2007) %>% 
  slice_max(lifeExp, prop = 0.1)
## # A tibble: 14 × 8
##    country          continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##    <fct>            <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
##  1 Japan            Asia       2007    82.6 127467972    31656. 127.    127468.
##  2 Hong Kong, China Asia       2007    82.2   6980412    39725.   6.98    6980.
##  3 Iceland          Europe     2007    81.8    301931    36181.   0.302    302.
##  4 Switzerland      Europe     2007    81.7   7554661    37506.   7.55    7555.
##  5 Australia        Oceania    2007    81.2  20434176    34435.  20.4    20434.
##  6 Spain            Europe     2007    80.9  40448191    28821.  40.4    40448.
##  7 Sweden           Europe     2007    80.9   9031088    33860.   9.03    9031.
##  8 Israel           Asia       2007    80.7   6426679    25523.   6.43    6427.
##  9 France           Europe     2007    80.7  61083916    30470.  61.1    61084.
## 10 Canada           Americas   2007    80.7  33390141    36319.  33.4    33390.
## 11 Italy            Europe     2007    80.5  58147733    28570.  58.1    58148.
## 12 New Zealand      Oceania    2007    80.2   4115771    25185.   4.12    4116.
## 13 Norway           Europe     2007    80.2   4627926    49357.   4.63    4628.
## 14 Singapore        Asia       2007    80.0   4553009    47143.   4.55    4553.


slice() działa świetnie z group_by() - najlepszy kraj z każdego kontynentu

gapminder %>% 
  filter(year == 2007) %>% 
  group_by(continent) %>% 
  slice_max(lifeExp, n = 1)
## # A tibble: 5 × 8
## # Groups:   continent [5]
##   country   continent  year lifeExp       pop gdpPercap pop_mln pop_tys
##   <fct>     <fct>     <int>   <dbl>     <int>     <dbl>   <dbl>   <dbl>
## 1 Reunion   Africa     2007    76.4    798094     7670.   0.798    798.
## 2 Canada    Americas   2007    80.7  33390141    36319.  33.4    33390.
## 3 Japan     Asia       2007    82.6 127467972    31656. 127.    127468.
## 4 Iceland   Europe     2007    81.8    301931    36181.   0.302    302.
## 5 Australia Oceania    2007    81.2  20434176    34435.  20.4    20434.


Funkcja distinct() zwraca tylko unikalne wiersze lub unikalne kombinacje wybranych kolumn. Przydatna do sprawdzania, jakie wartości występują w danych lub do usuwania duplikatów.

Jakie kraje są w zbiorze danych?

gapminder %>% 
  distinct(country)
## # A tibble: 142 × 1
##    country    
##    <fct>      
##  1 Afghanistan
##  2 Albania    
##  3 Algeria    
##  4 Angola     
##  5 Argentina  
##  6 Australia  
##  7 Austria    
##  8 Bahrain    
##  9 Bangladesh 
## 10 Belgium    
## # ℹ 132 more rows


Jakie lata są w zbiorze?

gapminder %>% 
  distinct(year)
## # A tibble: 12 × 1
##     year
##    <int>
##  1  1952
##  2  1957
##  3  1962
##  4  1967
##  5  1972
##  6  1977
##  7  1982
##  8  1987
##  9  1992
## 10  1997
## 11  2002
## 12  2007


Unikalne kombinacje kontynent-kraj

gapminder %>% 
  distinct(continent, country)
## # A tibble: 142 × 2
##    continent country    
##    <fct>     <fct>      
##  1 Asia      Afghanistan
##  2 Europe    Albania    
##  3 Africa    Algeria    
##  4 Africa    Angola     
##  5 Americas  Argentina  
##  6 Oceania   Australia  
##  7 Europe    Austria    
##  8 Asia      Bahrain    
##  9 Asia      Bangladesh 
## 10 Europe    Belgium    
## # ℹ 132 more rows


Domyślnie distinct() zwraca tylko wybrane kolumny

Jeśli chcemy zachować wszystkie kolumny, używamy .keep_all = TRUE

gapminder %>% 
  distinct(country, .keep_all = TRUE)  # jeden wiersz na kraj (pierwszy)
## # A tibble: 142 × 8
##    country     continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.   8.43    8425.
##  2 Albania     Europe     1952    55.2  1282697     1601.   1.28    1283.
##  3 Algeria     Africa     1952    43.1  9279525     2449.   9.28    9280.
##  4 Angola      Africa     1952    30.0  4232095     3521.   4.23    4232.
##  5 Argentina   Americas   1952    62.5 17876956     5911.  17.9    17877.
##  6 Australia   Oceania    1952    69.1  8691212    10040.   8.69    8691.
##  7 Austria     Europe     1952    66.8  6927772     6137.   6.93    6928.
##  8 Bahrain     Asia       1952    50.9   120447     9867.   0.120    120.
##  9 Bangladesh  Asia       1952    37.5 46886859      684.  46.9    46887.
## 10 Belgium     Europe     1952    68    8730405     8343.   8.73    8730.
## # ℹ 132 more rows


Ile unikalnych krajów jest na każdym kontynencie?

gapminder %>% 
  distinct(continent, country) %>% 
  count
## # A tibble: 1 × 1
##       n
##   <int>
## 1   142


Funkcja rename() pozwala zmieniać nazwy kolumn bez wpływu na ich zawartość. Przydatne, gdy nazwy są nieczytelne lub chcemy używać polskich nazw.


Składnia: rename(nowa_nazwa = stara_nazwa)

gapminder %>% 
  rename(
    kraj = country,
    kontynent = continent,
    rok = year
  ) %>% 
  head()
## # A tibble: 6 × 8
##   kraj        kontynent   rok lifeExp      pop gdpPercap pop_mln pop_tys
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.    8.43   8425.
## 2 Afghanistan Asia       1957    30.3  9240934      821.    9.24   9241.
## 3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   10267.
## 4 Afghanistan Asia       1967    34.0 11537966      836.   11.5   11538.
## 5 Afghanistan Asia       1972    36.1 13079460      740.   13.1   13079.
## 6 Afghanistan Asia       1977    38.4 14880372      786.   14.9   14880.


rename() vs select() - select() usuwa niewymienione kolumny!

gapminder %>% 
  select(kraj = country, rok = year)  # zostają tylko 2 kolumny
## # A tibble: 1,704 × 2
##    kraj          rok
##    <fct>       <int>
##  1 Afghanistan  1952
##  2 Afghanistan  1957
##  3 Afghanistan  1962
##  4 Afghanistan  1967
##  5 Afghanistan  1972
##  6 Afghanistan  1977
##  7 Afghanistan  1982
##  8 Afghanistan  1987
##  9 Afghanistan  1992
## 10 Afghanistan  1997
## # ℹ 1,694 more rows
gapminder %>% 
  rename(kraj = country, rok = year)  # wszystkie kolumny zostają
## # A tibble: 1,704 × 8
##    kraj        continent   rok lifeExp      pop gdpPercap pop_mln pop_tys
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.    8.43   8425.
##  2 Afghanistan Asia       1957    30.3  9240934      821.    9.24   9241.
##  3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   10267.
##  4 Afghanistan Asia       1967    34.0 11537966      836.   11.5   11538.
##  5 Afghanistan Asia       1972    36.1 13079460      740.   13.1   13079.
##  6 Afghanistan Asia       1977    38.4 14880372      786.   14.9   14880.
##  7 Afghanistan Asia       1982    39.9 12881816      978.   12.9   12882.
##  8 Afghanistan Asia       1987    40.8 13867957      852.   13.9   13868.
##  9 Afghanistan Asia       1992    41.7 16317921      649.   16.3   16318.
## 10 Afghanistan Asia       1997    41.8 22227415      635.   22.2   22227.
## # ℹ 1,694 more rows


Funkcje pomocnicze z tidyselectdostarczają rozwiązania ułatwiające wybieranie kolumn na podstawie wzorców w nazwach. Najczęściej używane to:

  • starts_with("prefix") - kolumny zaczynające się na dany tekst

  • ends_with("suffix") - kolumny kończące się danym tekstem

  • contains("text") - kolumny zawierające dany tekst

  • matches("regex") - kolumny pasujące do wyrażenia regularnego

  • everything() - wszystkie pozostałe kolumny


Wybieramy kolumny zawierające “e”

gapminder %>% 
  select(contains("e"))
## # A tibble: 1,704 × 4
##    continent  year lifeExp gdpPercap
##    <fct>     <int>   <dbl>     <dbl>
##  1 Asia       1952    28.8      779.
##  2 Asia       1957    30.3      821.
##  3 Asia       1962    32.0      853.
##  4 Asia       1967    34.0      836.
##  5 Asia       1972    36.1      740.
##  6 Asia       1977    38.4      786.
##  7 Asia       1982    39.9      978.
##  8 Asia       1987    40.8      852.
##  9 Asia       1992    41.7      649.
## 10 Asia       1997    41.8      635.
## # ℹ 1,694 more rows


Wybieramy kolumny zaczynające się na “c”

gapminder %>% 
  select(starts_with("c"))
## # A tibble: 1,704 × 2
##    country     continent
##    <fct>       <fct>    
##  1 Afghanistan Asia     
##  2 Afghanistan Asia     
##  3 Afghanistan Asia     
##  4 Afghanistan Asia     
##  5 Afghanistan Asia     
##  6 Afghanistan Asia     
##  7 Afghanistan Asia     
##  8 Afghanistan Asia     
##  9 Afghanistan Asia     
## 10 Afghanistan Asia     
## # ℹ 1,694 more rows


Te funkcje szczególnie przydają się podczas eksploracji danych. Zamiast od razu tworzyć skomplikowane analizy, warto zacząć od count() i distinct(), żeby zrozumieć strukturę danych, a następnie użyć slice_max()/slice_min() do znalezienia interesujących przypadków.



{wbstats}


Praktyczny przykład analizy


Znajdujemy dane i pakiet, które je zawiera.

Źródło: https://data.worldbank.org/

Szczegóły jak się dostać do zasobów: https://cran.r-project.org/web/packages/wbstats/vignettes/wbstats.html

# install.packages("wbstats")
library(wbstats)


Pobieramy dane - zgodnie z dokumentacją funkcji - funkcja wb_data() o PKB per capita, populacji i oczekiwanej długości życia dla wybranych krajów europejskich z lat 2010-2020.

# ?wb_data()

dane_wb <- wb_data(
  indicator = c(
    "NY.GDP.PCAP.CD",      # PKB per capita (USD)
    "SP.POP.TOTL",         # Populacja
    "SP.DYN.LE00.IN"       # Oczekiwana długość życia
  ),
  country = c("PL", "DE", "CZ", "SK", "HU"),
  start_date = 2010,
  end_date = 2020
)


Porządkowanie i wybór kolumn.

dane_wb %>% 
  select(country, date, NY.GDP.PCAP.CD, SP.DYN.LE00.IN) %>% 
  rename(
    kraj = country,
    rok = date,
    PKB_per_capita = NY.GDP.PCAP.CD,
    dlugosc_zycia = SP.DYN.LE00.IN
  ) %>% 
  arrange(rok, desc(PKB_per_capita)) %>% 
  head(10)
## # A tibble: 10 × 4
##    kraj              rok PKB_per_capita dlugosc_zycia
##    <chr>           <dbl>          <dbl>         <dbl>
##  1 Germany          2010         42410.          80.0
##  2 Czechia          2010         20160.          77.4
##  3 Slovak Republic  2010         16899.          75.1
##  4 Hungary          2010         13190.          74.2
##  5 Poland           2010         12568.          76.2
##  6 Germany          2011         47647.          80.4
##  7 Czechia          2011         22049.          77.9
##  8 Slovak Republic  2011         18469.          76.0
##  9 Hungary          2011         14211.          74.9
## 10 Poland           2011         13868.          76.7


Filtrowanie i tworzenie nowych zmiennych.

dane_wb %>% 
  filter(date >= 2015) %>% 
  mutate(
    populacja_mln = SP.POP.TOTL / 1000000,
    PKB_mld = (NY.GDP.PCAP.CD * SP.POP.TOTL) / 1e9
  ) %>% 
  select(country, date, populacja_mln, PKB_mld) %>% 
  arrange(desc(PKB_mld))
## # A tibble: 30 × 4
##    country  date populacja_mln PKB_mld
##    <chr>   <dbl>         <dbl>   <dbl>
##  1 Germany  2018          82.9   4052.
##  2 Germany  2019          83.1   3957.
##  3 Germany  2020          83.2   3940.
##  4 Germany  2017          82.7   3763.
##  5 Germany  2016          82.3   3538.
##  6 Germany  2015          81.7   3424.
##  7 Poland   2020          37.5    606.
##  8 Poland   2019          38.0    603.
##  9 Poland   2018          38.0    595.
## 10 Poland   2017          38.0    528.
## # ℹ 20 more rows


Grupowanie i podsumowania statystyczne.

dane_wb %>% 
  group_by(country) %>% 
  summarise(
    srednie_PKB = mean(NY.GDP.PCAP.CD, na.rm = TRUE),
    srednia_populacja = mean(SP.POP.TOTL, na.rm = TRUE),
    przyrost_PKB = last(NY.GDP.PCAP.CD) - first(NY.GDP.PCAP.CD),
    liczba_lat = n()
  ) %>% 
  arrange(desc(srednie_PKB))
## # A tibble: 5 × 5
##   country         srednie_PKB srednia_populacja przyrost_PKB liczba_lat
##   <chr>                 <dbl>             <dbl>        <dbl>      <int>
## 1 Germany              45933.         81814340.        4970.         11
## 2 Czechia              21033.         10566126.        3312.         11
## 3 Slovak Republic      18128.          5425728.        2836.         11
## 4 Hungary              14471.          9814032.        3197.         11
## 5 Poland               14010.         37964404.        3583.         11


Kombinacja wielu operacji z pipe.

dane_wb %>% 
  filter(date %in% c(2010, 2015, 2020)) %>% 
  select(country, date, NY.GDP.PCAP.CD, SP.DYN.LE00.IN) %>% 
  group_by(country) %>% 
  mutate(
    zmiana_PKB = NY.GDP.PCAP.CD - first(NY.GDP.PCAP.CD),
    zmiana_procent = (zmiana_PKB / first(NY.GDP.PCAP.CD)) * 100
  ) %>% 
  filter(date == 2020) %>% 
  arrange(desc(zmiana_procent))
## # A tibble: 5 × 6
## # Groups:   country [5]
##   country          date NY.GDP.PCAP.CD SP.DYN.LE00.IN zmiana_PKB zmiana_procent
##   <chr>           <dbl>          <dbl>          <dbl>      <dbl>          <dbl>
## 1 Poland           2020         16151.           76.4      3583.           28.5
## 2 Hungary          2020         16387.           75.4      3197.           24.2
## 3 Slovak Republic  2020         19735.           76.9      2836.           16.8
## 4 Czechia          2020         23473.           78.2      3312.           16.4
## 5 Germany          2020         47380.           81.0      4970.           11.7


Zliczanie i distinct()

dane_wb %>% 
  count(country, name = "liczba_obserwacji")
## # A tibble: 5 × 2
##   country         liczba_obserwacji
##   <chr>                       <int>
## 1 Czechia                        11
## 2 Germany                        11
## 3 Hungary                        11
## 4 Poland                         11
## 5 Slovak Republic                11
dane_wb %>% 
  distinct(country) %>% 
  pull(country)  # pull() wyciąga wektor z jednej kolumny
## [1] "Czechia"         "Germany"         "Hungary"         "Poland"         
## [5] "Slovak Republic"


Znajdowanie ekstremów z slice()


Kraj z najwyższą długością życia w każdym roku?

dane_wb %>% 
  filter(!is.na(SP.DYN.LE00.IN)) %>% 
  group_by(date) %>% 
  slice_max(SP.DYN.LE00.IN, n = 1) %>% 
  select(date, country, SP.DYN.LE00.IN)
## # A tibble: 11 × 3
## # Groups:   date [11]
##     date country SP.DYN.LE00.IN
##    <dbl> <chr>            <dbl>
##  1  2010 Germany           80.0
##  2  2011 Germany           80.4
##  3  2012 Germany           80.5
##  4  2013 Germany           80.5
##  5  2014 Germany           81.1
##  6  2015 Germany           80.6
##  7  2016 Germany           81.0
##  8  2017 Germany           81.0
##  9  2018 Germany           80.9
## 10  2019 Germany           81.3
## 11  2020 Germany           81.0


Szersze dane - porównanie wielu krajów.

dane_szerokie <- wb_data(
  indicator = "NY.GDP.PCAP.CD",
  country = c("PL", "DE", "FR", "GB", "IT", "ES"),
  start_date = 2015,
  end_date = 2020
)

dane_szerokie %>% 
  group_by(iso3c) %>% 
  summarise(
    PKB_2015 = first(NY.GDP.PCAP.CD),
    PKB_2020 = last(NY.GDP.PCAP.CD),
    wzrost = PKB_2020 - PKB_2015,
    wzrost_procent = (wzrost / PKB_2015) * 100
  ) %>% 
  arrange(desc(wzrost_procent))
## # A tibble: 6 × 5
##   iso3c PKB_2015 PKB_2020 wzrost wzrost_procent
##   <chr>    <dbl>    <dbl>  <dbl>          <dbl>
## 1 POL     12638.   16151.  3513.          27.8 
## 2 DEU     41911.   47380.  5469.          13.0 
## 3 FRA     36702.   39170.  2467.           6.72
## 4 ESP     25982.   27234.  1252.           4.82
## 5 ITA     30640.   32091.  1452.           4.74
## 6 GBR     44984.   40405. -4579.         -10.2


Filtrowanie z wieloma warunkami.

dane_wb %>% 
  filter(
    date >= 2018,
    country %in% c("Poland", "Germany"),
    !is.na(NY.GDP.PCAP.CD)
  ) %>% 
  select(country, date, NY.GDP.PCAP.CD) %>% 
  arrange(country, date)
## # A tibble: 6 × 3
##   country  date NY.GDP.PCAP.CD
##   <chr>   <dbl>          <dbl>
## 1 Germany  2018         48875.
## 2 Germany  2019         47624.
## 3 Germany  2020         47380.
## 4 Poland   2018         15658.
## 5 Poland   2019         15875.
## 6 Poland   2020         16151.


Tworzenie kategorii z mutate() + case_when().

dane_wb %>% 
  filter(date == 2020) %>% 
  mutate(
    kategoria_PKB = case_when(
      NY.GDP.PCAP.CD > 40000 ~ "Wysokie",
      NY.GDP.PCAP.CD > 20000 ~ "Średnie",
      TRUE ~ "Niskie"
    )
  ) %>% 
  select(country, NY.GDP.PCAP.CD, kategoria_PKB) %>% 
  arrange(desc(NY.GDP.PCAP.CD))
## # A tibble: 5 × 3
##   country         NY.GDP.PCAP.CD kategoria_PKB
##   <chr>                    <dbl> <chr>        
## 1 Germany                 47380. Wysokie      
## 2 Czechia                 23473. Średnie      
## 3 Slovak Republic         19735. Niskie       
## 4 Hungary                 16387. Niskie       
## 5 Poland                  16151. Niskie



Co to jest tibble?

Tibble to nowoczesna wersja ramki danych (data frame) w R, wprowadzona przez pakiet tibble, który jest częścią ekosystemu tidyverse. Tibble został zaprojektowany tak, aby być bardziej intuicyjny i wygodny w codziennej pracy z danymi.

Załadowanie pakietów

library(dplyr)
library(tibble)

Podstawowe różnice między tibble a data.frame

1. Lepsze wyświetlanie danych

Tradycyjne ramki danych mogą zaśmiecać konsolę, wyświetlając setki wierszy. Tibble pokazuje tylko pierwsze 10 wierszy i tyle kolumn, ile zmieści się na ekranie.

# Tradycyjna ramka danych
df_tradycyjny <- data.frame(
  x = 1:100,
  y = rnorm(100),
  z = letters[1:100]
)

# Tibble
df_tibble <- tibble(
  x = 1:100,
  y = rnorm(100),
  z = letters[1:100]
)

# Porównaj wyświetlanie
df_tibble
## # A tibble: 100 × 3
##        x       y z    
##    <int>   <dbl> <chr>
##  1     1  0.342  a    
##  2     2 -0.0434 b    
##  3     3  0.535  c    
##  4     4 -0.814  d    
##  5     5 -1.53   e    
##  6     6  2.70   f    
##  7     7  0.281  g    
##  8     8 -0.0109 h    
##  9     9  0.378  i    
## 10    10 -0.983  j    
## # ℹ 90 more rows

2. Informacje o typach danych

Tibble automatycznie pokazuje typ każdej kolumny (np. <int>, <dbl>, <chr>), co ułatwia szybkie zrozumienie struktury danych.

przykladowy_tibble <- tibble(
  liczby_calkowite = 1:5,
  liczby_zmiennoprzecinkowe = c(1.5, 2.3, 3.7, 4.1, 5.9),
  tekst = c("Ala", "ma", "kota", "i", "psa"),
  logiczne = c(TRUE, FALSE, TRUE, TRUE, FALSE)
)

przykladowy_tibble
## # A tibble: 5 × 4
##   liczby_calkowite liczby_zmiennoprzecinkowe tekst logiczne
##              <int>                     <dbl> <chr> <lgl>   
## 1                1                       1.5 Ala   TRUE    
## 2                2                       2.3 ma    FALSE   
## 3                3                       3.7 kota  TRUE    
## 4                4                       4.1 i     TRUE    
## 5                5                       5.9 psa   FALSE

3. Nie konwertuje automatycznie stringów na faktory

W tradycyjnych data.frame teksty były często automatycznie konwertowane na faktory (chyba że użyto jawnie stringsAsFactors = FALSE). Tibble nigdy tego nie robi.

# Data.frame - w starszych wersjach R tekst stawał się faktorem
df <- data.frame(imie = c("Anna", "Jan", "Kasia"))
class(df$imie)
## [1] "character"
# Tibble - tekst pozostaje tekstem
tb <- tibble(imie = c("Anna", "Jan", "Kasia"))
class(tb$imie)
## [1] "character"

4. Bezpieczniejsze indeksowanie

Tibble jest bardziej restrykcyjny i ostrzega przed potencjalnymi błędami.

# Tibble zwraca zawsze tibble, nawet dla jednej kolumny
wynik <- przykladowy_tibble[, 1]
class(wynik)  # Nadal tibble
## [1] "tbl_df"     "tbl"        "data.frame"
# Tradycyjny data.frame może zwrócić wektor
wynik_df <- as.data.frame(przykladowy_tibble)[, 1]
class(wynik_df)  # Wektor
## [1] "integer"

Tworzenie tibble

Sposób 1: Funkcja tibble()

studenci <- tibble(
  imie = c("Anna", "Jan", "Kasia", "Piotr", "Maria"),
  wiek = c(20, 22, 21, 23, 20),
  ocena = c(4.5, 3.5, 5.0, 4.0, 4.5),
  zdal = c(TRUE, TRUE, TRUE, TRUE, TRUE)
)

studenci
## # A tibble: 5 × 4
##   imie   wiek ocena zdal 
##   <chr> <dbl> <dbl> <lgl>
## 1 Anna     20   4.5 TRUE 
## 2 Jan      22   3.5 TRUE 
## 3 Kasia    21   5   TRUE 
## 4 Piotr    23   4   TRUE 
## 5 Maria    20   4.5 TRUE

Sposób 2: Konwersja z data.frame

# Mamy tradycyjny data.frame
stary_df <- data.frame(
  x = 1:5,
  y = letters[1:5]
)

# Konwertujemy na tibble
nowy_tibble <- as_tibble(stary_df)
nowy_tibble
## # A tibble: 5 × 2
##       x y    
##   <int> <chr>
## 1     1 a    
## 2     2 b    
## 3     3 c    
## 4     4 d    
## 5     5 e

Sposób 3: Funkcja tribble() - wierszami

Przydatne do tworzenia małych zbiorów danych ręcznie:

kraje <- tribble(
  ~kraj,      ~stolica,     ~populacja_mln,
  "Polska",   "Warszawa",   38,
  "Niemcy",   "Berlin",     83,
  "Francja",  "Paryż",      67,
  "Włochy",   "Rzym",       60
)

kraje
## # A tibble: 4 × 3
##   kraj    stolica  populacja_mln
##   <chr>   <chr>            <dbl>
## 1 Polska  Warszawa            38
## 2 Niemcy  Berlin              83
## 3 Francja Paryż               67
## 4 Włochy  Rzym                60

Praca z tibble w dplyr

Wszystkie funkcje z pakietu dplyr działają świetnie z tibble:

studenci %>%
  filter(wiek >= 21) %>%
  arrange(desc(ocena)) %>%
  select(imie, ocena)
## # A tibble: 3 × 2
##   imie  ocena
##   <chr> <dbl>
## 1 Kasia   5  
## 2 Piotr   4  
## 3 Jan     3.5

Praktyczny przykład z gapminder

library(gapminder)

# gapminder jest już tibble
class(gapminder)
## [1] "tbl_df"     "tbl"        "data.frame"
# Wyświetlenie
gapminder
## # A tibble: 1,704 × 8
##    country     continent  year lifeExp      pop gdpPercap pop_mln pop_tys
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>   <dbl>   <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.    8.43   8425.
##  2 Afghanistan Asia       1957    30.3  9240934      821.    9.24   9241.
##  3 Afghanistan Asia       1962    32.0 10267083      853.   10.3   10267.
##  4 Afghanistan Asia       1967    34.0 11537966      836.   11.5   11538.
##  5 Afghanistan Asia       1972    36.1 13079460      740.   13.1   13079.
##  6 Afghanistan Asia       1977    38.4 14880372      786.   14.9   14880.
##  7 Afghanistan Asia       1982    39.9 12881816      978.   12.9   12882.
##  8 Afghanistan Asia       1987    40.8 13867957      852.   13.9   13868.
##  9 Afghanistan Asia       1992    41.7 16317921      649.   16.3   16318.
## 10 Afghanistan Asia       1997    41.8 22227415      635.   22.2   22227.
## # ℹ 1,694 more rows
# Analiza z użyciem dplyr
gapminder %>%
  filter(year == 2007, continent == "Europe") %>%
  arrange(desc(gdpPercap)) %>%
  select(country, lifeExp, gdpPercap) %>%
  head(10)
## # A tibble: 10 × 3
##    country     lifeExp gdpPercap
##    <fct>         <dbl>     <dbl>
##  1 Norway         80.2    49357.
##  2 Ireland        78.9    40676.
##  3 Switzerland    81.7    37506.
##  4 Netherlands    79.8    36798.
##  5 Iceland        81.8    36181.
##  6 Austria        79.8    36126.
##  7 Denmark        78.3    35278.
##  8 Sweden         80.9    33860.
##  9 Belgium        79.4    33693.
## 10 Finland        79.3    33207.

Podsumowanie

Zalety tibble:

  • czytelne wyświetlanie danych

  • pokazuje typy kolumn

  • nie konwertuje automatycznie typów

  • bardziej przewidywalne zachowanie

  • idealnie współpracuje z {dplyr} i całym {tidyverse}

  • ostrzega przed potencjalnymi błędami

Kiedy używać tibble?

  • Zawsze, gdy pracujesz z {tidyverse} ({dplyr}, {tidyr}, {ggplot2})

  • Gdy chcesz nowoczesnego i bezpieczniejszego sposobu pracy z danymi

  • Gdy pracujesz z dużymi zbiorami danych

Kompatybilność

Tibble jest kompatybilny z większością funkcji, które działają z data.frame. W razie potrzeby możesz zawsze przekonwertować tibble z powrotem na data.frame:

class(studenci)
## [1] "tbl_df"     "tbl"        "data.frame"

tbl_df to konkretna klasa obiektu typu tibble (czyli ramki danych w stylu {tidyverse}).

tbl to bardziej ogólna klasa, której używały wcześniejsze wersje pakietów z rodziny {dplyr} (np. przy pracy z bazami danych lub tabelami SQL).

# Konwersja tibble -> data.frame
df_z_powrotem <- as.data.frame(studenci)
class(df_z_powrotem)
## [1] "data.frame"

!!! Pracując z pakietem dplyr i całym ekosystemem tidyverse, tibble jest standardem i rekomendowaną praktyką!



Źródła i inspiracje pomocne w przygotowaniu niniejszej prezentacji: