Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sum a undetermined number of rasters with do.call and raster package

Tags:

r

raster

in the frame of soil mapping, I need to sum a undetermined number of rasters. I try to do it using the 'raster' package and the 'do.call' function. However, if the 'sum' function can sum up to many rasters, doing the same operation using do.call leads to an error. What am I doing wrong ?

library(raster)

r1 <- raster(ncol=10, nrow=10)   # dataset for test
values(r1) <- runif(ncell(r1))
r2 <- raster(ncol=10, nrow=10)
values(r2) <- runif(ncell(r2))
r3 <- raster(ncol=10, nrow=10)
values(r3) <- runif(ncell(r3))

sum(r1,r2,r3)    # works nice

do.call(sum,list(r1,r2,r3))

##Erreur dans as.character(sys.call()[[1L]]) : 
##cannot coerce type 'builtin' to vector of type 'character'

Thank you for you help,

François

like image 509
fstevens Avatar asked Jan 10 '13 15:01

fstevens


2 Answers

You could use Reduce and + to compute the sum from a list:

Reduce("+",list(r1,r2,r3))
class       : RasterLayer 
dimensions  : 10, 10, 100  (nrow, ncol, ncell)
resolution  : 36, 18  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : in memory
names       : layer 
values      : 0.4278222, 2.476625  (min, max)

As for why your original command doesn't work, that is somewhat perplexing. Supplying the function name as a character seems to work:

do.call("sum",list(r1,r2,r3))
class       : RasterLayer 
dimensions  : 10, 10, 100  (nrow, ncol, ncell)
resolution  : 36, 18  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : in memory
names       : layer 
values      : 0.4278222, 2.476625  (min, max)

But this isn't required in other contexts:

do.call(sum,list(1,2,3))
[1] 6
like image 186
James Avatar answered Nov 12 '22 08:11

James


I do not know why this does not work (without quotes around sum as James points out), perhaps this is a bug (or a feature) related with "sum" being a member of the S4 Summary group generic; other members such as "max" and "prod" have the same behavior.

Either way, but instead of

 do.call("sum", list(r1,r2,r3))

you can also do

 sum(stack(r1,r2,r3))

or if you have already have a list

 sum(stack(list(r1,r2,r3)))
like image 37
Robert Hijmans Avatar answered Nov 12 '22 09:11

Robert Hijmans