Dplyr – manipulation of data frame
In this post, we will introduce the library dplyr, which allows you to easily manipulate variables of type data frame. For our example, we will use the list of geodetic surface fields that you can download as part of open data here.
Let’s initialize the library:
library(dplyr)
Let’s load the data:
dt = readr::read_csv("d:/GIS_in_R/powierzchnie.csv")
First we will use the filter function, which allows us to select rows that meet a certain criterion. In our case, these will be districts for which TERYT has 5 characters:
dt %›% filter(nchar(TERYT) == 5)
As a result we have:
# A tibble: 380 x 3
TERYT `Nazwa jednostki` `Powierzchnia [ha]`
‹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
Let’s add the mutate function to our previous line of code, which will allow us to compute a new value (column). We will determine the TERYT of the county from the TERYT of the province (TERYT_woj) using the substr function:
dt %›% filter(nchar(TERYT) == 5) %›%
mutate(TERYT_woj = substr(TERYT,0,2))
As a result we have:
# A tibble: 380 x 4
TERYT `Nazwa jednostki` `Powierzchnia [ha]` 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
We use the select function to select the columns we are interested in:
dt %›% select(TERYT,'Nazwa jednostki')
And we have:
# 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
We will use the select we did earlier to add the names of the provinces to our counties, using left_join from the join function group:
dt %›% filter(nchar(TERYT) == 5) %›%
mutate(TERYT_woj = substr(TERYT,0,2)) %›%
left_join(dt %›% select(TERYT,'Nazwa jednostki'), by = c("TERYT_woj" = "TERYT"))
The finished table looks like this:
# A tibble: 380 x 5
TERYT `Nazwa jednostki.x` `Powierzchnia [ha]` 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
Finally, in our long code, we select only the columns of interest in the resulting table (TERYT, unit name, area, and province name). We will give them new names (TERYT, Nazwa, Pow, Woj). The result will be stored in the variable 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 [ha]`,Woj = `Nazwa jednostki.y`)
The variable dt should contain this data:
# 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
For the created table we will calculate the minimum, average and maximum area of the districts using the summarize function:
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
If we want to calculate these values for provinces, our row should be completed with the function 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
Let’s add the number of districts:
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
And finally, we sort our results by the number of districts with the arrange function:
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
The rows are sorted from the smallest to the largest number of districts in the provinces. Reverse sorting is achieved by adding at the end of our code:
arrange(desc(nr))
We have shown you how the most commonly used functions from the dplyr library work:
- select – select columns,
- filter – select rows based on an expression,
- mutate – calculate new data based on existing,
- left_join – join two tables (there are many types of join),
- summarise -create summaries from values,
- group_by – group by the values in a column,
- arrange – sort rows by values in columns.
The library contains many other functions that you need to check yourself.