R: Changing values from raster at certain coordinates - r

I run species distribution models in R and want to create variable rasters for the mainland of Africa, without the islands. I can only find shapefiles of Africa with its islands, not from the mainland only.
1) Where can I possibly download a shapefile of the mainland only?
2) If there is no shapefile, I would like to manually delete the islands from my raster. Is there a way to do this, f.e. setting parts of the rasters between certain coordinates to NA?

Yes. Here is a minimal, self-contained, reproducible example. The easiest approach might be to use Africa polygons africa and do
library(raster)
afr <- aggregate(africa)
v <- disaggregate(afr)
a <- area(v)
afnois <- v[which.max(a), ]
And then used that in mask to remove the islands from the rasters
You can also create polygons with raster::drawPoly and use these for masking.

Related

How can I create a Kentucky Map by Zip Code in R?

Suppose I have a dataframe containing Kentucky zip codes and values between -1 and 1. I want to plot these as a heatmap of Kentucky, where -1 represents the lowest color of the gradient and 1 represents the highest.
How can I do this in R? I'm using R Studio 1.3.959 (R version 3.6.3).
An option using tigris and sf. Note that this uses zip code tabulation areas, which are not a 1:1 match with zip codes. Zip codes follow streets and can't be made into sensible polygons: https://gis.stackexchange.com/a/2693/162034
library(tigris)
library(sf)
# download zipcode tabulation areas and state boundaries
zcta1 <- zctas(TRUE)
sts <- states(TRUE)
# subset zipcode data
zcta_ky <- st_intersection(zcta1, sts[sts$NAME == 'Kentucky', ])
# add random 0-1 field
zcta_ky$rand <- runif(nrow(zcta_ky))
#plot
plot(zcta_ky['rand'])

How to get a subset from a shapefile with the correct outline?

I have a Hindu Kush Himalayan region shapefile that can be found in http://rds.icimod.org/Home/DataDetail?metadataId=3924 , and I have lat long of Nepal that have taken from this website (http://rds.icimod.org/Home/DataDetail?metadataId=19590&searchlist=True).
The geographical extent of Nepal is
Geographic Extent East: 88.19456,Geographic Extent West:80.0522,Geographic Extent North:30.42472,Geographic Extent South: 26.36836
Now I am trying to subset Nepal from Hindu Kush Himalayan shapefile. This is my code:
mountains<-readOGR("outline.shp") #hindukushhimalayanshapefile
sub <- crop(mountains, extent( 80.0522, 88.18456, 26.36836, 30.42472))
plot(sub)
But the plot sub (that is of Nepal) is not shown properly with a proper outline. There are straight lines showing in the top. How can I get a proper subset of Nepal with the right outline. Am I putting the extent wrong? Help would be appreciated
You cannot subset country boundaries from that shapefile as it does not contain information on country boundaries.
You would have to use a shapefile such as this one which contains information on country boundaries: http://rds.icimod.org/Home/DataDetail?metadataId=1218, or subset using a separate Nepal boundary shapefile instead of an extent:
require(maptools)
require(rgdal)
hkh_shp=readOGR("/Downloads/data/outline.shp")
data(wrld_simpl) ##this shapefile is quite coarse, you could substitute another one
nepal_shp=wrld_simpl[which(wrld_simpl$NAME=="Nepal"),]
##CRS are similar but not identical, so need to transform
nepal_shp=spTransform(nepal_shp,crs(hkh_shp))
plot(hkh_shp)
lines(nepal_shp,col="red")
##crop
hkh_sub_shp=crop(hkh_shp,nepal_shp)
plot(hkh_sub_shp) ##note, will look better with higher resolution shapefile

Merging (two and a half) countries from maps-package to one map object in R

