Error while producing choropleth map with maptoools - r

Hello, I am new to GIS with R and have been trying to create a choropleth map. I successfully created a choropleth map with ggplot2 and the fortify function, but it is not that easy to add more layers on the top of a map with ggplot2. Instead I am using maptools to plot a choropleth map and later add more layers as needed for my analysis.
The choropleth map I am trying to plot is the level of unemployment for Allegheny county by census tract. the files are available here:
shapefile https://www.dropbox.com/s/uci5g2ekeq9niww/census%20tract%20allegheyny%202010.shp
csv file https://www.dropbox.com/s/6nq8nnxftot8iya/allegheyny%20socioeconomic%20info.csv
And here is my code
library(rgdal)
library(RArcInfo)
library(RColorBrewer)
library(maptools)
library(maps)
library(classInt)
we load the csv file, clean it and create a subset with Id2 and unemployment
data<- read.csv('allegheyny socioeconomic info.csv',dec='.',
header=T)
data$Id2<-as.numeric(as.character(data$Id2))
data$Percent.Unemployed<-as.numeric(as.character(data$Percent.Unemployed))
names(data)[names(data)=="Percent.Unemployed"]<-'unemployed'
data1<-subset(data, select= c('Id2', 'unemployed'))
load shapefile of Allegheny County census tracts for 2010
tracts<-readShapePoly("census tract allegheyny 2010.shp")
names(tracts)[names(tracts)=="GEOID10"]<-'Id2'
merge the data by Id2
tr1<-merge(data1,tracts)
sort(tr1$Id2)
colours<-brewer.pal(5, 'Greens')
breaks<- classIntervals(tr1$unemployed, n=5, style='sd')
plot(tr1, col=colours[findInterval(tr1$unemployed, breaks, all.inside=T), axes=F])
And this is the message I get:
Error in x[-1L] >= x[-n] : comparison of these types is not implemented

plot(tracts,col=colours[findInterval(tr1$unemployed, breaks$brks, all.inside=T)])
Produces this:
To answer your question specifically:
The reason for the error is that findInteerval(...) takes as its second argument a vector of numeric. But
breaks<- classIntervals(tr1$unemployed, n=5, style='sd')
produces a list with two elements: 'var' and 'brks'. You need to use breaks$brks in findInterval(...).
Your statement
plot(tr1, col=colours[findInterval(tr1$unemployed, breaks, all.inside=T), axes=F])
attempts to plot tr1, which is not a map, it's a data frame with 402 rows. You need to plot(tracts,...)
Finally, why do you believe it is difficult to add layers in ggplot??

Related

Mapping with shapefiles in R

I have a shapefile with tons of different polygons representing different bodies of water (lakes, rivers etc.)
I would like to create a map of certain polygons. All of the current examples I could find only show how to plot shapefiles with ONLY the polygons wanted in them. So I am not sure how to only plot the specific polygons.
Link to the shapefile: https://hub.arcgis.com/datasets/esri::usa-detailed-water-bodies/explore?location=45.461044%2C-84.374110%2C10.71
I would like to plot OBJECTID295061, 295018, and 295017
Current code:
library(sf)
shp = st_read("USA_Detailed_Water_Bodies.shp")
ggplot(data = shp) +
geom_sf()+
coord_sf()+
theme_bw()
Current map:
Assuming OBJECTID is a numeric column of your data:
library(sf)
shp = st_read("USA_Detailed_Water_Bodies.shp")
Then you can make an "area of interest" subset like this:
aoi = shp[shp$OBJECTID %in% c(295061, 295018, 295017),]
Then make your plot using aoi.
If the OBJECTID numbers are the same as the row numbers you can select by row:
aoi = shp[c(295061, 295018, 295017),]
but I'm not sure because no time for a 250Mb download right now but I think this is correct.
Spatial dataframes from sf behave mostly like regular data frames, with a few weird exceptions. But for selecting rows and columns its not very different.

Global cartogram in R

