[R-sig-Geo] How to speed up calculating proportion of landcover classes falling within larger pixels?

Lyndon Estes lyndon.estes at gmail.com
Tue Aug 28 22:06:01 CEST 2012


Hi Robert,

Just wanted to report back on the solution you gave me, which worked
perfectly as you wrote it.

>> library(raster)
>>
>> library(rgdal)
>>
>> r <- raster(ncol=10, nrow=10)  # EP MODIS pixels
>> eplc <- raster()
>> set.seed(0)
>> eplc[] <- round(  runif(ncell(eplc)) + 3)
>> eplc[10000:11000] <- NA
>>
>> bs <- blockSize(r, minblocks = 200)  # Calculate size of rows to work on
>>
>> # Output datasets
>> rcl3 <- writeStart(r, "lc_class3.tif", overwrite = TRUE)
>> rcl4 <- writeStart(r, "lc_class4.tif", overwrite = TRUE)
>> rtot <- writeStart(r, "lc_aall.tif", overwrite = TRUE)
>>
>> # Start processing loop
>> for(i in 1:bs$n) {
>>    print(paste("Iteration", i))
>>    # extent of this (modis) block
>>    e <- extent(xmin(r), xmax(r), yFromRow(r, bs$row[i]+bs$nrows[i]-1) - 0.5 * yres(r), yFromRow(r, bs$row[i])+0.5 * yres(r))
>>
>>    vo1 <- vo2 <- vo3 <- rep(NA, bs$nrows[i] * ncol(r))
>>
>>    int <- intersect(e, extent(eplc))
>>    if (!is.null(int)) {
>>    b <- crop(eplc, int)
>>    xy <- xyFromCell(b, 1:ncell(b))
>>    mc <- cellFromXY(r, xy)
>>
>>            # here I use table, there could be other ways (e.g. tapply) to achieve the below
>> v <- table(mc, getValues(b))
>>    cells <- as.integer(rownames(v))
>> modcells <- cellFromRowCol(r, bs$row[i], 1) : cellFromRowCol(r, bs$row[i]+bs$nrows[i]-1, ncol(r))
>> m <- match(cells, modcells)
>>
>> cn <- as.integer(colnames(v))
>> if (3 %in% cn) {
>> vo1[m] <- v[, '3']
>> }
>> if (4 %in% cn) {
>> vo2[m] <- v[, '4']
>> }
>> vo3[m] <- apply(v, 1, sum)
>> rcl3 <- writeValues(rcl3, vo1, bs$row[i])  # Write out sum class 3
>> rcl4 <- writeValues(rcl4, vo2, bs$row[i])  # Write out sum class 4
>> rtot <- writeValues(rtot, vo3, bs$row[i])  # Write sum total pixels
>>   }
>> }
>>
>> rcl3 <- writeStop(rcl3)
>> rcl4 <- writeStop(rcl4)
>> rtot <- writeStop(rtot)
>>

I tweaked it to run with my actual grids, and it took only 6 minutes
to run, producing 4 outputs each with the following characteristics:

class       : RasterLayer
dimensions  : 1593, 1901, 3028293  (nrow, ncol, ncell)
resolution  : 231.6564, 231.6564  (x, y)
extent      : 3230680, 3671058, -1712867, -1343839  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181
+b=6371007.181 +units=m +no_defs
values      :
layer name  : eplc_ag
min value   : 0
max value   : 64

Needless to say, that is an enormous improvement on the 3 day run I
had using the extract approach.

Thanks again for the advice and for the raster package.

Cheers, Lyndon



More information about the R-sig-Geo mailing list