Before maptools and rgdal were deprecated, I used this code to import a shapefile, centroids csv and commuting count data, to create a flow map using the code below (I removed the ggplot code for legibility). I am trying to recreate this flow map with recent commuting data to compare changes between both time periods.
I read that read_sf/st_read was used to replace the readOGR function, so I used st_read to import the shapefile.
To join the shapefile to the centroid points, I need to get the polygon ID which is the common field for this join. However, the line soton@data$id = rownames(soton@data)
which I'm using to get the polygon IDs that are stored as row names is throwing this error:
Error in soton@data : no applicable method for
@
applied to an object of class "sf"
This code worked fine with maptools and rgdal, and I am using the exact same shapefile from before. I'll really appreciate help on tweaking my code to work with the new packages. Thank you.
library(tidyverse)
library(plyr)
library(ggplot2)
library(maptools) -- replaced with library(sf)
library(rgdal) -- removed this and loaded sp package
setwd("your working directory")
soton=st_read(dsn="SouthamptonMSOA",layer="SouthamptonOA")
ODmat=read.csv("ODSouthampton.csv")
centroids=read.csv("CentroidSouthampton.csv")
popdat=read.csv("SouthamptonWZ.csv")
ODmat$frx=0
ODmat$fry=0
ODmat$tox=0
ODmat$toy=0
for (i in 1:dim(ODmat)[1]){
ODmat$frx[i]=centroids$East[which(centroids$Code==ODmat$Origin[i])]
ODmat$fry[i]=centroids$North[which(centroids$Code==ODmat$Origin[i])]
ODmat$tox[i]=centroids$East[which(centroids$Code==ODmat$Destination[i])]
ODmat$toy[i]=centroids$North[which(centroids$Code==ODmat$Destination[i])]}
soton@data$id = rownames(soton@data)
soton.points = fortify(soton, region="id")
soton.df = join(soton.points, soton@data, by="id")
ODmatsub=subset(ODmat,Commuters>50)
figplot = ggplot()+
# ...
UPDATE: In the comments, it was suggested that I convert the centroids data to an sf object before joining to the shapefile. I have done this but now stuck on how to join the shapefile to the centroids data, bearing in mind that I also have to join the origin-destination data (ODSouthampton) to the centroids to create the flow lines.
Here's a sample of the centroids data(csv):
Code | Name | East | North |
---|---|---|---|
E02003549 | Southampton 001 | 442184.28 | 116144.73 |
E02003550 | Southampton 002 | 439810.63 | 116092.19 |
E02003551 | Southampton 003 | 443938.17 | 115842.76 |
E02003552 | Southampton 004 | 439018.21 | 115633.94 |
E02003553 | Southampton 005 | 443248.97 | 115497.68 |
Sample of the ODSouthampton data (csv):
Origin | Destination | Commuters |
---|---|---|
E02003549 | E02003549 | 22 |
E02003549 | E02003550 | 25 |
E02003549 | E02003551 | 13 |
E02003549 | E02003552 | 12 |
E02003549 | E02003553 | 24 |
I also have workplace population data which I will display as points on the map, and it's in a csv format. Will I need to convert all 3 csv files to sf objects? Sample of the population data is below:
MSOA_Code | WZ_Population | POINT_X | POINT_Y |
---|---|---|---|
E02003549 | 2149 | 442184.28 | 116144.73 |
E02003550 | 3227 | 439810.63 | 116092.19 |
E02003551 | 1998 | 443938.17 | 115842.76 |
E02003552 | 1596 | 439018.21 | 115633.94 |
E02003553 | 1772 | 443248.97 | 115497.68 |
csv
file contains centroid coordinates, read it as data.frame and convert tosf
object withsf::st_as_sf(data.frame.from.csv, coords = ("lon", "lat"), crs = ...)
and usesf::st_join(your_shape_data, your_centroids_data)
to join them. – Elinorelinorecentroids=sf::st_as_sf(data.frame.CentroidSouthampton.csv, coords = ("East", "North"), crs = OSGB 1936 / British National Grid)
This is throwing an "unexpected" error. Could you help correct my code? I assumed I was to change lon and lat to the column names for the coordinates in the centroid csv. Thank you so much for your help. – Dobysoton@data$id = rownames(soton@data)
which is the code to get the row names for the polygon IDs in the shapefile. Is there a way that works to get the row names? – Dobycrs =
an EPSG code, not the PCS name. Trycrs = 27700
. And if you supply some sample rows of you csv files, I'm happy to show you the entire workflow without needing a loop. – Owletcentroids=sf::st_as_sf(data.frame.CentroidSouthampton.csv, coords = ("East", "North"), crs = 27700)
– Dobycoords = c("East", "North"),
. – Owlet