Projekt R

Dplyr – manipulacja data frame

W dziesiejszym poście zapoznamy Was z biblioteką dplyr, która w łatwy sposób pozwala manipulować zmiennymi typu data frame. Do naszego przykładu wykorzystamy wykaz pól powierzchni geodezyjnych, który możecie pobrać tutaj w ramach otwartych danych.

Zainicjujmy bibliotekę:

library(dplyr)

Wczytajmy dane:

dt = readr::read_csv("d:/GIS_in_R/powierzchnie.csv")

W pierwszej kolejności wykorzystamy narzędzie filter pozwalające na wyselekcjonowanie wierszy spełniających zadane kryterium. W naszym przypadku będą to powiaty dla których TERYT ma 5 znaków:

dt %›% filter(nchar(TERYT) == 5)

W wyniku otrzymujemy:

# A tibble: 380 x 3
   TERYT `Nazwa jednostki`     `Powierzchnia`     
   ‹chr› ‹chr›                               ‹dbl›
 1 02 01 Powiat bolesławiecki               130351
 2 02 02 Powiat dzierżoniowski               47851
 3 02 03 Powiat głogowski                    44327
 4 02 04 Powiat górowski                     73827
 5 02 05 Powiat jaworski                     58155
 6 02 06 Powiat jeleniogórski                62714
 7 02 07 Powiat kamiennogórski               39569
 8 02 08 Powiat kłodzki                     164330
 9 02 09 Powiat legnicki                     74408
10 02 10 Powiat lubański                     42830
# ... with 370 more rows

Dodajmy do naszej poprzedniej linijki kodu jeszcze funkcję mutate za pomocą której możemy wyliczyć nową wartość (kolumnę). My wyznaczymy na podstawie TERYTu powiatu TERYT województwa (TERYT_woj) przy użyciu funkcji substr:

dt %›% filter(nchar(TERYT) == 5) %›% 
mutate(TERYT_woj = substr(TERYT,0,2))

W wyniku mamy:

# A tibble: 380 x 4
   TERYT `Nazwa jednostki`     `Powierzchnia`      TERYT_woj
   ‹chr› ‹chr›                               ‹dbl› ‹chr›    
 1 02 01 Powiat bolesławiecki               130351 02       
 2 02 02 Powiat dzierżoniowski               47851 02       
 3 02 03 Powiat głogowski                    44327 02       
 4 02 04 Powiat górowski                     73827 02       
 5 02 05 Powiat jaworski                     58155 02       
 6 02 06 Powiat jeleniogórski                62714 02       
 7 02 07 Powiat kamiennogórski               39569 02       
 8 02 08 Powiat kłodzki                     164330 02       
 9 02 09 Powiat legnicki                     74408 02       
10 02 10 Powiat lubański                     42830 02       
# ... with 370 more rows

Za pomocą funkcji select wybieramy interesujące nas kolumny:

dt %›% select(TERYT,'Nazwa jednostki')

I mamy:

# A tibble: 4,201 x 2
   TERYT      `Nazwa jednostki`            
   ‹chr›      ‹chr›                        
 1 00         POLSKA                       
 2 02         WOJ. DOLNOŚLĄSKIE            
 3 02 01      Powiat bolesławiecki         
 4 02 01 01 1 Bolesławiec                  
 5 02 01 02 2 Bolesławiec                  
 6 02 01 03 2 Gromadka                     
 7 02 01 04 3 Nowogrodziec                 
 8 02 01 04 4 Nowogrodziec - miasto        
 9 02 01 04 5 Nowogrodziec - obszar wiejski
10 02 01 05 2 Osiecznica                   
# ... with 4,191 more rows

Wykonany wcześniej select wykorzystamy do dodanie do naszych powiatów nazw województw, korzystając z left_join z grupy funkcji join:

dt %›% filter(nchar(TERYT) == 5) %›% 
mutate(TERYT_woj = substr(TERYT,0,2)) %›% 
left_join(dt %›% select(TERYT,'Nazwa jednostki'), by = c("TERYT_woj" = "TERYT"))

Uzupełniona tabela wygląda następująco:

