Estou extraindo a área e a porcentagem de cobertura de diferentes tipos de uso da terra de uma varredura baseada em vários milhares de limites de polígonos. Descobri que a função extrair funciona muito mais rápido se eu percorrer cada polígono individual e cortar, mascarar a varredura até o tamanho do polígono específico. No entanto, é bem lento, e estou me perguntando se alguém tem alguma sugestão para melhorar a eficiência e a velocidade do meu código.
A única coisa que encontrei relacionada a isso é essa resposta de Roger Bivand, que sugeriu o uso de GDAL.open()
e GDAL.close()
como getRasterTable()
e getRasterData()
. Eu olhei para eles, mas tive problemas com o gdal no passado e não o conheço o suficiente para saber como implementá-lo.
Exemplo reproduzível:
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 mais rápido até agora
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
Processamento paralelo
O processamento paralelo reduziu o tempo do usuário pela metade, mas negou o benefício dobrando o tempo do sistema. A varredura usa isso para a função de extração, mas infelizmente não para a função de corte ou máscara. Infelizmente, isso deixa uma quantidade ligeiramente maior de tempo total decorrido devido à "espera" do "IO".
beginCluster( detectCores() -1) #use all but one core
executar código em vários núcleos:
user system elapsed
23.31 0.68 42.01
então termine o cluster
endCluster()
Método lento: o método alternativo de fazer uma extração diretamente da função raster demora muito mais e não tenho certeza sobre o gerenciamento de dados para obtê-lo da forma que desejo:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14