Extraigo el área y el porcentaje de cobertura de diferentes tipos de uso de la tierra de un ráster basado en varios miles de límites de polígonos. Descubrí que la función de extracción funciona mucho más rápido si recorro cada polígono individual y recorto y luego enmascaro el ráster hasta el tamaño del polígono en particular. Sin embargo, es bastante lento, y me pregunto si alguien tiene alguna sugerencia para mejorar la eficiencia y la velocidad de mi código.
Lo único que he encontrado relacionado con esto es esta respuesta de Roger Bivand, quien sugirió usar GDAL.open()
y GDAL.close()
así como getRasterTable()
y getRasterData()
. Los investigué, pero he tenido problemas con gdal en el pasado y no lo sé lo suficiente como para saber cómo implementarlo.
Ejemplo reproducible:
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)
Método más rápido hasta ahora
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
Procesamiento en paralelo
El procesamiento paralelo reduce el tiempo del usuario a la mitad, pero niega el beneficio al duplicar el tiempo del sistema. Raster usa esto para la función de extracción, pero desafortunadamente no para la función de recorte o máscara. Desafortunadamente, esto deja una cantidad ligeramente mayor de tiempo total transcurrido debido a la "espera" del "IO".
beginCluster( detectCores() -1) #use all but one core
ejecutar código en múltiples núcleos:
user system elapsed
23.31 0.68 42.01
luego termina el clúster
endCluster()
Método lento: el método alternativo para hacer un extracto directamente desde la función de trama tarda mucho más, y no estoy seguro acerca de la gestión de datos para obtener el formato que quiero:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14