Extract WORLDCLIM data using R for a single country - r

I want to extract world climate data for minimum and maximum temperature for only one country India using R and save it as a data set (to use with my own data-set that contains crop yields at the district level).
I have gone through several posts and can see that this can be done easily in R, however the posts that I have tried to follow are a bit different in terms of the commands or sequences and I am getting confused.
(https://gis.stackexchange.com/questions/259478/worldclim-data-na-for-my-coordinates, https://gis.stackexchange.com/questions/227585/using-r-to-extract-data-from-worldclim
What I have tried to use is as follows.
library(raster)
library(sp)
r<- getData('CMIP5', var='tmin', res=10, rcp=45, model='HE', year=70)
r <- r[[c(1,12)]]
values <- extract(r,points)
df <- cbind.data.frame(coordinates(points),values)
head(df)
However, I can run only the first two lines and the line values
<- extract(r,points) gives the error Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘extract’ for signature ‘"RasterStack", "function"’
Any suggestions?

Here is the solution for it
library(raster)
library(sp)
library(rgeos)
library(rgdal)
library(sf)
r<- getData('CMIP5', var='tmin', res=10, rcp=45, model='HE', year=70)
#Using Zonal statistics
poly <- shapefile("Provide_your_drive_name" e.g. "F:\\Kriging in R\\India Shape files\\2011_Dist.shp")
plot(poly)
#This will take considerable time
ex <- extract(r, poly, fun='mean', na.rm=TRUE, df=TRUE, weights = TRUE)
write.csv(cbind(poly$DISTRICT,ex),"Worldclim.csv", row.names = F)
# using centroids
nc <- st_read(dsn="Provide_your_drive_name" e.g. "F:\\Kriging in R\\India Shape files", layer="2011_Dist")
# just view the attributes & first 6 attribute values of the data
head(nc)
sp_cent <- gCentroid(as(nc, "Spatial"), byid = TRUE)
values <- extract(r,sp_cent)
write.csv(cbind(as.data.frame(nc$DISTRICT),as.data.frame(values)),"Worldclim_centroids.csv", row.names = F)

Related

Error when using Aggregate function in stars raster extract

I'm trying to extract the mean of the raster values for each polygon in a shapefile using stars. Unfortunately, I'm getting the following error when executing it
library(sf)
library(exactextractr)
library(stars)
SA2_data <- st_read("/tmp/SA2_2016_GDA94_data/SA2_2016_AUST.shp") # SA2 regions for australia
SA2_data <- SA2_data[SA2_data$STE_CODE16 == '1',] # filtering the state of NSW
SA2_data <- SA2_data %>% dplyr::filter(!st_is_empty(.)) # filter out empty geometries
current_SOC <- read_stars("/tmp/current_soc_june2021_data/Current_SOC30_mean_June2021a.tif") #importing carbon stocks
SA2_data <- st_transform(SA2_data, crs = st_crs(current_SOC)) ## setting the same CRS in both files
### Extracting the sum of current SOC mean for each sa2 code
data_fill <- NULL
data_mean <- SA2_data %>%
st_drop_geometry() %>%
dplyr::select(SA2_MAIN16)
for (i in 98){
#i <-1
data <- data_mean$SA2_MAIN16[i]
extract_current <- aggregate(current_SOC, SA2_data[i,], sum, na.rm = TRUE, exact = TRUE)
extract_current <- extract_current %>%
st_as_sf() %>%
st_drop_geometry()
extract_current <- as.data.frame(extract_current)
data = cbind(data[1], extract_current)
data_fill <- rbind(data_fill, data)
print(i)
}
At some point (polygon number 98 in the loop, I receive the following error
Error in CPL_read_gdal(as.character(x), as.character(options), as.character(driver), :
negative length vectors are not allowed
I was trying at the beginning to do it for all the SA2_data in one run (without any loop) and received the same message. I've read that the processor could be running out of memory, but it doesn't make much sense since the polygon is not that big.
The data sources for these files can be found here:
sa2 shape file https://www.abs.gov.au/AUSSTATS/abs#.nsf/DetailsPage/1270.0.55.001July%202016?OpenDocument
current_SOC https://datasets.seed.nsw.gov.au/dataset/soil-carbon-sequestration-potential-with-enhanced-vegetation-cover-over-nsw
Appreciate any comment on this. Thanks!

How can I clip a shapefile to my raster using R?

I am trying to mask a raster to a shapefile boundary, but I am getting an error. How can I correctly perform this mask?
The raw data can be found here, entitled "data_for_question.txt." It is formatted so that users can copy and paste (from the web app) the text directly into an R window and generate a data frame. Otherwise, if one doesn't want to generate the data, the output raster (example_raster.tif) and shapefile (field_boundary.shp) can both also be found in the same link.
Here is what I have tried:
#Import necessary libraries
library(pacman)
p_load(sf,
spatstat,
maptools,
tidyverse,
ggplot2,
gstat,
sp,
rgdal,
raster,
spdep)
#Read shapefile
shp <- st_read("field_boundary.shp")
#Generate data to run interpolation on and project it to the desired CRS
data_sp <- SpatialPointsDataFrame(coords,
data[, c("OM", "data2")],
proj4string = CRS('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'))
#Perform an IDW interpolation:
grd <- SpatialPixels(SpatialPoints(makegrid(data_sp, n=10000)), proj4string = proj4string(data_sp)) #Generate grid for interpolation
plot(grd)
interp <- idw(formula = OM ~ 1, data_sp, grd, idp = 0.5, nmax = 12)
plot(interp) #Makes for a very pretty picture!
#Convert to raster
rast <- raster(interp)
plot(rast)
shp <- st_transform(shp, crs(rast))
#Crop and mask the raster
crop_rast <- crop(rast, shp)
crop_om <- mask(crop_rast, mask = shp)
The error occurs here:
Error in h(simpleError(msg, call)) :
error in evaluating the argument 'x' in selecting a method for function 'addAttrToGeom': sp supports Z dimension only for POINT and MULTIPOINT.
use `st_zm(...)` to coerce to XY dimensions

How to extract rasters and points?

I am working on R and creating prediction maps. In my data, I have the location coordinates.
How to extract my rasters and points?
library(randomForest)
library(caret)
library(raster)
library(raster)
library(rgdal)
##-----load data
data <- read.csv("0.10.coordinates.csv",sep=";", header = TRUE)
raster(swi.tif)
rsp.1<-raster("rsp.tif")
twi.1<-raster("twi.tif")
swi.1<-raster("swi.tif")
###load csv of 0-10cm sand,silt and clay %'s and lat/long (x,y) (in E: drive RF folder)
xy<-read.csv("0.10.coordinates.csv")
plot(swi.1)
plot(twi.1)
plot(swi.1)
plot(rsp.1)
stack(swi.1,rsp.1,twi.1,xy)
topo.brick<-brick(rsp.1,swi.1,twi.1,xy)
brick(rsp.1,twi.1,swi.1,data)
df<-extract(data,rsp.1,twi.1,swi.1)`
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘extract’ for signature ‘"data.frame", "RasterLayer"’
take a look at?raster::extract to see what inputs are required and in what order. In any case, you should create a reproducible example..
However, here an example with dummy data:
library(raster)
# with raster -------------------------------------------------------------
r <- s <- t <- raster()
r[] <- 1:ncell(r)
s[] <- sample(1:10,ncell(s),replace = T)
t[] <- runif(ncell(t))
stacked <- stack(r,s,t)
#points
xy <- cbind(-50, seq(-80, 80, by=20))
#extract
ex <- extract(stacked,xy, df=TRUE)
If the extraction takes too long, check out the terra::extract or even better a exactextractr::exact_extract.
See Elia's example, but from what I gather from your code you should be able to do
library(raster)
xy <- read.csv("0.10.coordinates.csv")
s <- stack("rsp.tif", "twi.tif", "swi.tif")
d <- extract(s, xy)`

How to select one point per raster grid cell?

I have a point shapefile ("search_effort.shp") that is highly clustered and an NDVI raster (resolution in m: 30.94948, 30.77829). I would like to subset my search_effort.shp by selecting 1 point per raster grid cell and create a new search_effort shapefile. I am using R version 4.0.3
I think I could have used Package ‘gridsample’ (in 'raster' v1.3-1), but it was removed from the CRAN repository and I would prefer not to use the archived version. Is there another way to do this in R?
I have also tried sample.grid but I do not know how to specify my raster as the grid, and have tried the following:
# NDVI raster to be used as the reference extent
NDVI_extent <-readGDAL('C:/Model_layers/NDVI.tif')
# Load the file names
layername <- "SearchEffort"
# Read in the shapefile
search_effort <- readOGR(dsn= ".", layer = layername)
plot(search_effort)
# Set the reference extent
r <- raster(NDVI_extent)
# Extract coordinates from the shapefile
search_effort#coords <- search_effort#coords[, 1:2]
#Subset points
sample.grid(search_effort, cell.size = c(30.94948, 30.77829), n = 1)
I get the following error:
"Error in validObject(.Object) : invalid class “GridTopology” object: cellsize has incorrect dimension."
I get the same error regardless of the cell.size I specify.
Example data
library(raster)
r <- raster(res=30)
values(r) <- 1:ncell(r)
x <- runif(1000,-180,180)
y <- runif(1000,-90,90)
xy <- cbind(x, y)
Solution
library(dismo)
s <- gridSample(xy, r, n=1)
Illustration
plot(as(r, "SpatialPolygons"))
points(s, col="red")
points(xy, cex=.1, col="blue")

Merge polygons and plot using spplot()

I would like to merge some regions in gadm data and then plot the map. So far I have the following:
#install.packages("sp",dependencies=TRUE)
#install.packages("RColorBrewer",dependencies=TRUE)
#install.packages("maptools",dependencies=TRUE)
library(sp)
library(maptools)
#library(RColorBrewer)
# get spatial data
con <- url("http://gadm.org/data/rda/CZE_adm2.RData")
print(load(con))
close(con)
IDs <- gadm$ID_2
IDs[IDs %in% c(11500:11521)] <- "11500"
gadm_new <- unionSpatialPolygons(gadm, IDs)
# plot map
spplot(gadm_new, "NAME_2", col.regions=col, main="Test",colorkey = FALSE, lwd=.4, col="white")
However this results in error:
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "spplot", for signature "SpatialPolygons"
Now I have no idea what can possibly fix this error.
I'm not sure about what you're trying to do here.
The error is due to the fact that spplot is used to draw spatial objects with attributes, ie with associated data. Your gadm object is of class SpatialPolygonsDataFrame, so it defines polygons and associated data that can be accessed via the slot gadm#data. When you use UnionSpatialPolygons, you only get a SpatialPolygons class object, which can be plotted with plot, but not with spplot :
IDs <- gadm$ID_2
IDs[IDs %in% c(11500:11521)] <- "11500"
gadm_new <- unionSpatialPolygons(gadm, IDs)
plot(gadm_new)
If you want to use spplot, you have to merge your associated data manually, the same way you merged your polygons, and then build back a SpatialPolygonsDataFrame. One way to do it is the following :
gadm_new <- gadm
## Change IDs
gadm_new$ID_2[gadm_new$ID_2 %in% c(11500:11521)] <- "11500"
## Merge Polygons
gadm_new.sp <- unionSpatialPolygons(gadm_new, gadm_new$ID_2)
## Merge data
gadm_new.data <- unique(gadm_new#data[,c("ID_2", "ENGTYPE_2")])
## Rownames of the associated data frame must be the same as polygons IDs
rownames(gadm_new.data) <- gadm_new.data$ID_2
## Build the new SpatialPolygonsDataFrame
gadm_new <- SpatialPolygonsDataFrame(gadm_new.sp, gadm_new.data)
Then you can use spplot to plot a map with an associated attribute :
spplot(gadm_new, "ENGTYPE_2", main="Test", lwd=.4, col="white")
Note that here I only used the ENGTYPE_2 variable of your data, not the NAME_2 variable, as I don't see the point to represent a variable where each value seems unique for each polygon.

Resources