R: plotting neighbouring countries using maptools - r

Say I am plotting countries on a world map using maptools, if I were to plot a country, is there a way of plotting the countries that border this country in a different colour? I am using the shapefile wrld_simpl that comes with maptools, so say I plot China:
plot(wrld_simpl[wrld_simpl$NAME=='China',], col='red', add=T)
is there a way I can get it to plot all the bordering countries to China. I want to be able to do this for lots of different countries so I'd ideally want a general solution, not one specific to just China.

How about gTouches or gIntersects in rgeos?
library(rgeos)
library(maptools)
wc <- subset(wrld_simpl, NAME == "China")
world <- subset(wrld_simpl, !NAME == "China")
Create a vector to store the test:
tst <- logical(nrow(world))
Do the test:
for (i in 1:nrow(world)) {
tst[i] <- gTouches(wc, world[i,])
}
See the result:
levels(world$NAME)[world$NAME[tst]]
[1] "India" "Russia"
plot(wc)
plot(world[tst, ], add = TRUE, col = "grey")
(No further correspondence on world affairs will be entered into, but gIntersects seems to give a better answer).
I strongly advise you to treat these built-in data sets with caution, you certainly need to get your hands on reliable data if you are to use such a tool for any non-trivial purpose. Geometry and data are tricky enough already. :)
for (i in 1:nrow(world)) {
tst[i] <- gIntersects(wc, world[i,])
}
length(levels(world$NAME)[world$NAME[tst]])
[1] 14
plot(world[tst, ], col = "firebrick")
plot(wc, add = TRUE, col = "grey")

Related

Mapping my data to a Zip Code area map in R

