Create many shape file from a large shape file. - r

I have a shape file with two different region with 12 sub region each.I want separate shape file of these 24 sub region from that shape file.I have also tried by using package maptools and rgeos but could not figure it.Any logarithm would be very much appreciated. Thanks.
sharif

You can split your data in a loop based on the unique value in the column of interest and write out the subset data. I am using rgdal in leu of maptools but you could easily change the code to use maptools functions for reading/writing shapefiles.
require(sp)
require(rgdal)
# READ SHAPEFILE
dat <- readOGR("C:/DATA", "dat")
# CREATE VECTOR OF UNIQUE SUBREGION VALUES
y <- unique(dat#data$SUBREGIONS)
# CREATE SHAPEFILE FOR EACH SUBREGION AND WRITE OUT
for (i in 1:length(y) ) {
temp <- dat[dat$SUBREGIONS == y[i], ]
writeOGR(temp, dsn=getwd(), y[i], driver="ESRI Shapefile",
overwrite_layer=TRUE)
}

Related

Use "st_transform()" to transform coordinates to another projection - when creating cartogram

I have a shapefile of population estimates of different administrative levels on Nigeria and I want to create a cartogram out of it.
I used the cartogram package and tried the following
library(cartogram)
admin_lvl2_cartogram <- cartogram(admin_level2_shape, "mean", itermax=5)
However this gives me an error stating "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." I'm not sure how to resolve this
To recreate the initial data
Download the data using the wopr package
library(wopr)
catalogue <- getCatalogue()
# Select files from the catalogue by subsetting the data frame
selection <- subset(catalogue,
country == 'NGA' &
category == 'Population' &
version == 'v1.2')
# Download selected files
downloadData(selection)
Manually unzip the downloaded zip file (NGA_population_v1_2_admin.zip) and read in the data
library(rgdal)
library(here)
admin_level2_shape <- readOGR(here::here("wopr/NGA/population/v1.2/NGA_population_v1_2_admin/NGA_population_v1_2_admin_level2_boundaries.shp"))
The function spTransform in the sp package is probably easiest because the readOGR call returns a spatial polygon defined in that package.
Here's a full example that transforms to a suitable projection for Nigeria, "+init=epsg:26331". You'll probably have to Google to find the exact one for your needs.
#devtools::install_github('wpgp/wopr')
library(wopr)
library(cartogram)
library(rgdal)
library(sp)
library(here)
catalogue <- getCatalogue()
# Select files from the catalogue by subsetting the data frame
selection <- subset(catalogue, country == 'NGA' & category == 'Population' & version == 'v1.2')
# Download selected files
downloadData(selection)
unzip(here::here("wopr/NGA/population/v1.2/NGA_population_v1_2_admin.zip"),
overwrite = T,
exdir = here::here("wopr/NGA/population/v1.2"))
admin_level2_shape <- readOGR(here::here("wopr/NGA/population/v1.2/NGA_population_v1_2_admin/NGA_population_v1_2_admin_level2_boundaries.shp"))
transformed <- spTransform(admin_level2_shape, CRS("+init=epsg:26331"))
admin_lvl2_cartogram <- cartogram(transformed, "mean", itermax=5)
I confess I don't know anything about the specific packages so I don't know if what is produced is correct, but at least it transforms.

Crop multiple Rasters (ASCII)

I have more than 50 raster files (ASCII format) that I need to crop. I already exported the mask from ArcMap in ASCII format as well and loaded it into R. How can I make it work for all rasters in a row and export them with the same name as before (of course in a different folder to not overwrite)?
I know there is a crop function in the raster package, but I never used it so far. I only stacked them for further habitat analysis.
My Code so far:
#### Use only part of area
files2 <- list.files(path="D:/",full.names=TRUE, pattern = "\\.asc$")
files2
# Create a RasterLayer from first file
mask_raster <- raster(files2[1])
# Crop. But how??
crop(x = , y=mask_raster)
writeRaster(...)`
I did not find an easy solution to crop multiple rasters by a raster, but by a shape file. So I just went back to ArcMap and converted the raster into a shapefile. Then in R, crop and mask were the crucial steps. See code below (modified from Mauricio Zambrano-Bigiarini's code). Hope this helps.
# Reading the shapefile (mask to crop later)
Maskshp <- readOGR("mask.shp")
# Getting the spatial extent of the shapefile
e <- extent(Maskshp)
# for loop with (in this case) 60 runs
for (i in 1:60) {
# Reading the raster to crop
files <- list.files(path="...your path",full.names=TRUE, pattern = "\\.asc$")
Env_raster <- raster(files[i])
# Save the filename
filename <- (paste(basename(files[i]), sep=""))
# Crop the raster
Env_raster.crop <- crop(Env_raster, e, snap="out")
# Dummy raster with a spatial extension equal to the cropped raster,
# but full of NA values
crop <- setValues(Env_raster.crop, NA)
# Rasterize the catchment boundaries, with NA outside the catchment boundaries
Maskshp.r <- rasterize(Maskshp, crop)
# Putting NA values in all the raster cells outside the shapefile boundaries
Maskshp.masked <- mask(x=Env_raster.crop, mask=Maskshp.r)
plot(Maskshp.masked)
#Export file to working directory with original name as new name
writeRaster(Maskshp.masked, filename)
}

How to filter a shape file before plotting it in R

Just to try to filter a shape file to ease plotting
I have a shape file downloaded from UK gov:
http://geoportal.statistics.gov.uk/datasets/7ff28788e1e640de8150fb8f35703f6e_1/data?geometry=-76.678%2C45.365%2C69.572%2C63.013&orderBy=lad16cd&orderByAsc=false&where=%20(UPPER(lad16cd)%20like%20%27%25E0800000%25%27%20OR%20UPPER(lad16cd)%20like%20%27%25E08000010%25%27)%20
Based on this: https://www.r-bloggers.com/r-and-gis-working-with-shapefiles/
I wrote but do not know to filter :
setwd("~/Documents/filename")
getwd() # --double confirm real data directory
#install.packages("maptools")
library(maptools)
crswgs84=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
ukmap=readShapePoly("filename.shp",proj4string=crswgs84,verbose=TRUE)
class(ukmap)
str(ukmap#data)
str(ukmap#polygons[[1]])
ukmap#bbox
# <-- need to do some filterig
plot(ukmap) # as this will take too long and not want to plot whole UK
For example I just want "E06000001" to "E06000020".
(the filename is "Local_Authority_Districts_December_2016_Full_Extent_Boundaries_in_the_UK" not sure how to include it in the program coding quote)
You can consider to use the sf package to read the shapefile and plot the data. Filtering the sf object is the same as filtering a data frame.
library(sf)
# Read the sahpefile
ukmap <- st_read("Local_Authority_Districts_December_2016_Full_Extent_Boundaries_in_the_UK.shp")
# Subset the sf object
ukmap_sub <- ukmap[ukmap$lad16cd %in% c("E06000001", "E06000020"), ]
# Plot the boundary of ukmap_sub
plot(st_geometry(ukmap_sub))
If you prefer to work with on SpatialPolygonsDataFrame, we can use the readOGR function from the rgdal package. After that, we can subset the SpatialPolygonsDataFrame like a regular data frame.
library(maptools)
library(rgdal)
ukmap <- readOGR(dsn = getwd(), layer = "Local_Authority_Districts_December_2016_Full_Extent_Boundaries_in_the_UK")
ukmap_sub <- ukmap[ukmap$lad16cd %in% c("E06000001", "E06000020"), ]
plot(ukmap_sub)

How to convert .shp file into .csv in R?

I want to to convert two .shp files into one database that would allow me to draw the maps together.
Also, is there a way to convert .shp files into .csv files? I want to be able to personalize and add some data which is easier for me under a .csv format. What I have in mind if to add overlay yield data and precipitation data on the maps.
Here are the shapefiles for Morocco, and Western Sahara.
Code to plot the two files:
# This is code for mapping of CGE_Morocco results
# Loading administrative coordinates for Morocco maps
library(sp)
library(maptools)
library(mapdata)
# Loading shape files
Mor <- readShapeSpatial("F:/Purdue University/RA_Position/PhD_ResearchandDissert/PhD_Draft/Country-CGE/MAR_adm1.shp")
Sah <- readShapeSpatial("F:/Purdue University/RA_Position/PhD_ResearchandDissert/PhD_Draft/Country-CGE/ESH_adm1.shp")
# Ploting the maps (raw)
png("Morocco.png")
Morocco <- readShapePoly("F:/Purdue University/RA_Position/PhD_ResearchandDissert/PhD_Draft/Country-CGE/MAR_adm1.shp")
plot(Morocco)
dev.off()
png("WesternSahara.png")
WesternSahara <- readShapePoly("F:/Purdue University/RA_Position/PhD_ResearchandDissert/PhD_Draft/Country-CGE/ESH_adm1.shp")
plot(WesternSahara)
dev.off()
After looking into suggestions from #AriBFriedman and #PaulHiemstra and subsequently figuring out how to merge .shp files, I have managed to produce the following map using the following code and data (For .shp data, cf. links above)
code:
# Merging Mor and Sah .shp files into one .shp file
MoroccoData <- rbind(Mor#data,Sah#data) # First, 'stack' the attribute list rows using rbind()
MoroccoPolys <- c(Mor#polygons,Sah#polygons) # Next, combine the two polygon lists into a single list using c()
summary(MoroccoData)
summary(MoroccoPolys)
offset <- length(MoroccoPolys) # Next, generate a new polygon ID for the new SpatialPolygonDataFrame object
browser()
for (i in 1: offset)
{
sNew = as.character(i)
MoroccoPolys[[i]]#ID = sNew
}
ID <- c(as.character(1:length(MoroccoPolys))) # Create an identical ID field and append it to the merged Data component
MoroccoDataWithID <- cbind(ID,MoroccoData)
MoroccoPolysSP <- SpatialPolygons(MoroccoPolys,proj4string=CRS(proj4string(Sah))) # Promote the merged list to a SpatialPolygons data object
Morocco <- SpatialPolygonsDataFrame(MoroccoPolysSP,data = MoroccoDataWithID,match.ID = FALSE) # Combine the merged Data and Polygon components into a new SpatialPolygonsDataFrame.
Morocco#data$id <- rownames(Morocco#data)
Morocco.fort <- fortify(Morocco, region='id')
Morocco.fort <- Morocco.fort[order(Morocco.fort$order), ]
MoroccoMap <- ggplot(data=Morocco.fort, aes(long, lat, group=group)) +
geom_polygon(colour='black',fill='white') +
theme_bw()
Results:
New Question:
1- How to eliminate the boundaries data that cuts though the map in half?
2- How to combine different regions within a .shp file?
Thanks you all.
P.S: the community in stackoverflow.com is wonderful and very helpful, and especially toward beginners like :) Just thought of emphasizing it.
Once you have loaded your shapefiles into Spatial{Lines/Polygons}DataFrames (classes from the sp-package), you can use the fortify generic function to transform them to flat data.frame format. The specific functions for the fortify generic are included in the ggplot2 package, so you'll need to load that first. A code example:
library(ggplot2)
polygon_dataframe = fortify(polygon_spdf)
where polygon_spdf is a SpatialPolygonsDataFrame. A similar approach works for SpatialLinesDataFrame's.
The difference between my solution and that of #AriBFriedman is that mine includes the x and y coordinates of the polygons/lines, in addition to the data associated to those polgons/lines. I really like visualising my spatial data with the ggplot2 package.
Once you have your data in a normal data.frame you can simply use write.csv to generate a csv file on disk.
I think you mean you want the associated data.frame from each?
If so, it can be accessed with the # slot access function. The slot is called data:
write.csv( WesternSahara#data, file="/home/wherever/myWesternSahara.csv")
Then when you read it back in with read.csv, you can try assigning:
myEdits <- read.csv("/home/wherever/myWesternSahara_modified.csv")
WesternSahara#data <- myEdits
You may need to do some massaging of row names and so forth to get it to accept the new data.frame as valid. I'd probably try to merge the existing data.frame with a csv you read in in R, rather than making edits destructively....

making a choropleth in R: merging zip code shapefiles from multiple states

Motivated by the post here, Developing Geographic Thematic Maps with R, I was thinking about constructing a choropleth map based on zip codes. I've downloaded the shape files for New Hampshire and Maine from http://www.census.gov/geo/www/cob/z52000.html, but I'm interested in combining or merging the .shp files from these two states.
Is there a mechanism in the maptools package for doing this kind of merge or concatenation of two .shp files after you read them in using readShapeSpatial()? Also welcome input if e.g. using the RgoogleMaps package would be easier.
I followed up on the link posted by Roman Luštrik, and the following answer is a slight modification of http://r-sig-geo.2731867.n2.nabble.com/suggestion-to-MERGE-or-UNION-3-shapefiles-td5914413.html#a5916751.
The following code will allow you to merge the .shp files obtained from Census 2000 5-Digit ZIP Code Tabulation Areas (ZCTAs) Cartographic Boundary Files and plot them.
In this case, I downloaded the .shp files and associated .dbf and .shx files for Massachusetts, New Hampshire, and Maine.
library('maptools')
library('rgdal')
setwd('c:/location.of.shp.files')
# this location has the shapefiles for zt23_d00 (Maine), zt25_d00 (Mass.), and zt33_d00 (New Hampshire).
# columns.to.keep
# allows the subsequent spRbind to work properly
columns.to.keep <- c('AREA', 'PERIMETER', 'ZCTA', 'NAME', 'LSAD', 'LSAD_TRANS')
files <- list.files(pattern="*.shp$", recursive=TRUE, full.names=TRUE)
uid <-1
# get polygons from first file
poly.data<- readOGR(files[1], gsub("^.*/(.*).shp$", "\\1", files[1]))
n <- length(slot(poly.data, "polygons"))
poly.data <- spChFIDs(poly.data, as.character(uid:(uid+n-1)))
uid <- uid + n
poly.data <- poly.data[columns.to.keep]
# combine remaining polygons with first polygon
for (i in 2:length(files)) {
temp.data <- readOGR(files[i], gsub("^.*/(.*).shp$", "\\1",files[i]))
n <- length(slot(temp.data, "polygons"))
temp.data <- spChFIDs(temp.data, as.character(uid:(uid+n-1)))
temp.data <- temp.data[columns.to.keep]
uid <- uid + n
poly.data <- spRbind(poly.data,temp.data)
}
plot(poly.data)
# save new shapefile
combined.shp <- 'combined.shp'
writeOGR(poly.data, dsn=combined.shp, layer='combined1', driver='ESRI Shapefile')
GeoMerge is a free tool for merging Shapefiles. Merges SHP and DBF parts. Seems to work OK, but I haven't pushed it too much.

Resources