Ich extrahiere die Fläche und die prozentuale Abdeckung verschiedener Landnutzungstypen aus einem Raster, das auf mehreren tausend Polygongrenzen basiert. Ich habe festgestellt, dass die Extrahierungsfunktion viel schneller funktioniert, wenn ich durch jedes einzelne Polygon iteriere und es beschneide und dann das Raster auf die Größe des jeweiligen Polygons verkleinere. Trotzdem ist es ziemlich langsam und ich frage mich, ob jemand Vorschläge zur Verbesserung der Effizienz und Geschwindigkeit meines Codes hat.
Das einzige, was ich im Zusammenhang damit gefunden habe, ist die Antwort von Roger Bivand, der die Verwendung von GDAL.open()
und GDAL.close()
sowie getRasterTable()
und vorschlug getRasterData()
. Ich habe mir diese angeschaut, hatte aber in der Vergangenheit Probleme mit gdal und kenne sie nicht gut genug, um zu wissen, wie man sie umsetzt.
Reproduzierbares Beispiel:
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)
Schnellste Methode bisher
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
Parallelverarbeitung
Durch die parallele Verarbeitung wurde die Benutzerzeit halbiert, der Vorteil jedoch durch die Verdoppelung der Systemzeit zunichte gemacht. Raster verwendet dies für die Extraktionsfunktion, aber leider nicht für die Zuschneide- oder Maskenfunktion. Leider verbleibt dadurch etwas mehr Gesamtzeit, da das "IO" "herumwartet".
beginCluster( detectCores() -1) #use all but one core
Code auf mehreren Kernen ausführen:
user system elapsed
23.31 0.68 42.01
Beenden Sie dann den Cluster
endCluster()
Langsame Methode: Die alternative Methode zum Erstellen eines Extrakts direkt aus der Rasterfunktion dauert viel länger, und ich bin nicht sicher, ob die Datenverwaltung das gewünschte Format annimmt:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14