0

I have a list named coord_pts with 4 SpatialPointsDataFrame files and a list with 14 raster. What I want is to extract the data from the 14 raster for the coordinates of each one of the SpatialpointsDataFrame files. I tried to make a nested for loop but I am only getting the output for the first object of coord_pts.

crops<-list()
extract<-list() 
 for(j in 1:length(coord_pts)){
  for(i in 1:length(Temp_raster)){
   extract[[j*i]]<-extract(Temp_raster[[i]],coord_pts[[j]], method='simple')
   crops[[j]]<-data.frame(c(extract))
  }  
   colnames(crops)<-c('MeanTemp', 'Prec', 'Temp1', 'Temp10', 'Temp11', 'Temp12', 'Temp2', 'Temp3', 'Temp4', 'Temp5', 'Temp6', 'Temp7', 'Temp8', 'Temp9')      
   }
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Sep 25 '19 at 17:29

3 Answers3

0

Basics of recursion, while not knowing your dataset..

is.deep <- function(x){
  is.list(x) | is.data.frame(x)
}
list.dive <- function(L, func = NULL, ...){
      L <- func(L, ...)
      if(!is.deep(L)){
        L
      }else{
        lapply(L,function(x){
          list.dive(x, func, ...)
        })
      }
    }

The idea is you write a function that does what you need, and then pass the list to L, and that function to func. The function will execute, test if the result is still a list or other type of object which you can iterate over, it will perform the function again until the condition is no longer met.

Carl Boneri
  • 2,632
  • 1
  • 13
  • 15
0

Always include some example data in your question. Also you probably do not need a loop, or at least not a nested loop. This is R, you should assume that loops are implicit.

In the simplest case, you make a RasterStack from your files

library(raster)
s <- stack(system.file("external/rlogo.grd", package="raster"))
coord_pts <- cbind(1:4, 1:4) * 10
extract(s, coord_pts)

#     red green blue
#[1,] 255   255  255
#[2,]  55    55   53
#[3,] 255   255  253
#[4,] 149   159  186

If you cannot make a RasterStack because the rasters do not align you could use a list, as in your question; and loop.

Temp_raster <- as.list(s)

Assuming that each list element has a single layer you can do

m <- matrix(nrow=nrow(coord_pts), ncol=length(Temp_raster))
colnames(m) <- sapply(Temp_raster, names)
for (i in 1:length(Temp_raster)) {
   m[, i] <- extract(Temp_raster[[i]], coord_pts)
}

m
#     red green blue
#[1,]  255  255  255
#[2,]   55   55   53
#[3,]  255  255  253
#[4,]  149  159  186

Or for more complex cases

x <- list()
for (i in 1:length(Temp_raster)) {
   x[[i]] <- extract(Temp_raster[[i]], coord_pts)
}

And take it from there.

Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
  • You were right, the solution was to stack it and then to run only one for loop to extract from s raster for each one of the objects in coord_pts. Cheers. – Héctor Camargo Sep 26 '19 at 15:29
  • I would say that if you can make a stack, you should not use a for loop at all --- as I showed in my answer. – Robert Hijmans Sep 26 '19 at 17:07
0

Sorry, I did not explain it well, the SpatialPointsDataFrame depending on the coordinate set are between 40 and 100 datapoints around the world and varible (HI). Like this:

Lat  Long          HI 
 -39.85000  -72.50000  0.4240000     
 -36.75000  142.10000  0.3620000    

...

The 14 raster are global data (0.5 degree res.) for annual temperature, precipitation and monthly temp. I want to get a data frame for each set of coordinates with the index and the 14 variables from the raster.

 Lat    Long    HI      temp        prec    temp1        temp2      temp3   ......
-39.85  -72.5   0.424   10.65100003 2305    15.77600002 15.2840004  13.36400032 
-36.75  142.1   0.362   14.54166676 466     20.79999924 21.1000004  18.59200096