ali
ali

Reputation: 29

Loop to extract specific raster/spatial point pairs

I have many point shapefiles which are not overlapping, which I would like to attribute to analagous rasters, also not overlapping. I would like to attribute these points with the raster data. For some of the raster data types with which I am doing this, I was able to merge the rasters first, then attribute. However, my last sets of raster data do not have the same origin, so I was unable to merge/mosaic them. I am trying to instead attribute the points to rasters without merging the rasters. This would require me to use extract() on specific spatial point - raster pairs. I have named each spatial point file with a unique 4-letter name, which is also part of the raster name I would like the extract() to use.

I've created a reproducible example below that mimics my data and problem. Can anyone make suggestions on how I could code the looping for extract() to get the spatial point file to extract to the analagously-named raster?

Alternatively, if it is better/possible to combine all the spatial points and just loop through extracting all the rasters, then managing the data so that all extracted values are in one vector or column of a dataframe, perhaps that would be better.

I am using RStudio 1.2.1335

Note: I posted this question to GIS Stack Exchange, but did not receive any answers, hope cross-posting is ok.

library(raster)
library(sp)   

#create point shapefiles
loc1 <- data.frame(x = c(-100,-90, -80, -70),
                  y = c(-100,-90, -80, -70))
loc2 <- data.frame(x = c(-100,-90, -80, -70),
                   y = c(100,90, 80, 70))
loc3 <- data.frame(x = c(100,90, 80, 70),
                   y = c(100,90, 80, 70))
coordinates(loc1) <- ~x+y
sp.loc1<- SpatialPoints(loc1,proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))
coordinates(loc2) <- ~x+y
sp.loc2<- SpatialPoints(loc2,proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))
coordinates(loc3) <- ~x+y
sp.loc3<- SpatialPoints(loc3,proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs"))
plot(sp.loc1)

#create rasters which have a common part of the naming convention of point shapefiles targeting for attribution
loc1_blablabla<- raster(xmn=-200, xmx=0, ymn=-200, ymx=0)
loc1_blablabla
ncell(loc1_blablabla)
#it has 64800 cells
values(loc1_blablabla)<-1:64800
plot(loc1_blablabla, add=TRUE)
plot(sp.loc1, add=TRUE)
loc2_blablabla<- raster(xmn=-200, xmx=0, ymn=0, ymx=200)
values(loc2_blablabla)<-1:64800
loc3_blablabla<- raster(xmn=0, xmx=200, ymn=0, ymx=200)
values(loc3_blablabla)<-1:64800

#plot all, but first create extent poly
#borrowed some code from here:https://gis.stackexchange.com/questions/206929/r-create-a-boundingbox-convert-to-polygon-class-and-plot/206952
library(rgeos)
ext.box<-rgeos::bbox2SP(n=250, s=-250, w=-250, e=250)
plot(ext.box)
plot(loc1_blablabla, add=TRUE)
plot(loc2_blablabla, add=TRUE)
plot(loc3_blablabla, add=TRUE)
plot(sp.loc1, add=TRUE)
plot(sp.loc2, add=TRUE)
plot(sp.loc3, add=TRUE)

#now attempt to extract raster values at points for multiple non-overlapping point and raster files ie. extract(loc1_blablabla, loc1)
#try lapply as in: https://stackoverflow.com/questions/59164538/create-a-loop-to-extract-data-from-multiple-raster
#create list as below, however, with my real data I would use list.files()
loc.list<-list(loc1,loc2,loc3)
rast.list<-list(loc1_blablabla,loc2_blablabla,loc3_blablabla)
attr.data<-lapply(rastlist.extract,loc.list)
#this doesn't work -- i think I need coordinates as the last term, not a list of spatial points

#also tried a for loop, but this gave error:  "Error in (function (classes, fdef, mtable): unable to find an inherited method for function ‘shapefile’ for signature ‘"list"’"
for (i in 1:length(loc.list)) {
  #this reads in each spatialpoint file and assigns each sp's name to the variable 'sp.name'
  sp.name<-shapefile(loc.list[i]) 
  attr.data<-data.frame(coordinates(sp.name),
                             extract(rast.list[grep(sp.name,rast.list)],sp.name))
  #eventually add this line to affix the new vector attr.data to the coordinates for each plot:  names(attr.data)<-c("x","y","raster.value")
}

Upvotes: 0

Views: 746

Answers (1)

Robert Hijmans
Robert Hijmans

Reputation: 47401

Can't you match them by their filenames? If so, that is what you should do. What you are proposing is possible in more than one way, but it seems you are trying to solve problem of you own creation --- and it could be much easier to avoid all that.

I would read in the files using

library(raster)
r <- lapply(raster_file_names, raster)
s <- lapply(shapefile_names, shapefile)

And then loop over these

With your example data

library(raster)
p1 <- SpatialPoints(cbind(x = c(-100,-90, -80, -70), y = c(-100,-90, -80, -70)))
p2 <- SpatialPoints(cbind(x = c(-100,-90, -80, -70), y = c(100,90, 80, 70)))
p3 <- SpatialPoints(cbind(x = c(100,90, 80, 70), y = c(100,90, 80, 70)))
pts <- list(p1, p2, p3)

r1 <- raster(xmn=-200, xmx=0, ymn=-200, ymx=0, vals=1:64800)
r2 <- raster(xmn=-200, xmx=0, ymn=0, ymx=200, vals=1:64800)
r3 <- raster(xmn=0, xmx=200, ymn=0, ymx=200, vals=1:64800)
ras <- list(r1, r2, r3)

e <- list()
for (i in 1:length(ras)) {
    e[[i]] <- extract(ras[[i]], pts[[i]])
}
e
#[[1]]
#[1] 32581 29359 26137 22915
#[[2]]
#[1] 32581 35839 39097 42355
#[[3]]
#[1] 32581 35803 39025 42247

Upvotes: 0

Related Questions