I am looking for a map that combines Germany, Austria and parts of Switzerland together to one spatial object. This area should represent the German speaking areas in those three countries. I have some parts in place, but can not find a way to combine them. If there is a completely different solution to solve this problem, I am still interested.
I get the German and the Austrian map by:
require(maps)
germany <- map("world",regions="Germany",fill=TRUE,col="white") #get the map
austria <- map("world",regions="Austria",fill=TRUE,col="white") #get the map
Switzerland is more complicated, as I only need the 60-70% percent which mainly speak German. The cantones that do so (taken from the census report) are
cantonesGerman = c("Uri", "Appenzell Innerrhoden", "Nidwalden", "Obwalden", "Appenzell Ausserrhoden", "Schwyz", "Lucerne", "Thurgau", "Solothurn", "Sankt Gallen", "Schaffhausen", "Basel-Landschaft", "Aargau", "Glarus", "Zug", "Zürich", "Basel-Stadt")
The cantone names can used together with data from gadm.org/country (selecting Switzerland & SpatialPolygonsDataFrame -> Level 1 or via the direct link) to get the German-speaking areas from the gadm-object:
gadmCH = readRDS("~/tmp/CHE_adm1.rds")
dataGermanSwiss <- gadmCH[gadmCH$NAME_1 %in% cantonesGerman,]
I am now missing the merging step to get this information together. The result should look like this:
It represents a combined map consisting of the contours of the merged area (Germany + Austria + ~70% of Switzerland), without borders between the countries. If adding and leaving out the inter-country borders would be parametrizable, that would be great but not a must have.
You can that like this:
Get the polygons you need
library(raster)
deu <- getData('GADM', country='DEU', level=0)
aut <- getData('GADM', country='AUT', level=0)
swi <- getData('GADM', country='CHE', level=1)
Subset the Swiss cantons (here an example list, not the correct one); there is no need for a loop for such things in R.
cantone <- c('Aargau', 'Appenzell Ausserrhoden', 'Appenzell Innerrhoden', 'Basel-Landschaft', 'Basel-Stadt', 'Sankt Gallen', 'Schaffhausen', 'Solothurn', 'Thurgau', 'Zürich')
GermanSwiss <- swi[swi$NAME_1 %in% cantone,]
Aggregate (dissolve) Swiss internal boundaries
GermanSwiss <- aggregate(GermanSwiss)
Combine the three countries and aggregate
german <- bind(deu, aut, GermanSwiss)
german <- aggregate(german)

R - Fully remove cropped shapefile data

Is there a way to remove unused levels in a SpatialPolygonsDataFrame object in R?
I have large shapefile of geological data Geology that I am clipping with the raster::crop tool. This seems to work fine.
But when I try to work using my new, cropped shapefile Geo, polygon types present in Geology but absent in area covered by Geo still appear as levels in Geo. This interferes with my later analysis.
I have tried to remove these "ghost" levels/attributes using droplevels, but this function is not valid for SpatialPolygons or SpatialPolygonsDataFrame objects.
For reference, I am using the wygeol_dd_polygon.shp shapefile (downloadable here - 41.4 MB) as a starting point. The salient parts of my code are below:
library(maptools)
Geology <- readShapePoly("~/wygeol_dd_polygon.shp")
library(raster)
Geo <- crop(Geology, extent(-111.05, -110.25, 44.2667, 44.7667))
After cropping, I have ten unique rock types, but still 46 levels:
unique(Geo$ROCKTYPE1)
[1] alluvium rhyolite mixed clastic/volcanic intermediate volcanic rock
[5] basalt water trachyandesite sandstone
[9] conglomerate shale
46 Levels: alkalic intrusive rock alkalic volcanic rock alluvium andesite anorthosite basalt carbonate clastic ... water
How do I get rid of these?
Try this:
Geo#data<-droplevels(Geo#data)
The above will handle all the factor columns in one call.
The column you are having issues with as a factor variable. When you crop factors in R, it often retains the cropped factors even though you no longer have any remaining in your dataset. Gladly it's an easy fix as follows:
Geo$ROCKTYPE1 <- factor(Geo$ROCKTYPE1)
This redefines the factor so now you should only have 10 levels, as you want.

Shading counties using FIPS code in R map

I am looking for a way to shade counties on the US maps in R. I have list of numeric/char county FIPS code that I can input as parameter. I just need to highlight these counties -- so would just need to shade them and there are no values or variations corresponding to the counties. I tried to look up
library(choroplethr)
library(maps)
and
county_choropleth(df_pop_county)
head(df_pop_county)
region value
1 1001 54590
2 1003 183226
3 1005 27469
4 1007 22769
5 1009 57466
6 1011 10779
But these need a region, value pair. For e.g.,fips code and population in the above. Is there a way to call the county_choropleth function without having to use the values, just with the fipscode dataframe. In that way, I can my fips code with one color. What would be an efficient way to accomplish this in R using Choroplethr?
Here's an example using the maps library:
library(maps)
library(dplyr)
data(county.fips)
## Set up fake df_pop_county data frame
df_pop_county <- data.frame(region=county.fips$fips)
df_pop_county$value <- county.fips$fips
y <- df_pop_county$value
df_pop_county$color <- gray(y / max(y))
## merge population data with county.fips to make sure color column is
## ordered correctly.
counties <- county.fips %>% left_join(df_pop_county, by=c('fips'='region'))
map("county", fill=TRUE, col=counties$color)
Here's the resulting map:
Notice that counties with lower FIPS are darker, while counties with higher FIPS are lighter.

Resources