I am trying to create a global cartogram using the cartogram package in R. I am trying to use the data from wrld_simpl. What I expect is a cartogram in which the Population ("Pop2005" variable) is plotted. The code I have developed is this:
data(wrld_simpl)
world<-wrld_simpl
world_sf = st_as_sf(world)
world_sf_proj = st_transform(world_sf, crs = 3785)
world_cartogram <- cartogram_cont(world_sf_proj, "POP2005")
plot(world_cartogram)
Nonetheless, this has resulted in the following figure:
Do you know what is wrong with the code? Maybe the CRS? I have tried to use others CRS but I got the following error:
"Error: Using an unprojected map. This function does not give correct centroids and distances for longitude/latitude data:
Use "st_transform()" to transform coordinates to another projection."
Taken from this documentation, it is stated that
The default plot of an sf object is a multi-plot of all attributes, up
to a reasonable maximum
If you want to use the base R plot function, then use st_geometry(your_map) to plot (the geometry) an sf object.
Another possibility (which I don't recommend) is to set plot options to 1 plot maximum (options(sf_max.plot=1)), but this plots the first variable, and it might not be the best idea.
library(sf)
library(spData)
library(cartogram)
library(tidyverse)
world_sf = st_as_sf(world)
world_sf_proj = st_transform(world_sf, crs = 3785)
world_cartogram <- cartogram_cont(world_sf_proj, "pop")
plot(st_geometry(world_cartogram))
Now, sf is particularly well suited with ggplot2 and the tidyverse. In that setting, just use ggplot in combination with geom_sf.
ggplot(world_cartogram) +
geom_sf()

Colorize the map of Russia depending on the variable in R

I have a map of Russia with regional subdivision
library(raster)
data <- getData('GADM', country='RUS', level=1)
http://www.gks.ru/bgd/regl/B16_14p/IssWWW.exe/Stg/d01/08-01.doc
The link is to a Word.doc with data (table) on crime rates for Russian regions. I can extract this data and use it in R. I want to take 2015 year and colorize regions on the map depending on the crime rate (also add a legend). How can I do this? The problem is that names of regions are sometimes different in the shape file (NL_NAME_1) and in the data from www.gks.ru.
I also have this code for graph that I need, except that here we have meaningless colors:
library(sp)
library(RColorBrewer)
data$region <- as.factor(iconv(as.character(data$NAME_1)))
spplot(data, "region", xlim=c(15,190), ylim=c(40,83),
col.regions=colorRampPalette(brewer.pal(12, "Set3"))(85), col = "white")
If I understand your question properly, you just need to add your data to the spatial object for making colors meaningful.
Note, please, that the data is a reserved word in R. So, it's better to modify a little your variable name:
geo_data <- getData('GADM', country = 'RUS', level = 1)
Let's emulate some data to demonstrate a visualization strategy:
set.seed(23)
geo_data#data["data_to_plot"] <- sample(1:100, length(geo_data#data$NAME_1))
Using a default GADM projection would cut the most eastern part of the country. A simple transformation helps to fit the whole area to a plot:
# fit Russian area inside the plot
geo_data_trsf <- spTransform(geo_data, CRS("+proj=longlat +lon_wrap=180"))
Draw the map selecting data_to_plot instead of region:
max_data_val <- max(geo_data_trsf#data$data_to_plot)
spplot(geo_data_trsf, zcol = "data_to_plot",
col.regions = colorRampPalette(brewer.pal(12, "Set3"))(max_data_val),
col = "white")
The plot limits are adjusted automatically for the transformed spatial data geo_data_trsf, making possible to omit xlim and ylim.
As for the problem with the names, I can't provide any ready-to-use solution. Obviously, the regions' names of NL_NAME_1 need some additional treatment to use them as labels. I think, it would be better to use NAME_1 as an identifier in your code to ensure that it'll be no troubles with encoding. The NL_NAME_1 column is perfectly suitable to set the correspondence between your Word-data and the data inside the spatial object geo_data.

Plotting Canmaps line data in R

I am new to using R and am working with a shape file from the DMTI Canmap dataset: http://www.dmtispatial.com/canmap/#top
I have been successful importing the shape file as a 'SpatialLineDataFrame' using readOGR. I have been unsuccessful in mapping the data. Here is what I have tried so far. Note: I have named the data frame 'trans'.
library(maps)
library(rgdal)
1 Plotting the longitude and latitude coordinates
plot(trans$LONGITUDE,trans$LATITUDE)
This command plots the coordinates as points not lines. I'd like to map the lines.
2 Using ggmap to plot
library(ggmap)
can <- get_map(location="canada",zoom=3)
ggmap(can) + geom_point(data=trans, aes(x="LONGITUDE",y="LATITUDE"))
This returns an error saying 'Error: Discrete value supplied to continuous scale'
ggmap(can) + geom_path(data=trans, aes(x="LONGITUDE",y="LATITUDE"))
This also returns an error saying 'Error: Discrete value supplied to continuous scale'
As a heads-up, when I ask for the names of the data stored in 'trans' I get these names: "UID" "NAME" "TYPE" "LOCATION" "NUM_LINES" "MUNICIPAL" "PROV" "LONGITUDE" "LATITUDE" "BEGELEV" "ENDELEV" "ACCURACY" "ACQ_TECH" "VALDATE" "PROVIDER" "SHAPE_Leng"
Are there packages or commands you would recommend trying in order to map the lines stored in this .shp file using R?

R Highlighting some of the boundaries (or borders) of the region in a shape file with spplot()

I am working on a shape file and like to highlight some of the boundaries (borders) of the regions (as figure 1):
Figure 1: some but not all of the regions (borders) of the shape file are highlighted
(Source: https://dl.dropboxusercontent.com/u/48721006/highlighted.png)
The highlighting is achieved with ArcMap. I can't figure out how to do the same with R (particularly with the spplot()). Any suggestions on this?
To get the shape file
library(sp)
library(maptools)
con <- url("http://gadm.org/data/rda/ZAF_adm2.RData")
print(load(con))
close(con)
plot(gadm)
Many thanks!
G
What I would do: (1) plot the complete set; (2) take a subset; (3) plot the subset with a different line type. For subsetting shape files, check this question.
plot(gadm)
# check class and structure of the data
class(gadm)
head(gadm#data)
# take a subset based on ID_2
some_polygons = subset(gadm,ID_2>=38840 & ID_2<38850)
plot(some_polygons, add=T, border='cyan', lwd=2)

Resources