4 Przetwarzanie danych - dplyr
4.1 Pakiety
4.1.1 Pakiet dplyr
Pakiet dplyr wykorzystuje się do podstawowych operacji przetwarzania danych z wykrzystaniem obiektów typu data.frame. Podstawowe funkcje pakietu to:
select()- tworzenie podzbioru danych poprzez wybór zmiennych na podstawie ich nazw,filter()- tworzenie podzbioru danych poprzez wybór wierszy na podstawie określonego warunku,arrange()- sortowanie danych,mutate()- tworzenie nowych zmiennych na podstawie określenia warunku,summarize()- podsumowanie danych, np. poprzez obliczenie statystyk podstawowych.
Pakiet dplyr dostarcza także funkcji:
- do grupowania danych:
group_by()- pozwala na wykonanie operacji w podziale na grupy. - do łączenia dwóch lub więcej obiektów (data.frame):
join(),left_join(),right_join()
Pakiet dplyr pozwala także na wykorzystanie operatora łączącego funkcje %>%
Więcej informacji:
- dokumentacja pakietu: https://dplyr.tidyverse.org/
- podstawowe funkcje pakietu: “Cheat Sheet”
4.1.2 Pakiet tidyr
Dane wykorzysywane w analizach muszą być przechowywane w tzw. uporządkowany sposób (ang. tidy data). Uporządkowane dane to dane, w których:
- każda zmienna przechowywana jest w osobnej kolumnie.
- każda obserwacja jest zapisana w osobnym wierszu w tabeli danych
- każda wartość przechowywana jest w osobnej komórce (tzn. każda komórka przechowuje tylko jedną wartość).
Pakiet tidyr() zawiera zestaw funkcji, które ułatwiają tworzenie uporządkowanych danych. Uporządkowane dane mogą być przechowywane w dwóch układach: układzie długim i układzie szerokim (więcej informacji w podrozdziale Sekcja 4.3)
Więcej informacji:
- dokumentacja: https://tidyr.tidyverse.org/
- cheat sheet: https://github.com/rstudio/cheatsheets/blob/main/tidyr.pdf
4.2 Przetwarzanie danych z pakietem dplyr
4.2.1 Funkcja select()
- Wybór kolumn country, year oraz pop.
sel1 <- select(gapminder, country, year, pop)
head(sel1)# A tibble: 6 × 3
country year pop
<fct> <int> <int>
1 Afghanistan 1952 8425333
2 Afghanistan 1957 9240934
3 Afghanistan 1962 10267083
4 Afghanistan 1967 11537966
5 Afghanistan 1972 13079460
6 Afghanistan 1977 14880372
Ze zbioru danych gapminder proszę wybrać dane dla zmiennych country, year oraz lifeExp.
Rozwiązanie:
Wykorzystaj funkcję select() z pakietu dplyr
select(gapminder, country, year, lifeExp) - Wybór wszystkich kolumn z wyjątkiem kolumny kontynent
sel2 <- select(gapminder, -continent)
head(sel2)# A tibble: 6 × 5
country year lifeExp pop gdpPercap
<fct> <int> <dbl> <int> <dbl>
1 Afghanistan 1952 28.8 8425333 779.
2 Afghanistan 1957 30.3 9240934 821.
3 Afghanistan 1962 32.0 10267083 853.
4 Afghanistan 1967 34.0 11537966 836.
5 Afghanistan 1972 36.1 13079460 740.
6 Afghanistan 1977 38.4 14880372 786.
Ze zbioru danych gapminder proszę wybrać wszystkie kolumny z wyjątkiem continent oraz gdpPercap.
Rozwiązanie:
Wykorzystaj funkcję select() z pakietu dplyr
select(gapminder, -continent, -gdpPercap) 4.2.2 Funkcja filter()
Funkcja filter() służy do tworzenia podzbiorów danych poprzez wybór obserwacji spełniających określone warunki. Warunki są określane za pomocą operatorów logicznych (!=, ==, >, <, >=, <=, |, &).
- Wybór danych dla roku 2007.
filt1 <- filter(gapminder, year == 2007)
head(filt1)# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 2007 43.8 31889923 975.
2 Albania Europe 2007 76.4 3600523 5937.
3 Algeria Africa 2007 72.3 33333216 6223.
4 Angola Africa 2007 42.7 12420476 4797.
5 Argentina Americas 2007 75.3 40301927 12779.
6 Australia Oceania 2007 81.2 20434176 34435.
Wybierz dane dla kontynentu Europa.
Rozwiązanie:
Wykorzystaj funkcję filter() z pakietu dplyr
filter(gapminder, continent == 'Europe') W jaki inny sposób można wybrać dane dla roku 2007?
- Wybór danych dla roku 2007, w których oczekiwana długość trwania życia przekracza 80 lat.
filt2 <- filter(gapminder, year == 2007 & lifeExp > 80)
filt2# A tibble: 13 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Australia Oceania 2007 81.2 20434176 34435.
2 Canada Americas 2007 80.7 33390141 36319.
3 France Europe 2007 80.7 61083916 30470.
4 Hong Kong, China Asia 2007 82.2 6980412 39725.
5 Iceland Europe 2007 81.8 301931 36181.
6 Israel Asia 2007 80.7 6426679 25523.
7 Italy Europe 2007 80.5 58147733 28570.
8 Japan Asia 2007 82.6 127467972 31656.
9 New Zealand Oceania 2007 80.2 4115771 25185.
10 Norway Europe 2007 80.2 4627926 49357.
11 Spain Europe 2007 80.9 40448191 28821.
12 Sweden Europe 2007 80.9 9031088 33860.
13 Switzerland Europe 2007 81.7 7554661 37506.
Wybór danych dla roku 2007, dla wszystkich kontynentów z wyjątkiem Azji, w których oczekiwana długość trwania życia przekracza 80 lat.
Rozwiązanie:
Wykorzystaj funkcję filter() z pakietu dplyr
filter(gapminder, continent != 'Asia' & year == 2007 & lifeExp > 80) 4.2.3 Funkcja mutate()
Funkcja mutate() służy do tworzenia nowych zmiennych na podstawie określonego wyrażenia
- Dodaj kolumnę abbr_country zawierającą trzyliterowy kod państwa.
gap2 <- mutate(gapminder, abbr_country = toupper(substr(country, 1, 3)))
head(gap2)# A tibble: 6 × 7
country continent year lifeExp pop gdpPercap abbr_country
<fct> <fct> <int> <dbl> <int> <dbl> <chr>
1 Afghanistan Asia 1952 28.8 8425333 779. AFG
2 Afghanistan Asia 1957 30.3 9240934 821. AFG
3 Afghanistan Asia 1962 32.0 10267083 853. AFG
4 Afghanistan Asia 1967 34.0 11537966 836. AFG
5 Afghanistan Asia 1972 36.1 13079460 740. AFG
6 Afghanistan Asia 1977 38.4 14880372 786. AFG
Co w powyższym poleceniu robi funkcja
substr()oraztoupper()?
Dodaj do zbioru danych kolumnę pop_mln zawierająca liczbę ludności w milionach.
Rozwiązanie:
Wykorzystaj funkcję mutate() z pakietu dplyr
ex6 <- mutate(gapminder, pop_mln = pop/1000000)4.2.4 Funkcja arrange()
Funkcja arrange() wykorzystywana jest do sortowania danych.
- Sortowanie rosnące względem zmiennej lifeExp
arr1 <- arrange(gapminder, lifeExp)
head(arr1)# A tibble: 6 × 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.
- Sortowanie malejące względem zmiennej lifeExp
arr2 <- arrange(gapminder, desc(lifeExp))
head(arr2)# A tibble: 6 × 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.
Posortuj dane malejąco względem zmiennej pop. Pokaż 10 pierwszych wierszy
Rozwiązanie:
Wykorzystaj funkcję arrange() z pakietu dplyr
ex7 <- arrange(gapminder, desc(pop))
head(ex7, 10)- Sortowanie rosnące względem kontynentu (continent) oraz oczekiwanej długości trwania życia (lifeExp)
arr3 <- arrange(gapminder, continent, lifeExp)
head(arr3)# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Rwanda Africa 1992 23.6 7290203 737.
2 Gambia Africa 1952 30 284320 485.
3 Angola Africa 1952 30.0 4232095 3521.
4 Sierra Leone Africa 1952 30.3 2143249 880.
5 Mozambique Africa 1952 31.3 6446316 469.
6 Sierra Leone Africa 1957 31.6 2295678 1004.
Posortuj malejąco względem nazwy państwa oraz rosnąco względem liczby ludności. Pokaż 4 pierwsze wiersze
Rozwiązanie:
Wykorzystaj funkcję arrange() z pakietu dplyr
ex8 <- arrange(gapminder, desc(country), pop)
head(ex8, 4)4.2.5 Funkcja rename()
Funkcja rename() służy do zmiany nazw kolumn. W funkcji rename() definiujemy nowa_nazwa = stara_nazwa.
- Zmiana nazw kolumn na polskie nazwy.
gap2 <- rename(gapminder, panstwo = country, kontynent = continent, rok = year, dlugosc_zycia = lifeExp, ludnosc = pop, PKB = gdpPercap)
names(gap2)[1] "panstwo" "kontynent" "rok" "dlugosc_zycia"
[5] "ludnosc" "PKB"
Korzystając ze strony pomocy funkcji
rename()sprawdź jak zmienić nazwy kolumn w obiekcie gap2 na drukowane litery.
Rozwiązanie:
Wykorzystaj funkcję rename()` z pakietu dplyr
rename_with(gapminder, toupper)4.2.6 Funkcja summarize()
Funkcja summarize() służy do wykonywania podsumowań statystycznych. Tworzy kolumny z zadanymi statystykami.
- Średnia oczekiwana długość trwania życia.
smr1 <- summarize(gapminder,
srednia = mean(lifeExp))
smr1# A tibble: 1 × 1
srednia
<dbl>
1 59.5
- Średnia, minimalna oraz maksymalna oczekiwana długość trwania życia.
smr2 <- summarize(gapminder,
srednia = mean(lifeExp),
min = min(lifeExp),
max = max(lifeExp))
smr2# A tibble: 1 × 3
srednia min max
<dbl> <dbl> <dbl>
1 59.5 23.6 82.6
Oblicz średnią, odchylenie standardowe, minimum i maksimum dla zmiennej gdpPercap.
Rozwiązanie:
Wykorzystaj funkcję summarize z pakietu dplyr
ex10 <- summarize(gapminder,
sd = sd(gdpPercap),
min = min(gdpPercap),
max = max(gdpPercap))
ex104.2.7 Grupowanie .by
- argument .by; np. summarize(, .by) - grupowanie dokonywane tylko na potrzeby danej funkcji
grp1 = summarize(filt1 ,
srednia = mean(lifeExp),
.by = continent)
grp1# A tibble: 5 × 2
continent srednia
<fct> <dbl>
1 Asia 70.7
2 Europe 77.6
3 Africa 54.8
4 Americas 73.6
5 Oceania 80.7
Oblicz minimalną i maksymalną długość trwania życia w 2007 roku w podziale na kontynenty.
Rozwiązanie:
Wykorzystaj funkcję summarize z pakietu dplyr
ex11filt <- filter(gapminder, year == 2007)
ex11 <- summarize(ex11filt,
min = min(lifeExp, na.rm = TRUE),
max = max(lifeExp, na.rm = TRUE),
.by = continent)
ex114.2.8 Funkcja pull()
Funkcja pull() służy do wyciągania tylko jednej zmiennej
life_exp <- pull(gapminder, lifeExp)
head(life_exp)[1] 28.801 30.332 31.997 34.020 36.088 38.438
continent <- pull(gapminder, continent)
head(continent)[1] Asia Asia Asia Asia Asia Asia
Levels: Africa Americas Asia Europe Oceania
Wybierz ze zbioru danych kolumnę pop.
Rozwiązanie:
Wykorzystaj funkcję pull z pakietu dplyr
ex12 <- pull(gapminder, pop)
head(ex12)4.2.9 Operator łączący (%>%).
Używając pakietu dplyr można łączyć ze sobą funkcje używając operatora %>%
Przykład
Które kraje w roku 1952 miały liczbę ludności powyżej 100 milionów?
Aby odpowiedzieć na to pytanie możemy wykonać każdą operację osobno, i jej wynik zapisać w osobnym obiekcie. Operator łączący %>% pozwala natomiast na przekazanie wyniku działania jednej funkcji do drugiej, bez tworzenia osobnych obiektów.
f1 <- filter(gapminder, pop > 100000000 & year == 1952)
s1 <- select(f1, country, pop)
a1 <- arrange(s1, pop) # sortowanie danych wzgledem pop
a1# A tibble: 3 × 2
country pop
<fct> <int>
1 United States 157553000
2 India 372000000
3 China 556263527
- Wykorzystanie operatora łączącego
%>%
df <- gapminder %>% #wejsciowy zbior danych
filter(pop > 100000000 & year == 1952) %>% # wybor krajow z pop > 100mln w roku 1952
select(country, pop) %>% # wybor kolumn country, pop
arrange(pop) # sortowanie danych wzgledem pop
df# A tibble: 3 × 2
country pop
<fct> <int>
1 United States 157553000
2 India 372000000
3 China 556263527
Które kraje w 2007 roku miały populację powyżej 100 milionów? Posortuj wynik od krajów z największą liczbą ludności do krajów z najmniejszą liczbą ludności.
Rozwiązanie:
ex13 <- gapminder %>% #wejsciowy zbior danych
filter(pop > 100000000 & year == 2007) %>% # wybor krajow z pop > 100mln w roku 2007
select(country, pop) %>% # wybor kolumn country, pop
arrange(desc(pop)) # sortowanie danych wzgledem pop
ex134.2.10 Funkcja join()
x <- data.frame(country = c("Poland", "USA", "Germany"), pop = c(36.82, 333.3, 83.8))
y = data.frame(country = c("Poland", "USA", "Italy"), pop = c(36.82, 333.3, 58.94))x country pop
1 Poland 36.82
2 USA 333.30
3 Germany 83.80
y country pop
1 Poland 36.82
2 USA 333.30
3 Italy 58.94
- Funkcja
inner_join(x, y)zwraca tylko obiekty występujące w obu tabelach
inner_df <- inner_join(x, y, by = 'country')
inner_df country pop.x pop.y
1 Poland 36.82 36.82
2 USA 333.30 333.30
- Funkcja
left_join(x, y)zachowuje wszystkie obserwacje w x, niezależnie od tego, czy mają swój odpowiednik w tabeli y. Jest to najczęściej używane łączenie, ponieważ gwarantuje, że nie utracimy obserwacji z tabeli podstawowej (x).
left_df <- left_join(x, y, by = 'country')
left_df country pop.x pop.y
1 Poland 36.82 36.82
2 USA 333.30 333.30
3 Germany 83.80 NA
- Funkcja
right_join(x, y)zachowuje wszystkie obserwacje w y.
right_df <- right_join(x, y, by = 'country')
right_df country pop.x pop.y
1 Poland 36.82 36.82
2 USA 333.30 333.30
3 Italy NA 58.94
- Funkcja
full_join(x, y)zwraca wszystkie obiekty z tabeli x oraz z tabeli y.
full_df <- full_join(x, y, by = 'country')
full_df country pop.x pop.y
1 Poland 36.82 36.82
2 USA 333.30 333.30
3 Germany 83.80 NA
4 Italy NA 58.94
4.3 Układ danych
Dane w tabeli mogą być zapisywane w układzie długim lub szerokim.

Zmiana układu danych jest możliwa z użyciem funkcji z pakietu tidyr.
library(tidyr)- Układ długi
Dane gapminder są zapisane w układzie długim:
head(gapminder, 10)# A tibble: 10 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
7 Afghanistan Asia 1982 39.9 12881816 978.
8 Afghanistan Asia 1987 40.8 13867957 852.
9 Afghanistan Asia 1992 41.7 16317921 649.
10 Afghanistan Asia 1997 41.8 22227415 635.
- Układ szeroki
Funkcja pivot_wider() przekształca dane z formatu długiego w szeroki. Obiekt gapminder_wide w każdej kolumnie przechowuje dane dla jednego roku, a w każdym wierszu dla kraju.
gapminder2 <- select(gapminder, -continent,
-lifeExp, -gdpPercap)
gapminder_wide <- pivot_wider(gapminder2,
names_from = year,
values_from = pop)
head(gapminder_wide)# A tibble: 6 × 13
country `1952` `1957` `1962` `1967` `1972` `1977` `1982` `1987` `1992` `1997`
<fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 Afghani… 8.43e6 9.24e6 1.03e7 1.15e7 1.31e7 1.49e7 1.29e7 1.39e7 1.63e7 2.22e7
2 Albania 1.28e6 1.48e6 1.73e6 1.98e6 2.26e6 2.51e6 2.78e6 3.08e6 3.33e6 3.43e6
3 Algeria 9.28e6 1.03e7 1.10e7 1.28e7 1.48e7 1.72e7 2.00e7 2.33e7 2.63e7 2.91e7
4 Angola 4.23e6 4.56e6 4.83e6 5.25e6 5.89e6 6.16e6 7.02e6 7.87e6 8.74e6 9.88e6
5 Argenti… 1.79e7 1.96e7 2.13e7 2.29e7 2.48e7 2.70e7 2.93e7 3.16e7 3.40e7 3.62e7
6 Austral… 8.69e6 9.71e6 1.08e7 1.19e7 1.32e7 1.41e7 1.52e7 1.63e7 1.75e7 1.86e7
# ℹ 2 more variables: `2002` <int>, `2007` <int>
Wybierz z danych kolumnę country, lifeExp oraz year i zamień dane na układ szeroki.
Rozwiązanie:
ex14 <- gapminder %>%
select(country, year, lifeExp) %>%
pivot_wider(names_from = year, values_from = lifeExp)
ex14- Układ szeroki -> Układ długi
gapminder_long <- pivot_longer(gapminder_wide,
cols = colnames(gapminder_wide)[-1])
gapminder_long # A tibble: 1,704 × 3
country name value
<fct> <chr> <int>
1 Afghanistan 1952 8425333
2 Afghanistan 1957 9240934
3 Afghanistan 1962 10267083
4 Afghanistan 1967 11537966
5 Afghanistan 1972 13079460
6 Afghanistan 1977 14880372
7 Afghanistan 1982 12881816
8 Afghanistan 1987 13867957
9 Afghanistan 1992 16317921
10 Afghanistan 1997 22227415
# ℹ 1,694 more rows
Wybierz z danych kolumnę country, gdpPercap oraz year i zamień dane na układ szeroki. Następnie z układu szerokiego zamień dane na układ długi.
Rozwiązanie:
ex15_wide <- gapminder %>%
select(country, year, gdpPercap) %>%
pivot_wider(names_from = year, values_from = gdpPercap)
ex15_long <- pivot_longer(ex15_wide, cols = colnames(ex15_wide)[-1])