SpatVector (terra) subset in parallel using foreach in R

738 Views Asked by At

I am trying to subset SpatVector from terra in parallel with the help of foreach .

My ultimate aim is to extract pixels of rasters from several tiles using specific polygons. The extraction of pixels works, but not the subseting of specific polygons.

Take the bellow code as a reproducible example for this problem. No message need to show up if that works.


# Libraries
library(terra)
library(foreach)
library(doParallel)

# Example vector
vector <- vect(system.file("ex/lux.shp", package="terra"))
aoi <- vector$NAME_2

# Set up cluster
threads <- 4
cl <- makeCluster(threads)
registerDoParallel(cl)

# Parallel loop
extraction <- foreach(i = 1:length(aoi),
                      .packages = c("terra"),
                      .inorder = F) %dopar% {
                        
                        IDoi <- aoi[i]
                        
                        tile_vector <- subset(vector, 
                                              NAME_2 == IDoi, 
                                              NAME_2,
                                              NSE = TRUE)
                        
                      }

# Stop cluster
stopCluster(cl)
gc()

The resulting error message says Error in { : task 1 failed - "error in evaluating the argument 'x' in selecting a method for function 'as.list': NULL value passed as symbol address"

Any idea?

1

There are 1 best solutions below

0
Chris On

Before I parallelized this, I'd get my loop working in a simple for loop, as that is where the error propagates. I'm assuming you want 12 polygons returned rather than overwriting and simply returning the last:

aoi <- vector$NAME_2
tile_vector3 <- list()
for (i in 1:length(aoi)) {
    tile_vector3[[i]] <- terra::subset(vector,
    vector$NAME_2 == aoi[i],
    vector$NAME_2,
    NSE = FALSE
    )
  }
> tile_vector3
[[1]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.826232, 6.16085, 49.94611, 50.18162  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[2]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.967658, 6.315773, 49.78479, 49.98745  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[3]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.746118, 6.029145, 49.69933, 49.89461  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[4]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 6.092986, 6.239243, 49.87053, 49.98416  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[5]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.74414, 6.05839, 49.85149, 50.03632  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[6]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 6.242424, 6.528252, 49.72324, 49.85403  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[7]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 6.222746, 6.381701, 49.46498, 49.62416  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[8]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 6.169137, 6.516485, 49.58699, 49.75016  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[9]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.852082, 6.098635, 49.5487, 49.72005  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[10]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.810482, 6.236431, 49.44781, 49.59285  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[11]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.998247, 6.312236, 49.51847, 49.69196  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

[[12]]
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 1, 0  (geometries, attributes)
 extent      : 5.979951, 6.278229, 49.68504, 49.83112  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 

Wrapping things deeper can obscure error messages, though in the above, it was pointing to subset, even as wrapped in foreach & %dopar%. terra::subset suggests NSE=FALSE for wrapped evaluation. And perhaps the wrapping within { explains why, in my case, 'NAME_2' wasn't being found, even after establishing 'terra::subset('. And it is just as likely I've misinterpreted your needs, but I'd move on to parallel once these issues were addressed.