# A tibble: 380 x 5
   TERYT `Nazwa jednostki.x`   `Powierzchnia`      TERYT_woj `Nazwa jednostki.y`
   ‹chr› ‹chr›                               ‹dbl› ‹chr›     ‹chr›              
 1 02 01 Powiat bolesławiecki               130351 02        WOJ. DOLNOŚLĄSKIE  
 2 02 02 Powiat dzierżoniowski               47851 02        WOJ. DOLNOŚLĄSKIE  
 3 02 03 Powiat głogowski                    44327 02        WOJ. DOLNOŚLĄSKIE  
 4 02 04 Powiat górowski                     73827 02        WOJ. DOLNOŚLĄSKIE  
 5 02 05 Powiat jaworski                     58155 02        WOJ. DOLNOŚLĄSKIE  
 6 02 06 Powiat jeleniogórski                62714 02        WOJ. DOLNOŚLĄSKIE  
 7 02 07 Powiat kamiennogórski               39569 02        WOJ. DOLNOŚLĄSKIE  
 8 02 08 Powiat kłodzki                     164330 02        WOJ. DOLNOŚLĄSKIE  
 9 02 09 Powiat legnicki                     74408 02        WOJ. DOLNOŚLĄSKIE  
10 02 10 Powiat lubański                     42830 02        WOJ. DOLNOŚLĄSKIE  
# ... with 370 more rows

Na końcu w naszej długiej linijce kodu dodamy select tylko interesujących nas w wynikowej tabeli kolumn (TERYT, Nazwa jednostki, Powierzchnia i Nazwa województwa). Nadamy im nowe nazwy (TERYT, Nazwa, Pow, Woj). Wynik zapiszemy do zmiennej dt:

dt = dt %›% filter(nchar(TERYT) == 5) %›% 
mutate(TERYT_woj = substr(TERYT,0,2)) %›% 
left_join(dt %›% select(TERYT,'Nazwa jednostki'), by = c("TERYT_woj" = "TERYT")) %›%
select(TERYT,Nazwa = `Nazwa jednostki.x`,Pow = `Powierzchnia`     ,Woj = `Nazwa jednostki.y`)

Zmienna dt powinna zawierać takie dane:

# A tibble: 380 x 4
   TERYT Nazwa                    Pow Woj              
   ‹chr› ‹chr›                  ‹dbl› ‹chr›            
 1 02 01 Powiat bolesławiecki  130351 WOJ. DOLNOŚLĄSKIE
 2 02 02 Powiat dzierżoniowski  47851 WOJ. DOLNOŚLĄSKIE
 3 02 03 Powiat głogowski       44327 WOJ. DOLNOŚLĄSKIE
 4 02 04 Powiat górowski        73827 WOJ. DOLNOŚLĄSKIE
 5 02 05 Powiat jaworski        58155 WOJ. DOLNOŚLĄSKIE
 6 02 06 Powiat jeleniogórski   62714 WOJ. DOLNOŚLĄSKIE
 7 02 07 Powiat kamiennogórski  39569 WOJ. DOLNOŚLĄSKIE
 8 02 08 Powiat kłodzki        164330 WOJ. DOLNOŚLĄSKIE
 9 02 09 Powiat legnicki        74408 WOJ. DOLNOŚLĄSKIE
10 02 10 Powiat lubański        42830 WOJ. DOLNOŚLĄSKIE
# ... with 370 more rows

Dla utworzonej tabeli wyliczymy minimalną, średnią i maksymalną powierzchnię powiatów z wykorzystaniem narzędzia summarise:

dt %›% summarise(min = min(Pow), avg = mean(Pow), max = max(Pow))
# A tibble: 1 x 3
    min    avg    max
  ‹dbl›  ‹dbl›  ‹dbl›
1  1331 82291. 297644

W przypadku gdy chcemy wyliczyć te wartości dla województw naszą linjkę należy uzupełnić o funcję grupującą group_by:

dt %›% group_by(Woj) %›% 
summarise(min = min(Pow), avg = mean(Pow), max = max(Pow))
# A tibble: 16 x 4
   Woj                        min     avg    max
   ‹chr›                    ‹dbl›   ‹dbl›  ‹dbl›
 1 WOJ. DOLNOŚLĄSKIE         5629  66489  164330
 2 WOJ. KUJAWSKO-POMORSKIE   5776  78136. 147418
 3 WOJ. LUBELSKIE            3034 104677. 275426
 4 WOJ. LUBUSKIE             8572  99914. 139278
 5 WOJ. ŁÓDZKIE              3460  75912. 149083
 6 WOJ. MAŁOPOLSKIE          5758  69013. 154980
 7 WOJ. MAZOWIECKIE          3186  84663. 209355
 8 WOJ. OPOLSKIE            14888  78432. 153430
 9 WOJ. PODKARPACKIE         4472  71383. 130837