My data is like this:
ZIPcode Cases longi lati
43613 1 -83.604452 41.704307
44140 1 -81.92148 41.48982
46052 1 -86.470531 40.051603
48009 22 -83.213883 42.544619
48017 6 -83.151815 42.535396
48021 7 -82.946167 42.463894
48025 19 -83.265758 42.523195
I want to get a map similar to this (if you can see it) in R. The outline should be zipcodes and the shading should be according to number of cases, darker as cases increase.
I'm very new to R. Tried a lot of code I found online but can't get what I want. Any help is appreciated. Can this be done in base SAS ?
Thank you!
enter image description here
Definetly you can do it in R, I put together a reprex (reproducible example) for you. Key points:
You need to load into R a .shp file (or .geojson, .gpkg, etc.). That is an actual file with the outline of your map. For ZIPCODES I found a R package, tigris, that does that for you, if not you'll need to load it by yourself.
For handling mapping objects (load, transform, .etc), sf package is your best friend.
For plotting, in this example I used cartography, but you can use several different package, as ggplot2 or tmap.
Last line is that, given your data (and if I didn't get the ZIPCODEs wrong), a map as the one you shown (choropleth map) maybe is not the best options. Have a look here to see other alternatives.
library(sf) #Overall handling of sf objects
library(cartography) #Plotting maps package
#1. Create your data
yourdata <- data.frame(ZCTA5CE10=c("43613", "44140", "46052",
"48009","48017", "48021","48025"),
Cases=c(1,1,1,22,6,7,19)
)
#2. Download a shapefile (shp,gpkg,geojson...)
library(tigris) #For downloading the zipcode map
options(tigris_use_cache = TRUE)
geo <- st_as_sf(zctas(cb = TRUE, starts_with = yourdata$ZCTA5CE10))
#Overall shape of USA states
states <- st_as_sf(states(cb=TRUE))
#For plotting, all the maps should have the same crs
states=st_transform(states,st_crs(geo))
#3. Now Merge your data
yourdata.sf=merge(geo,yourdata)
#4. Plotting
par(mar=c(1,1,1,1))
ghostLayer(yourdata.sf)
plot(st_geometry(states), add=TRUE)
choroLayer(yourdata.sf,
var="Cases",
add=TRUE,
border = NA,
legend.pos = "right",
legend.frame = TRUE)
layoutLayer(title = "Cases by ZIPCODE",
theme = "blue.pal",
scale = FALSE,
sources = "Source; your question on SO",
author = "by dieghernan, 2020"
)
Created on 2020-02-27 by the reprex package (v0.3.0)

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.

How to map a single US state (MO) county population data using maps package?

I'm having difficulty mapping gradient colors to some county-level population data I have using the base R package maps. I know that colors must be interpolated to the dataframe, but I'm not sure how that is then translated to the map. Here is the code I'm using:
library(dplyr)
require(maps)
my_fake_data <- data_frame(
county = sample(c('list','of','all','counties'),115,T),
county_population = sample(1:1000000,115,T))
grey_black <- colorRampPalette(c('grey50','black'))
map_data <- my_fake_data %>%
arrange(county_population) %>%
mutate(county_population_color = grey_black(nrow(.)))
map('county','missouri',interior = T,fill =T,
col = grey_black(map_data$county_population_color))
How do I tell R to map colors in the correct order? My sense tells me to attach my data to map's internal database, but I can't find the documentation to do it correctly - - or, more likely, I'm just wrong. Any help would be greatly appreciated.
To answer your question, you will need to access the county.fips data frame contained in the maps package. This will have the fips number and the state, county name. This list is in the correct order for mapping. The code example below extracts the Missouri counties and randomly colors a couple for verification:
mocounties<-county.fips[grepl('missouri', county.fips$polyname),]
mocounties$col<-"grey"
mocounties$col[5]<-"red"
mocounties$col[15]<-"green"
mocounties$col[115]<-"blue"
map('county','missouri', interior = T,fill =T,
col = mocounties$col)

Creating a geographical map in R

I want to create a geographical map of countries in Europe where I can highlight which of the countries are using a particular system.
I have tried using the library(maps) but here I cant find an option to plot the whole of Europa (and also several relevant countries are not included in the package). Does anybody have suggestion for me on how to do is?
What about this?
library(rworldmap)
world <- getMap()
europe <- world[world$ADMIN %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus","Czech Republic","Denmark","Estonia","Finland","France","Germany","Greece","Hungary","Ireland","Italy","Latvia","Lithuania","Luxembourg","Malta","Netherlands","Poland","Portugal","Romania","Slovakia","Slovenia","Spain","Sweden","United Kingdom"), ]
cols <- setNames(rep("yellow", length(europe$ADMIN)), europe$ADMIN)
cols["France"] <- "blue"; cols["Poland"] <- "red"
plot(europe, col = cols)

Plotting Great Circle Paths

I'm trying to plot some path/connection based maps but am unable to figure out how.
I see a lot of possibilities for one point based metrics (crime hotspots in London, etc. with googleVis, ggmap, etc.) but I can't find too many examples of two points based metrics (immigrations between cities, train routes, etc.) There is an example with the package geosphere, but it seems to not be available for R 3.0.2.
Ideally I would like something like this D3 example and would also like to customise the thickness, colour, etc. of the lines and the circles.
PS: I don't suppose rCharts can do this just yet, right?
Here's something I started last year and never got around to polishing properly but hopefully it should answer your question of joining points on a map with great circle lines, with the flexibility to customise lines, circles etc.
I use the (my) rworldmap package for mapping, WDI for world bank data and geosphere for the great circle lines. The aim was to plot aid flows from all donor countries to all recipient countries (one plot per donor). Below is an example plot, and below that the code. Hope it helps. Would be nice to find time to pick it up again!
Andy
library(rworldmap)
library(WDI) # WORLD BANK INDICATORS
## lines of either type may obscure more than they add
##**choose line option here
addLines <- 'gc' #'none''straight' 'gc'
if ( addLines == 'gc' ) library(geosphere)
# setting background colours
oceanCol = rgb(7,0,30,maxColorValue=255)
landCol = oceanCol
#produces a list of indicator IDs and names as a matrix
indicatorList <- WDIsearch('aid flows')
#setting up a world map shaped plot window
#*beware this is windows specific
mapDevice('windows',width=10,height=4.5)
year <- 2000
#for(indNum in 1:2)
for(indNum in 1:nrow(indicatorList))
{
indID <- indicatorList[indNum][1]
donorISO3 <- substr(indID,start=8,stop=10)
dFdonor <- WDI(indicator=indID,start=year,end=year)
#divide by 10^6 for million dollars
dFdonor[indID] <- dFdonor[indID] * 1/10^6
sPDFdonor <- joinCountryData2Map(dFdonor,nameJoinColumn='country',joinCode='NAME')
#take out Antarctica
sPDFdonor <- sPDFdonor[-which(row.names(sPDFdonor)=='Antarctica'),]
legendTitle=paste("aid flow from",donorISO3,year,"(millions US$)")
mapBubbles(sPDFdonor, nameZSize=indID, plotZeroVals=FALSE, legendHoriz=TRUE, legendPos="bottom", fill=FALSE, legendTitle=legendTitle, oceanCol=oceanCol, landCol=landCol,borderCol=rgb(50,50,50,maxColorValue=255),lwd=0.5,lwdSymbols=1)
#removed because not working , main=paste('donor', donorISO3,year)
#now can I plot lines from the centroid of the donor to the centroids of the recipients
xDonor <- sPDFdonor$LON[ which(sPDFdonor$ISO3==donorISO3) ]
yDonor <- sPDFdonor$LAT[ which(sPDFdonor$ISO3==donorISO3) ]
xRecips <- sPDFdonor$LON[ which(sPDFdonor[[indID]] > 0) ]
yRecips <- sPDFdonor$LAT[ which(sPDFdonor[[indID]] > 0) ]
amountRecips <- sPDFdonor[[indID]][ which(sPDFdonor[[indID]] > 0) ]
## straight lines
if ( addLines == 'straight' )
{
for(line in 1:length(xRecips))
{
#col <- 'blue'
#i could modify the colour of the lines by the size of the donation
#col=rgb(1,1,1,alpha=amountRecips[line]/max(amountRecips))
#moving up lower values
col=rgb(1,1,0,alpha=sqrt(amountRecips[line])/sqrt(max(amountRecips)))
lines(x=c(xDonor,xRecips[line]),y=c(yDonor,yRecips[line]),col=col, lty="dotted", lwd=0.5) #lty = "dashed", "dotted", "dotdash", "longdash", lwd some devices support <1
}
}
## great circle lines
## don't work well when donor not centred in the map
## also the loop fails at CEC & TOT because not ISO3 codes
if ( addLines == 'gc' & donorISO3 != "CEC" & donorISO3 != "TOT" )
{
for(line in 1:length(xRecips))
{
#gC <- gcIntermediate(c(xDonor,yDonor),c(xRecips[line],yRecips[line]), n=50, breakAtDateLine=TRUE)
#30/10/13 lines command failed with Error in xy.coords(x, y) :
#'x' is a list, but does not have components 'x' and 'y'
#adding sp=TRUE solved
gC <- gcIntermediate(c(xDonor,yDonor),c(xRecips[line],yRecips[line]), n=50, breakAtDateLine=TRUE, sp=TRUE)
#i could modify the colour of the lines by the size of the donation
#col=rgb(1,1,1,alpha=amountRecips[line]/max(amountRecips))
#moving up lower values
col=rgb(1,1,0,alpha=sqrt(amountRecips[line])/sqrt(max(amountRecips)))
lines(gC,col=col,lwd=0.5)
}
}
#adding coasts in blue looks nice but may distract
data(coastsCoarse)
plot(coastsCoarse,add=TRUE,col='blue')
#repeating mapBubbles with add=T to go on top of the lines
mapBubbles(sPDFdonor, nameZSize=indID, plotZeroVals=FALSE, fill=FALSE, addLegend=FALSE, add=TRUE, ,lwd=2)
#removed because not working : , main=paste('donor', donorISO3,year)
#looking at adding country labels
text(xRecips,yRecips,sPDFdonor$NAME[ which(sPDFdonor[[indID]] > 0) ],col=rgb(1,1,1,alpha=0.3),cex=0.6,pos=4) #pos=4 right (1=b,2=l,3=ab)
#add a title
nameDonor <- sPDFdonor$NAME[ which(sPDFdonor$ISO3==donorISO3) ]
mtext(paste("Aid flow from",nameDonor,year), cex = 1.8, line=-0.8)
#savePlot(paste("C:\\rProjects\\aidVisCompetition2012\\Rplots\\greatCircles\\wdiAidFlowLinesDonor",donorISO3,year,sep=''),type='png')
#savePlot(paste("C:\\rProjects\\aidVisCompetition2012\\Rplots\\greatCircles\\wdiAidFlowLinesDonor",donorISO3,year,sep=''),type='pdf')
} #end of indNum loop

Resources