├── .gitignore ├── README.md ├── data ├── england_lsoa_2011.zip ├── hpdata.csv ├── nomis-2011-age-data.zip ├── police-uk-2018-12-merseyside-street.csv ├── pop2011.csv └── sthelens.zip ├── images ├── europe-pop-r.png ├── function.png ├── glossary-p1.png ├── google-r-multiple-maps.png ├── map-example-outputs-1.png ├── map-output.png ├── monmonier-telephones.png ├── plot-2-maps.png ├── readShapeSpatial-deprecated.png ├── rstudio-in-use-selected.png ├── rstudio-in-use.png ├── rstudio-labelled.png ├── script-multiple-map-pdf.png ├── script-single-map-pdf.png ├── script-single-map.png ├── spatial-autocorrelation.png ├── stack-exchange-answer.png └── stack-exchange.png ├── links.htm ├── presentation-intro-r-short.pdf ├── script-examples ├── script-SP-multiple-maps-title.R ├── script-SP-multiple-maps.R ├── script-SP-single-map.R ├── script-crime-rates.R ├── script-multiple-maps-title.R ├── script-multiple-maps.R └── script-single-map.R ├── short-r-course-repo.Rproj ├── software-requirements.txt ├── workbook.Rmd └── workbook.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .Rproj.user 3 | /data-user 4 | /ss 5 | /data/ss 6 | TODO.txt 7 | course-materials/ 8 | README-local.txt 9 | previous-courses.txt 10 | README.html 11 | *.lnk 12 | presentation-intro-r-short.pptx 13 | presentation-intro-r-short-p1.pdf 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to Spatial Data & Using R as a GIS 2 | This is the material for the 1 hour very short version of my course on **Introduction to Spatial Data & Using R as a GIS**. More details on my courses are available at http://www.geospatialtrainingsolutions.co.uk. 3 | 4 | This course does not spend much time on the very basics of using R - if you want to find out more, there are some good tutorials at http://www.social-statistics.org/?p=764 or http://rpubs.com/nickbearman/gettingstartedwithr. 5 | 6 | The material for this workshop is available here: 7 | - [The PDF of the handout with the practical instructions (PDF, 242 KB)](https://github.com/nickbearman/intro-r-spatial-analysis/blob/master/workbook.pdf) 8 | - [Software requirements](https://github.com/nickbearman/intro-r-spatial-analysis/blob/master/software-requirements.txt) 9 | 12 | 15 | 16 | This practical was written using R 3.5.1 (2018-07-02) and RStudio 1.1.463 by Dr. Nick Bearman ([nick@geospatialtrainingsolutions.co.uk](mailto:nick@geospatialtrainingsolutions.co.uk)). 17 | 18 | *This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit [http://creativecommons.org/licenses/by-sa/4.0/deed.en](http://creativecommons.org/licenses/by-sa/4.0/deed.en).* 19 | 20 | Material will be updated periodically, usually in line with courses run by Nick Bearman. 21 | -------------------------------------------------------------------------------- /data/england_lsoa_2011.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/data/england_lsoa_2011.zip -------------------------------------------------------------------------------- /data/hpdata.csv: -------------------------------------------------------------------------------- 1 | "ID","Burglary","Price" 2 | 21,0,200 3 | 24,7,130 4 | 31,0,200 5 | 32,0,200 6 | 78,6,180 7 | 80,19,140 8 | 81,32,65 9 | 98,0,220 10 | 100,0,180 11 | 101,0,200 12 | 102,15,210 13 | 111,6,170 14 | 112,12,180 15 | 113,8,160 16 | 114,7,180 17 | 115,6,130 18 | 116,0,240 19 | 117,0,180 20 | 118,6,170 21 | 119,0,230 22 | 120,7,150 23 | 121,0,200 24 | 122,0,200 25 | 123,0,210 26 | 124,0,220 27 | 125,0,180 28 | 126,0,200 29 | 127,0,210 30 | 128,17,150 31 | 614,0,200 32 | 620,0,230 33 | 621,21,120 34 | 622,7,180 35 | 624,12,180 36 | 625,7,190 37 | 626,36,72 38 | 627,18,80 39 | 628,0,190 40 | 629,0,220 41 | 764,7,150 42 | 765,6,200 43 | 766,0,170 44 | 767,0,170 45 | 768,0,230 46 | 769,0,200 47 | 833,0,160 48 | 834,13,140 49 | 835,22,100 50 | 836,0,140 51 | 837,0,170 52 | 838,0,180 53 | 839,7,260 54 | 840,12,170 55 | 841,7,230 56 | 842,5,190 57 | 843,11,220 58 | 844,0,140 59 | 845,0,220 60 | 846,13,120 61 | 847,13,96 62 | 848,0,210 63 | 849,6,170 64 | 850,15,180 65 | 851,6,140 66 | 852,17,150 67 | 853,37,67 68 | 854,0,200 69 | 855,6,230 70 | 856,6,140 71 | 857,5,230 72 | 858,24,83 73 | 859,0,170 74 | 860,0,200 75 | 861,0,210 76 | 862,0,240 77 | 863,0,180 78 | 864,0,200 79 | 865,0,210 80 | 866,5,250 81 | 867,15,140 82 | 868,0,130 83 | 869,5,190 84 | 870,6,110 85 | 871,0,160 86 | 872,0,150 87 | 873,0,230 88 | 874,13,160 89 | 875,0,210 90 | 876,6,200 91 | 877,0,230 92 | 878,0,210 93 | 879,0,190 94 | 880,23,120 95 | 881,6,180 96 | 882,13,87 97 | 883,15,160 98 | 884,6,190 99 | 885,0,190 100 | 886,0,230 101 | 887,7,180 102 | 888,7,110 103 | 889,0,200 104 | 890,0,250 105 | 891,0,180 106 | 892,0,200 107 | 893,19,130 108 | 894,13,180 109 | 895,0,190 110 | 896,0,190 111 | 897,0,230 112 | 898,6,210 113 | 899,9,210 114 | 900,0,150 115 | 901,0,190 116 | 902,0,210 117 | 903,0,200 118 | 904,0,210 119 | 905,5,170 120 | -------------------------------------------------------------------------------- /data/nomis-2011-age-data.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/data/nomis-2011-age-data.zip -------------------------------------------------------------------------------- /data/sthelens.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/data/sthelens.zip -------------------------------------------------------------------------------- /images/europe-pop-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/europe-pop-r.png -------------------------------------------------------------------------------- /images/function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/function.png -------------------------------------------------------------------------------- /images/glossary-p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/glossary-p1.png -------------------------------------------------------------------------------- /images/google-r-multiple-maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/google-r-multiple-maps.png -------------------------------------------------------------------------------- /images/map-example-outputs-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/map-example-outputs-1.png -------------------------------------------------------------------------------- /images/map-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/map-output.png -------------------------------------------------------------------------------- /images/monmonier-telephones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/monmonier-telephones.png -------------------------------------------------------------------------------- /images/plot-2-maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/plot-2-maps.png -------------------------------------------------------------------------------- /images/readShapeSpatial-deprecated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/readShapeSpatial-deprecated.png -------------------------------------------------------------------------------- /images/rstudio-in-use-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/rstudio-in-use-selected.png -------------------------------------------------------------------------------- /images/rstudio-in-use.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/rstudio-in-use.png -------------------------------------------------------------------------------- /images/rstudio-labelled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/rstudio-labelled.png -------------------------------------------------------------------------------- /images/script-multiple-map-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/script-multiple-map-pdf.png -------------------------------------------------------------------------------- /images/script-single-map-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/script-single-map-pdf.png -------------------------------------------------------------------------------- /images/script-single-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/script-single-map.png -------------------------------------------------------------------------------- /images/spatial-autocorrelation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/spatial-autocorrelation.png -------------------------------------------------------------------------------- /images/stack-exchange-answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/stack-exchange-answer.png -------------------------------------------------------------------------------- /images/stack-exchange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/images/stack-exchange.png -------------------------------------------------------------------------------- /links.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | Best reproducible map competition for GISRUK 2019
4 | Robin's Slides
5 | Attribute operations 6 | 7 | -------------------------------------------------------------------------------- /presentation-intro-r-short.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/presentation-intro-r-short.pdf -------------------------------------------------------------------------------- /script-examples/script-SP-multiple-maps-title.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(maptools) 3 | library(rgdal) 4 | library(classInt) 5 | library(RColorBrewer) 6 | #download csv file 7 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 8 | #unzip csv file 9 | unzip("nomis-2011-age-data.zip") 10 | #read in csv file to pop2011 11 | pop2011 <- read.csv("bulk.csv", header = TRUE) 12 | #create a new variable which contains the new variable names 13 | newcolnames <- c("AllUsualResidentsc","Age00to04","Age05to07", 14 | "Age08to09","Age10to14","Age15","Age16to17", 15 | "Age18to19","Age20to24","Age25to29", 16 | "Age30to44","Age45to59","Age60to64", 17 | "Age65to74","Age75to84","Age85to89", 18 | "Age90andOver","MeanAge","MedianAge") 19 | #apply these to pop2011 data frame 20 | colnames(pop2011)[5:23] <- newcolnames 21 | #download shapefile 22 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 23 | #unzip shapefile 24 | unzip("england_lsoa_2011.zip") 25 | #read in shapefile 26 | LSOA <- readOGR(".", "england_lsoa_2011") 27 | #join attribute data to LSOA 28 | LSOA@data <- merge(pop2011,LSOA@data,by.x="geography.code",by.y="code") 29 | #setup variable with list of maps to print 30 | mapvariables <- c(6,7,8,9) 31 | #loop through for each map 32 | for (i in 1:length(mapvariables)) { 33 | #setup file name 34 | filename <- paste0("map",colnames(LSOA@data)[mapvariables[i]],".pdf") 35 | pdf(file=filename) 36 | #create map 37 | var <- LSOA@data[,mapvariables[i]] 38 | #colours and breaks 39 | breaks <- classIntervals(var, n = 6, style = "fisher") 40 | my_colours <- brewer.pal(6, "Greens") 41 | #plot map 42 | plot(LSOA, col = my_colours[findInterval(var, breaks$brks, all.inside = TRUE)], 43 | axes = FALSE, border = rgb(0.8,0.8,0.8)) 44 | #add legend 45 | legend(x = 330130, y = 385206.5, legend = leglabs(breaks$brks), fill = my_colours, bty = "n") 46 | #add title 47 | #get fieldname and convert to title 48 | fieldname <- colnames(LSOA@data)[mapvariables[i]] 49 | firstyear <- substr(fieldname, 4, 5) 50 | lastyear <- substr(fieldname, 8, 9) 51 | title(paste0("Count of population Aged ", firstyear, " to ", lastyear)) 52 | #Add North Arrow 53 | SpatialPolygonsRescale(layout.north.arrow(2), offset= c(332732,385110), scale = 2000, 54 | plot.grid=F) 55 | #Add Scale Bar 56 | SpatialPolygonsRescale(layout.scale.bar(), offset= c(331030,379600), scale= 5000, 57 | fill= c("white", "black"), plot.grid= F) 58 | #Add text to scale bar 59 | text(331030,379206,"0km", cex=.6) 60 | text(331030 + 2500,379206,"2.5km", cex=.6) 61 | text(331030 + 5000,379206,"5km", cex=.6) 62 | dev.off() 63 | } -------------------------------------------------------------------------------- /script-examples/script-SP-multiple-maps.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(maptools) 3 | library(rgdal) 4 | library(classInt) 5 | library(RColorBrewer) 6 | #download csv file 7 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 8 | #unzip csv file 9 | unzip("nomis-2011-age-data.zip") 10 | #read in csv file to pop2011 11 | pop2011 <- read.csv("bulk.csv", header = TRUE) 12 | #create a new variable which contains the new variable names 13 | newcolnames <- c("AllUsualResidentsc","Age00to04","Age05to07", 14 | "Age08to09","Age10to14","Age15","Age16to17", 15 | "Age18to19","Age20to24","Age25to29", 16 | "Age30to44","Age45to59","Age60to64", 17 | "Age65to74","Age75to84","Age85to89", 18 | "Age90andOver","MeanAge","MedianAge") 19 | #apply these to pop2011 data frame 20 | colnames(pop2011)[5:23] <- newcolnames 21 | #download shapefile 22 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 23 | #unzip shapefile 24 | unzip("england_lsoa_2011.zip") 25 | #read in shapefile 26 | LSOA <- readOGR(".", "england_lsoa_2011") 27 | #join attribute data to LSOA 28 | LSOA@data <- merge(pop2011,LSOA@data,by.x="geography.code",by.y="code") 29 | #setup variable with list of maps to print 30 | mapvariables <- c(6,7,8) 31 | #loop through for each map 32 | for (i in 1:length(mapvariables)) { 33 | #setup file name 34 | filename <- paste0("map",colnames(LSOA@data)[mapvariables[i]],".pdf") 35 | #write out PDF 36 | pdf(file=filename) 37 | #create map 38 | var <- LSOA@data[,mapvariables[i]] 39 | #colours and breaks 40 | breaks <- classIntervals(var, n = 6, style = "fisher") 41 | my_colours <- brewer.pal(6, "Greens") 42 | #plot map 43 | plot(LSOA, col = my_colours[findInterval(var, breaks$brks, all.inside = TRUE)], 44 | axes = FALSE, border = rgb(0.8,0.8,0.8)) 45 | #add legend 46 | legend(x = 330130, y = 385206.5, legend = leglabs(breaks$brks), fill = my_colours, bty = "n") 47 | #add title 48 | title(colnames(LSOA@data)[mapvariables[i]]) 49 | #add north arrow 50 | SpatialPolygonsRescale(layout.north.arrow(2), offset= c(332732,385110), scale = 2000, 51 | plot.grid=F) 52 | #add scale bar 53 | SpatialPolygonsRescale(layout.scale.bar(), offset= c(331030,379600), scale= 5000, 54 | fill= c("white", "black"), plot.grid= F) 55 | #add text to scale bar 56 | text(331030,379206,"0km", cex=.6) 57 | text(331030 + 2500,379206,"2.5km", cex=.6) 58 | text(331030 + 5000,379206,"5km", cex=.6) 59 | #stop PDF output 60 | dev.off() 61 | } 62 | -------------------------------------------------------------------------------- /script-examples/script-SP-single-map.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(maptools) 3 | library(rgdal) 4 | library(classInt) 5 | library(RColorBrewer) 6 | #download csv file 7 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 8 | #unzip csv file 9 | unzip("nomis-2011-age-data.zip") 10 | #read in csv file to pop2011 11 | pop2011 <- read.csv("bulk.csv", header = TRUE) 12 | #create a new variable which contains the new variable names 13 | newcolnames <- c("AllUsualResidentsc","Age00to04","Age05to07", 14 | "Age08to09","Age10to14","Age15","Age16to17", 15 | "Age18to19","Age20to24","Age25to29", 16 | "Age30to44","Age45to59","Age60to64", 17 | "Age65to74","Age75to84","Age85to89", 18 | "Age90andOver","MeanAge","MedianAge") 19 | #apply these to pop2011 data frame 20 | colnames(pop2011)[5:23] <- newcolnames 21 | #download shapefile 22 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 23 | #unzip shapefile 24 | unzip("england_lsoa_2011.zip") 25 | #read in shapefile 26 | LSOA <- readOGR(".", "england_lsoa_2011") 27 | #join attribute data to LSOA 28 | LSOA@data <- merge(pop2011,LSOA@data,by.x="geography.code",by.y="code") 29 | #select variable 30 | var <- LSOA@data[,"Age00to04"] 31 | #set colours & breaks 32 | breaks <- classIntervals(var, n = 6, style = "fisher") 33 | my_colours <- brewer.pal(6, "Greens") 34 | #plot map 35 | plot(LSOA, col = my_colours[findInterval(var, breaks$brks, all.inside = TRUE)], axes = FALSE, 36 | border = rgb(0.8,0.8,0.8)) 37 | #draw legend 38 | legend(x = 328130, y = 386506.5, legend = leglabs(breaks$brks), fill = my_colours, bty = "n") 39 | -------------------------------------------------------------------------------- /script-examples/script-crime-rates.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(sf) 3 | library(tmap) 4 | 5 | #Read the data into a variable called crimes 6 | crimes <- read.csv("http://nickbearman.me.uk/data/r/police-uk-2018-12-merseyside-street.csv") 7 | #create crimes data 8 | crimes_sf <- st_as_sf(crimes, coords = c('Longitude', 'Latitude'), crs = "+init=epsg:4326") 9 | #qtm 10 | qtm(crimes_sf) 11 | #reproject to British National Grid, from Latitude/Longitude 12 | crimes_sf_bng <- st_transform(crimes_sf, crs = "+init=epsg:27700") 13 | #plot map 14 | tm_shape(crimes_sf_bng) + 15 | tm_dots(size = 0.1, shape = 19, col = "darkred", alpha = 0.5) 16 | #table of crime types 17 | table(crimes_sf_bng$Crime.type) 18 | 19 | #Point in Polygon 20 | #plot the crime data 21 | tm_shape(crimes_sf_bng) + 22 | tm_dots(size = 0.1, shape = 19, col = "red", alpha = 0.5)+ 23 | #add LSOA on top 24 | tm_shape(LSOA) + 25 | tm_borders() 26 | 27 | #load libraries 28 | library(rgdal) #for readOGR() 29 | library(GISTools) #for poly.counts() 30 | #read shape file in in SP format 31 | LSOA_sp <- readOGR(".", "england_lsoa_2011") 32 | #convert crimes SF to sp 33 | #(see https://cran.r-project.org/web/packages/sf/vignettes/sf2.html# 34 | # conversion_to_other_formats:_wkt,_wkb,_sp for details) 35 | crimes_sp_bng <- as(crimes_sf_bng, "Spatial") 36 | #calculate the number of crimes in each LSOA 37 | crimes.count <- poly.counts(crimes_sp_bng, LSOA_sp) 38 | #add this as a new field to our LSOA data 39 | LSOA_sp@data$crimes.count <- crimes.count 40 | #show the first 6 rows (exactly the same as head(LSOA_sp) but for SP data) 41 | head(LSOA_sp@data) 42 | 43 | #tmap of crime count 44 | tm_shape(crimes_sf_bng) + 45 | tm_dots(size = 0.1, shape = 19, col = "red", alpha = 0.5) + 46 | #add LSOA on top 47 | tm_shape(LSOA_sp) + 48 | tm_borders() 49 | 50 | #Calc Crime Rate 51 | #join pop data 52 | #download csv file 53 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 54 | #unzip csv file 55 | unzip("nomis-2011-age-data.zip") 56 | #read in csv file to pop2011 57 | pop2011 <- read.csv("bulk.csv", header = TRUE) 58 | #create a new variable which contains the new variable names 59 | newcolnames <- c("AllUsualResidents","Age00to04","Age05to07", 60 | "Age08to09","Age10to14","Age15","Age16to17", 61 | "Age18to19","Age20to24","Age25to29", 62 | "Age30to44","Age45to59","Age60to64", 63 | "Age65to74","Age75to84","Age85to89", 64 | "Age90andOver","MeanAge","MedianAge") 65 | #apply these to pop2011 data frame 66 | colnames(pop2011)[5:23] <- newcolnames 67 | #read in shapefile 68 | LSOA <- st_read("england_lsoa_2011.shp") 69 | #join attribute data to LSOA 70 | LSOA <- merge(LSOA,pop2011,by.x="code",by.y="geography.code") 71 | #check data 72 | head(LSOA) 73 | #add crime count 74 | LSOA$crimes.count <- crimes.count 75 | #check data 76 | head(LSOA) 77 | #calculate crime rate 78 | LSOA$crime.rate <- (LSOA$crimes.count / LSOA$AllUsualResidents) * 10000 79 | #check 80 | head(LSOA) 81 | #map 82 | qtm(LSOA, fill="crime.rate") 83 | 84 | #tmap of crime count 85 | tm_shape(crimes_sf_bng) + 86 | tm_dots(size = 0.1, shape = 19, col = "red", alpha = 0.5) + 87 | #add LSOA on top 88 | tm_shape(LSOA_sp) + 89 | tm_borders() 90 | 91 | #tmap of crime rate 92 | tm_shape(LSOA) + 93 | tm_polygons("crime.rate", title = "Crime rate per 10,000 pop", palette = "Greens", style = "jenks") + 94 | tm_layout(legend.title.size = 0.8) 95 | 96 | #tmap of crime rate & crime points 97 | tm_shape(LSOA) + 98 | tm_polygons("crime.rate", title = "Crime rate per 10,000 pop", palette = "Greens", style = "jenks") + 99 | tm_layout(legend.title.size = 0.8) + 100 | #add crime points 101 | tm_shape(crimes_sf_bng) + 102 | tm_dots(size = 0.1, shape = 19, col = "red", alpha = 0.5) 103 | -------------------------------------------------------------------------------- /script-examples/script-multiple-maps-title.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(sf) 3 | library(tmap) 4 | #download csv file 5 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 6 | #unzip csv file 7 | unzip("nomis-2011-age-data.zip") 8 | #read in csv file to pop2011 9 | pop2011 <- read.csv("bulk.csv", header = TRUE) 10 | #create a new variable which contains the new variable names 11 | newcolnames <- c("AllUsualResidents","Age00to04","Age05to07", 12 | "Age08to09","Age10to14","Age15","Age16to17", 13 | "Age18to19","Age20to24","Age25to29", 14 | "Age30to44","Age45to59","Age60to64", 15 | "Age65to74","Age75to84","Age85to89", 16 | "Age90andOver","MeanAge","MedianAge") 17 | #apply these to pop2011 data frame 18 | colnames(pop2011)[5:23] <- newcolnames 19 | #download shapefile 20 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 21 | #unzip shapefile 22 | unzip("england_lsoa_2011.zip") 23 | #read in shapefile 24 | LSOA <- st_read("england_lsoa_2011.shp") 25 | #join attribute data to LSOA 26 | LSOA <- merge(LSOA,pop2011,by.x="code",by.y="geography.code") 27 | #multiple map s 28 | #set which varaibles will be mapped 29 | mapvariables <- c("AllUsualResidents", "Age00to04", "Age05to07") 30 | #set titles 31 | maptitles <- c("All Residents", "Age 0 to 4", "Age 5 to 7") 32 | 33 | #loop through for each map 34 | for (i in 1:length(mapvariables)) { 35 | #setup map 36 | m <- tm_shape(LSOA) + 37 | #set variable, colours and classes 38 | tm_polygons(mapvariables[i], palette = "Greens", style = "equal") + 39 | #set scale bar 40 | tm_scale_bar(width = 0.22, position = c(0.05, 0.19)) + 41 | #set compass 42 | tm_compass(position = c(0.3, 0.08)) + 43 | #set layout 44 | tm_layout(frame = F, title = maptitles[i], title.size = 1.25, 45 | title.position = c(0.65, "top")) 46 | #save map 47 | tmap_save(m, filename = paste0("map-",mapvariables[i],".png")) 48 | #end loop 49 | } 50 | -------------------------------------------------------------------------------- /script-examples/script-multiple-maps.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(sf) 3 | library(tmap) 4 | #download csv file 5 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 6 | #unzip csv file 7 | unzip("nomis-2011-age-data.zip") 8 | #read in csv file to pop2011 9 | pop2011 <- read.csv("bulk.csv", header = TRUE) 10 | #create a new variable which contains the new variable names 11 | newcolnames <- c("AllUsualResidents","Age00to04","Age05to07", 12 | "Age08to09","Age10to14","Age15","Age16to17", 13 | "Age18to19","Age20to24","Age25to29", 14 | "Age30to44","Age45to59","Age60to64", 15 | "Age65to74","Age75to84","Age85to89", 16 | "Age90andOver","MeanAge","MedianAge") 17 | #apply these to pop2011 data frame 18 | colnames(pop2011)[5:23] <- newcolnames 19 | #download shapefile 20 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 21 | #unzip shapefile 22 | unzip("england_lsoa_2011.zip") 23 | #read in shapefile 24 | LSOA <- st_read("england_lsoa_2011.shp") 25 | #join attribute data to LSOA 26 | LSOA <- merge(LSOA,pop2011,by.x="code",by.y="geography.code") 27 | #multiple map s 28 | #set which varaibles will be mapped 29 | mapvariables <- c("AllUsualResidents", "Age00to04", "Age05to07") 30 | 31 | #loop through for each map 32 | for (i in 1:length(mapvariables)) { 33 | #setup map 34 | m <- tm_shape(LSOA) + 35 | #set variable, colours and classes 36 | tm_polygons(mapvariables[i], palette = "Greens", style = "equal") + 37 | #set scale bar 38 | tm_scale_bar(width = 0.22, position = c(0.05, 0.19)) + 39 | #set compass 40 | tm_compass(position = c(0.3, 0.08)) + 41 | #set layout 42 | tm_layout(frame = F, title = "Liverpool", title.size = 2, 43 | title.position = c(0.65, "top")) 44 | #save map 45 | tmap_save(m, filename = paste0("map-",mapvariables[i],".png")) 46 | #end loop 47 | } 48 | -------------------------------------------------------------------------------- /script-examples/script-single-map.R: -------------------------------------------------------------------------------- 1 | #load libraries 2 | library(sf) 3 | library(tmap) 4 | #download csv file 5 | download.file("http://www.nickbearman.me.uk/data/r/nomis-2011-age-data.zip","nomis-2011-age-data.zip") 6 | #unzip csv file 7 | unzip("nomis-2011-age-data.zip") 8 | #read in csv file to pop2011 9 | pop2011 <- read.csv("bulk.csv", header = TRUE) 10 | #create a new variable which contains the new variable names 11 | newcolnames <- c("AllUsualResidents","Age00to04","Age05to07", 12 | "Age08to09","Age10to14","Age15","Age16to17", 13 | "Age18to19","Age20to24","Age25to29", 14 | "Age30to44","Age45to59","Age60to64", 15 | "Age65to74","Age75to84","Age85to89", 16 | "Age90andOver","MeanAge","MedianAge") 17 | #apply these to pop2011 data frame 18 | colnames(pop2011)[5:23] <- newcolnames 19 | #download shapefile 20 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 21 | #unzip shapefile 22 | unzip("england_lsoa_2011.zip") 23 | #read in shapefile 24 | LSOA <- st_read("england_lsoa_2011.shp") 25 | #join attribute data to LSOA 26 | LSOA <- merge(LSOA,pop2011,by.x="code",by.y="geography.code") 27 | #map 28 | tm_shape(LSOA) + 29 | tm_polygons("Age00to04", title = "Aged 0 to 4", palette = "Greens", style = "jenks") + 30 | tm_layout(legend.title.size = 0.8) 31 | -------------------------------------------------------------------------------- /short-r-course-repo.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /software-requirements.txt: -------------------------------------------------------------------------------- 1 | software-requirements 2 | 3 | R (3.5 or above) 4 | RStudio (1.1.456 or above) 5 | 6 | Libraries: 7 | sf 8 | tmap 9 | -------------------------------------------------------------------------------- /workbook.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to Spatial Data & Using R as a GIS" 3 | output: pdf_document 4 | author: "Nick Bearman - Geospatial Training Solutions & Robin Lovelace - University of Leeds" 5 | --- 6 | 7 | ```{r setup, echo=FALSE} 8 | #set working directory to /data-user 9 | knitr::opts_knit$set(root.dir = 'C:/Users/nick/Dropbox/Work/course-repos/03-intro-r-spatial-analysis/data-user') 10 | ``` 11 | 12 | 25 | 26 | 27 | 28 | 29 | 30 | ## R Basics 31 | 32 | R began as a statistics program and is still used as one by many users. We are going to use a program called [RStudio](http://www.rstudio.com/ "R Studio website"), which works on top of R and provides a good user interface. 33 | 34 | - Open up RStudio (click **Start** and type in `RStudio` or double-click the icon on the desktop). 35 | 36 | R can initially be used as a calculator - enter the following into the left-hand side of the window - the section labelled **Console**: 37 | 38 | ```{r,eval=FALSE} 39 | 6 + 8 40 | ``` 41 | 42 | R stores data in a data frame, which is a key type of variable in R. We can read some data in from the internet. 43 | 44 | 45 | 46 | 47 | ```{r getdata} 48 | pop2011 <- read.csv("http://nickbearman.me.uk/data/r/pop2011.csv") 49 | ``` 50 | 51 | When we read in data, it is always a good idea to check it came in ok. To do this, we can preview the data set. The `head` command shows the first 6 rows of the data. 52 | 53 | ```{r, comment=NA, eval=FALSE} 54 | head(pop2011) 55 | ``` 56 | 57 | You can also click on the variable listed in the Environment window, which will show the data in a new tab. You can also enter: 58 | 59 | ```{r, comment=NA} 60 | View(pop2011) 61 | ``` 62 | to open a new tab showing the data. 63 | 64 | We can use square brackets to look at specific sections of the data frame, for example `pop2011[1,]` or `pop2011[,1]`. We can also delete columns and create new columns using the code below. 65 | 66 | ```{r, eval=FALSE} 67 | #create a new column in pop2011 dataframe call avgincome, storing the value NA 68 | pop2011$avgincome <- NA 69 | #see what has happened 70 | head(pop2011) 71 | 72 | #delete a column 73 | pop2011$avgincome <- NULL 74 | #see what has happened 75 | head(pop2011) 76 | 77 | #rename a column 78 | colnames(pop2011)[1] <- "year" 79 | #see what has happened 80 | head(pop2011) 81 | ``` 82 | 83 | ## Geographical Information 84 | 85 | R has developed into a GIS as a result of user contributed packages, or libraries, as R refers to them. To work with spatial data, we need to load some new *libraries*. 86 | 87 | ```{r,message=FALSE,display=FALSE, warning = FALSE} 88 | library(sf) 89 | library(tmap) 90 | ``` 91 | 92 | If you get an error message, you may need to install these libaries. Run `install.packages("sf")` for the `sf` library. 93 | 94 | This makes R *able* to handle geographical data, it doesn't actually load any specific data sets. To do this, we need to read in some data. We are going to use **shapefiles**. 95 | 96 | 97 | 98 | R uses working folders to store information relevant to the current project you are working on. I suggest you make a folder called **R work** somewhere sensible. Then we need to tell R where this is, so click **Session > Set Working Directory > Choose Directory...** and select the folder that you created. 99 | 100 | If you are using RStudio Server, then your working directory is on the server, so you don't need to do anything! 101 | 102 | 103 | ```{r setwd, include=FALSE} 104 | setwd("C:/Users/nick/Dropbox/Work/course-repos/03-intro-r-spatial-analysis/data-user") 105 | ``` 106 | 107 | There is a set of shapefiles for Liverpool in a zip file. You can download, extract and load in these files: 108 | 109 | 110 | ```{r, comment=NA} 111 | download.file("http://www.nickbearman.me.uk/data/r/england_lsoa_2011.zip","england_lsoa_2011.zip") 112 | unzip("england_lsoa_2011.zip") 113 | 114 | ``` 115 | 116 | ```{r, comment=NA, message=FALSE, results='hide'} 117 | LSOA <- st_read("england_lsoa_2011.shp") 118 | ``` 119 | 120 | The `st_read` function does this and stores them as a Simple Features (or `sf`) object. You can use the `plot` function to draw the polygons (i.e. the map of the LSOA). 121 | 122 | ```{r, comment=NA, eval=FALSE} 123 | plot(LSOA$geometry) 124 | ``` 125 | 126 | We can also use the `head()` command to show the first six rows, exactly the same as with a data frame. 127 | 128 | ```{r, comment=NA, eval=FALSE} 129 | head(LSOA) 130 | ``` 131 | 132 | *This is the same as the attribute table in programs like ArcGIS, QGIS or MapInfo. If you want to open the shapefile in QGIS or ArcGIS to have a look, feel free to.* 133 | 134 | You can see there is a lot of information there, including the geometry. The useful bit for us is the `code` field, as this matched the `code` field in the `pop2011` file. We can use this to join the two data sets together. 135 | 136 | ```{r, comment=NA} 137 | LSOA <- merge(LSOA, pop2011, by.x="code", by.y="code") 138 | ``` 139 | 140 | And use the `head` function to check the data have been joined correctly. 141 | 142 | ```{r,comment=NA, eval=FALSE} 143 | head(LSOA) 144 | ``` 145 | 146 | Now that we have joined the data together, we can draw a choropleth map of these data. 147 | 148 | ```{r echo=TRUE, eval=FALSE} 149 | tm_shape(LSOA) + 150 | tm_polygons("Age00to04") 151 | ``` 152 | 153 | ```{r echo=TRUE, eval=FALSE} 154 | tm_shape(LSOA) + 155 | tm_polygons("Age00to04", title = "Aged 0 to 4", palette = "Greens", style = "jenks") + 156 | tm_layout(legend.title.size = 0.8) 157 | ``` 158 | 159 | 160 | 161 | This is a very quick way of getting a map out of R. To use the map, click on the **Export** button, and then choose **Copy to Clipboard...**. Then choose Copy Plot. If you also have Word up and running, you can then paste the map into your document. You can also save the map as an Image or PDF. 162 | 163 | Working with R often requires several lines of code to get an output. Rather than typing code into the **Console**, we can use a **script** instead. This allows us to go back and edit the code very easily, to correct mistakes! 164 | 165 | Create a new script (**File > New File > R Script**) and enter the code in there. Then you can select the lines you want to run by highlighting them, and then pressing `Ctrl+Enter`, or using the **Run** button. 166 | 167 | We can change the `fill` parameter to show different data sets. Try using it to show data from the different age catagories in the attribute table. 168 | 169 | This allows us to change the title, colours and legend title size. Try substituting in `Blues` and adjusting the title. 170 | 171 | ## Colours and Categories 172 | 173 | We can choose lots of different colours from ColorBrewer, and different classification methods as well. To show all of the different colour palettes we could use, run this code: 174 | 175 | ```{r echo=TRUE, eval=FALSE} 176 | library(RColorBrewer) 177 | display.brewer.all() 178 | ``` 179 | 180 | We can also choose which classification method to use and how many classes. We can set `n = 6` to set the number of classes 181 | 182 | ```{r echo=TRUE, eval=FALSE} 183 | tm_shape(LSOA) + 184 | tm_polygons("Age00to04", title = "Aged 0 to 4", palette = "Greens", n = 6, style = "jenks") 185 | ``` 186 | 187 | ## Histograms (optional exercise) 188 | 189 | We can also add a histogram of the data to the map: 190 | 191 | ```{r,eval=FALSE} 192 | tm_shape(LSOA) + 193 | tm_polygons("AllUsualResidents", title = "All Usual Residents", palette = "Greens", 194 | style = "equal", legend.hist = T) 195 | ``` 196 | 197 | ## Scale Bar and North Arrow (optional exercise) 198 | 199 | It is also good practice to add a scale bar and a north arrow to each of the maps you produce. Running this code will add these to the map: 200 | 201 | ```{r, eval=FALSE} 202 | tm_shape(LSOA) + 203 | #Set colours and classification methods 204 | tm_polygons("AllUsualResidents", title = "All Usual Residents", palette = "Greens", 205 | style = "equal") + 206 | #Add scale bar 207 | tm_scale_bar(width = 0.22, position = c(0.05, 0.18)) + 208 | #Add compass 209 | tm_compass(position = c(0.3, 0.07)) + 210 | #Set layout details 211 | tm_layout(frame = F, title = "Liverpool", title.size = 2, 212 | title.position = c(0.7, "top")) 213 | ``` 214 | 215 | You may well need to adjust the position of the items on the map. Try Googling `"tm_scale_bar position"` for information on how to do this. 216 | 217 | Remember that any line starting with a `#` is a comment, and will be ignored by R. Comments are very useful for us to note what the code is doing, particularly when you come back to it 6 months later and can't remember what it is supposed to do! 218 | 219 | ## Exporting and Creating Multiple Maps 220 | 221 | We can automatically save the map as a file by creating the map object as a new variable (`m`) and then save it using `tmap_save(m)`. 222 | 223 | ```{r, comment=NA, eval=FALSE} 224 | #create map 225 | m <- tm_shape(LSOA) + 226 | tm_polygons("AllUsualResidents", title = "All Usual Residents", palette = "Greens", 227 | style = "equal") + 228 | tm_layout(frame = F, title = "Liverpool", title.size = 2, 229 | title.position = c(0.7, "top")) 230 | #save map 231 | tmap_save(m) 232 | ``` 233 | 234 | Saving the map using code allows us to create multiple maps very easily. A variable (`mapvariables`) is used to list which variables should be mapped, and then the line starting `for` starts a loop. Try running the code, and then change the variables it maps. 235 | 236 | 237 | ```{r message=FALSE, comment=NA} 238 | #set which variables will be mapped 239 | mapvariables <- c("AllUsualResidents", "Age00to04", "Age05to07") 240 | 241 | #loop through for each map 242 | for (i in 1:length(mapvariables)) { 243 | #setup map 244 | m <- tm_shape(LSOA) + 245 | #set variable, colours and classes 246 | tm_polygons(mapvariables[i], palette = "Greens", style = "equal") + 247 | #set layout 248 | tm_layout(frame = F, title = "Liverpool", title.size = 2, 249 | title.position = c(0.7, "top")) 250 | #save map 251 | tmap_save(m, filename = paste0("map-",mapvariables[i],".png")) 252 | #end loop 253 | } 254 | ``` 255 | 256 | You can replace `.png` with `.jpg` or `.pdf` for different file formats. 257 | 258 | ## Exporting Shapefiles 259 | 260 | We used `st_read` to read in a shape file, and we can use `st_write` to export a shape file: 261 | 262 | ```{r eval=FALSE} 263 | st_write(LSOA, "LSOA-population.shp") 264 | ``` 265 | 266 | 267 | ---- 268 | 269 | This practical was written using R 3.5.1 (2018-07-02) and RStudio 1.1.463 by Dr. Nick Bearman (nick@geospatialtrainingsolutions.co.uk). 270 | 271 | This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/deed.en. The latest version of the PDF is available from https://github.com/nickbearman/intro-r-spatial-analysis-short. This version was created on `r format(Sys.time(), '%d %B %Y')`. 272 | 273 | -------------------------------------------------------------------------------- /workbook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickbearman/intro-r-spatial-analysis-short/5269cec20e0f523a06c872fbcc6208e39b3172aa/workbook.pdf --------------------------------------------------------------------------------