10 WOJ. PODLASKIE            3267 118747. 297644
11 WOJ. POMORSKIE            1728  91618. 230424
12 WOJ. ŚLĄSKIE              1331  34259. 152205
13 WOJ. ŚWIĘTOKRZYSKIE      10965  83646. 224607
14 WOJ. WARMIŃSKO-MAZURSKIE  7982 115112. 283802
15 WOJ. WIELKOPOLSKIE        3186  85219. 189988
16 WOJ. ZACHODNIOPOMORSKIE   9834 109070. 186911

Dodajmy jeszcze liczbę powiatów:

dt %›% group_by(Woj) %›% 
summarise(nr = length(Pow), min = min(Pow), avg = mean(Pow), max = max(Pow))
# A tibble: 16 x 5
   Woj                         nr   min     avg    max
   ‹chr›                    ‹int› ‹dbl›   ‹dbl›  ‹dbl›
 1 WOJ. DOLNOŚLĄSKIE           30  5629  66489  164330
 2 WOJ. KUJAWSKO-POMORSKIE     23  5776  78136. 147418
 3 WOJ. LUBELSKIE              24  3034 104677. 275426
 4 WOJ. LUBUSKIE               14  8572  99914. 139278
 5 WOJ. ŁÓDZKIE                24  3460  75912. 149083
 6 WOJ. MAŁOPOLSKIE            22  5758  69013. 154980
 7 WOJ. MAZOWIECKIE            42  3186  84663. 209355
 8 WOJ. OPOLSKIE               12 14888  78432. 153430
 9 WOJ. PODKARPACKIE           25  4472  71383. 130837
10 WOJ. PODLASKIE              17  3267 118747. 297644
11 WOJ. POMORSKIE              20  1728  91618. 230424
12 WOJ. ŚLĄSKIE                36  1331  34259. 152205
13 WOJ. ŚWIĘTOKRZYSKIE         14 10965  83646. 224607
14 WOJ. WARMIŃSKO-MAZURSKIE    21  7982 115112. 283802
15 WOJ. WIELKOPOLSKIE          35  3186  85219. 189988
16 WOJ. ZACHODNIOPOMORSKIE     21  9834 109070. 186911

I na koniec posortujmy nasze wyniki po liczbie powiatów używając funkcji arrange:

dt %›% group_by(Woj) %›% 
summarise(nr = length(Pow), min = min(Pow), avg = mean(Pow), max = max(Pow)) %›%
arrange(nr)
# A tibble: 16 x 5
   Woj                         nr   min     avg    max
   ‹chr›                    ‹int› ‹dbl›   ‹dbl›  ‹dbl›
 1 WOJ. OPOLSKIE               12 14888  78432. 153430
 2 WOJ. LUBUSKIE               14  8572  99914. 139278
 3 WOJ. ŚWIĘTOKRZYSKIE         14 10965  83646. 224607
 4 WOJ. PODLASKIE              17  3267 118747. 297644
 5 WOJ. POMORSKIE              20  1728  91618. 230424
 6 WOJ. WARMIŃSKO-MAZURSKIE    21  7982 115112. 283802
 7 WOJ. ZACHODNIOPOMORSKIE     21  9834 109070. 186911
 8 WOJ. MAŁOPOLSKIE            22  5758  69013. 154980
 9 WOJ. KUJAWSKO-POMORSKIE     23  5776  78136. 147418
10 WOJ. LUBELSKIE              24  3034 104677. 275426
11 WOJ. ŁÓDZKIE                24  3460  75912. 149083
12 WOJ. PODKARPACKIE           25  4472  71383. 130837
13 WOJ. DOLNOŚLĄSKIE           30  5629  66489  164330
14 WOJ. WIELKOPOLSKIE          35  3186  85219. 189988
15 WOJ. ŚLĄSKIE                36  1331  34259. 152205
16 WOJ. MAZOWIECKIE            42  3186  84663. 209355

Wiesze zostały posortowane od najmniejszej do największej liczby powiatów w województwach. Odwrotne sortowanie uzyskamy dodając na końcu naszego kodu:

arrange(desc(nr))

Zaprezentowaliśmy Wam na przykładzie jak działają najczęściej używane funkcje z biblioteki dplyr:

  • select – wybór kolumn,
  • filter – wybór wierszy na podstawie wyrażenia,
  • mutate – wyliczenie nowych danych na podstawie istniejących,
  • left_join – łączenie dwóch tabel (jest wiele innych rodzajów),
  • summarise – wyliczanie zestawień z wartości,
  • group_by – grupowanie po wartościach w kolumnie,
  • arrange – sortowanie wierszy po wartościach w kolumnach.

Biblioteka zawiera wiele innych funkcji z którymi musicie zapoznać się sami.