Sto estraendo l'area e la percentuale di copertura di diversi tipi di uso del suolo da un raster basato su diverse migliaia di confini poligonali. Ho scoperto che la funzione di estrazione funziona molto più velocemente se eseguo l'iterazione attraverso ogni singolo poligono e ritaglio, quindi maschera il raster fino alla dimensione del particolare poligono. Tuttavia, è piuttosto lento e mi chiedo se qualcuno abbia qualche suggerimento per migliorare l'efficienza e la velocità del mio codice.
L'unica cosa che ho trovato correlata a questa è questa risposta di Roger Bivand che ha suggerito di usare GDAL.open()
e GDAL.close()
così come getRasterTable()
e getRasterData()
. Ho esaminato quelli, ma ho avuto problemi con gdal in passato e non lo conosco abbastanza bene da saperlo implementare.
Esempio riproducibile:
library(maptools) ## For wrld_simpl
library(raster)
## Example SpatialPolygonsDataFrame
data(wrld_simpl) #polygon of world countries
bound <- wrld_simpl[1:25,] #name it this to subset to 25 countries and because my loop is set up with that variable
## Example RasterLayer
c <- raster(nrow=2e3, ncol=2e3, crs=proj4string(wrld_simpl), xmn=-180, xmx=180, ymn=-90, ymx=90)
c[] <- 1:length(c)
#plot, so you can see it
plot(c)
plot(bound, add=TRUE)
Metodo più veloce finora
result <- data.frame() #empty result dataframe
system.time(
for (i in 1:nrow(bound)) { #this is the number of polygons to iterate through
single <- bound[i,] #selects a single polygon
clip1 <- crop(c, extent(single)) #crops the raster to the extent of the polygon, I do this first because it speeds the mask up
clip2 <- mask(clip1,single) #crops the raster to the polygon boundary
ext<-extract(clip2,single) #extracts data from the raster based on the polygon bound
tab<-lapply(ext,table) #makes a table of the extract output
s<-sum(tab[[1]]) #sums the table for percentage calculation
mat<- as.data.frame(tab)
mat2<- as.data.frame(tab[[1]]/s) #calculates percent
final<-cbind(single@data$NAME,mat,mat2$Freq) #combines into single dataframe
result<-rbind(final,result)
})
user system elapsed
39.39 0.11 39.52
Elaborazione parallela
L'elaborazione parallela ha dimezzato il tempo dell'utente, ma ha annullato il vantaggio raddoppiando il tempo di sistema. Raster lo utilizza per la funzione di estrazione, ma sfortunatamente non per la funzione di ritaglio o maschera. Sfortunatamente, questo lascia una quantità leggermente maggiore di tempo totale trascorso a causa di "aspettare" dall'IO.
beginCluster( detectCores() -1) #use all but one core
eseguire codice su più core:
user system elapsed
23.31 0.68 42.01
quindi termina il cluster
endCluster()
Metodo lento: il metodo alternativo per eseguire un estratto direttamente dalla funzione raster richiede molto più tempo e non sono sicuro della gestione dei dati per ottenerlo nella forma che desidero:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14