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:
1 |
library(dplyr) |
Let’s load the data:
1 |
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:
1 |
dt %›% filter(nchar(TERYT) == 5) |
As a result we have:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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:
1 2 |
dt %›% filter(nchar(TERYT) == 5) %›% mutate(TERYT_woj = substr(TERYT,0,2)) |
As a result we have:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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:
1 |
dt %›% select(TERYT,'Nazwa jednostki') |
And we have:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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:
1 2 3 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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:
1 2 3 4 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 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:
1 |
dt %›% summarise(min = min(Pow), avg = mean(Pow), max = max(Pow)) |
1 2 3 4 |
# 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:
1 2 |
dt %›% group_by(Woj) %›% summarise(min = min(Pow), avg = mean(Pow), max = max(Pow)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 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:
1 2 |
dt %›% group_by(Woj) %›% summarise(nr = length(Pow), min = min(Pow), avg = mean(Pow), max = max(Pow)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 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:
1 2 3 |
dt %›% group_by(Woj) %›% summarise(nr = length(Pow), min = min(Pow), avg = mean(Pow), max = max(Pow)) %›% arrange(nr) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 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:
1 |
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.