Skip to content

Bioclimatic variables - wettest quarter

11 messages · Jacob van Etten, Brian, Robert J. Hijmans

#
Hello All,

I am attempting to reproduce the bioclimatic (Worldclim, Hijmans et al
2005) variables with the raster package and I am stuck on the group
"temp of driest quarter" etc. variables.
I am attempting it with the function "overlay" ("raster" package).

Here is how it looks:
# To know the first month of the wettest quarter
maxmonth<- function(a,b,d,e,f,g,i,j,k,l,m,n){
                     o<- sum(c(a,b,d))
                     p<- sum(c(b,d,e))
                     r<- sum(c(d,e,f))
                     u<- sum(c(e,f,g))
                     v<- sum(c(f,g,i))
                     w<- sum(c(g,i,j))
                     x<- sum(c(i,j,k))
                     y<- sum(c(j,k,l))
                     z<- sum(c(k,l,m))
                     aa<- sum(c(l,m,n))
                     ab<- sum(c(m,n,a))
                     ac<- sum(c(n,a,b))
                     ad<- which.max(c(o,p,r,u,v,w,x,y,z,aa,ab,ac))
                     return(ad)}
# works: 2nd element (month) is the beginning of the wettest quarter
[1] 2
mon_stac<- stack(paste(pc_clim,"",y,"_prec",1:12,".asc", sep=""))
# Now attempt it
avg<- overlay(mon_stac, fun=maxmonth)
Error in .overlayList(rasters, fun = fun, filename = filename, ...) :
   cannot use this formula; lenghts do not match

# How about manually?
a<- raster(paste(pc_clim,"",y,"_prec",1,".asc", sep=""))
b<- raster(paste(pc_clim,"",y,"_prec",2,".asc", sep=""))
d<- raster(paste(pc_clim,"",y,"_prec",3,".asc", sep=""))
e<- raster(paste(pc_clim,"",y,"_prec",4,".asc", sep=""))
f<- raster(paste(pc_clim,"",y,"_prec",5,".asc", sep=""))
g<- raster(paste(pc_clim,"",y,"_prec",6,".asc", sep=""))
i<- raster(paste(pc_clim,"",y,"_prec",7,".asc", sep=""))
j<- raster(paste(pc_clim,"",y,"_prec",8,".asc", sep=""))
k<- raster(paste(pc_clim,"",y,"_prec",9,".asc", sep=""))
l<- raster(paste(pc_clim,"",y,"_prec",10,".asc", sep=""))
m<- raster(paste(pc_clim,"",y,"_prec",11,".asc", sep=""))
n<- raster(paste(pc_clim,"",y,"_prec",12,".asc", sep=""))

avg<- overlay(a,b,d,e,f,g,i,j,k,l,m,n, fun=maxmonth)
Error in .overlayList(rasters, fun = fun, filename = filename, datatype
= datatype,  :
   cannot use this formula; lenghts do not match

Also doesn't work...
[1] 12
I have 12 rasters being fed into overlay, but it won't buy it.
I think that my first step is to know the first month of the wettest
month. Once I can do that I can do it for temperature as well.

Thanks and Regards,
Brian
#
Brian,

The problem is that the the function needs to be either vectorized
(return a vector when the input consists of vectors), or appropriate
for apply (e.g. 'max'). I shall make this clearer in the help file.

You could make your function work by doing

 o<- a + b + d
 p<- b + d + e
 etc.
?ad <- calc(stack(o,p,r,u,v,w,x,y,z,aa,ab,ac), fun= which.max)
 return(ad)

or avoid the overlay function: and use map algebra

 o<- sum(a,b,d)
 p<- sum(b,d,e)
 r<- sum(d,e,f)
etc.
 s <- stack(o,p,r,u,v,w,x,y,z,aa,ab,ac)
 x <- calc(s, which.max)

Finally, the computation of bioclimatic variables has been implemented
(but not extensively tested; please provide feedback if you use it) in
the 'biovars' function in the 'dismo' package.

see
getMethod(biovars, c('Raster', 'Raster', 'Raster'))
getMethod(biovars, c('matrix', 'matrix', 'matrix'))

for its implenentation

Robert
On Sun, Nov 7, 2010 at 4:40 PM, Brian Oney <zenlines at gmail.com> wrote:
#
Hello Robert,

Thank you for the suggestions.
The first one:
mon_stac <- stack(paste(pc_clim,"1975_prec",1:12,".asc", sep=""))
plot(mon_stac * 10) # gives me twelve plots of horrendous amounts of rain
  maxmonth <- function(a,b,d,e,f,g,i,j,k,l,m,n){
+                     o <- a + b + d
+                     p <- b + d + e
+                     r <- d + e + f
+                     u <- e + f + g
+                     v <- f + g + i
+                     w <- g + i + j
+                     x <- i + j + k
+                     y <- j + k + l
+                     z <- k + l + m
+                     aa <- l + m + n
+                     ab <- m + n + a
+                     ac <- n + a + b
+                     #ad <- which.max(c(o,p,r,u,v,w,x,y,z,aa,ab,ac))
+                     ad <- calc(stack(o,p,r,u,v,w,x,y,z,aa,ab,ac), fun= 
which.max)
+                     return(ad)}
 >
 > avg <- overlay(mon_stac, fun=maxmonth)
Error in rep.int(names(x), lapply(x, length)) :
   no function to return from, jumping to top level
Error in .overlayList(rasters, fun = fun, filename = filename, ...) :
   cannot use this formula

When I use uncomment the which.max attempt above, I still get the same
"Error in .overlayList(rasters, fun = fun, filename = filename, ...) :
   cannot use this formula; lenghts do not match" error.


In trying it manually, with map algebra:

a <- raster(paste(pc_clim,"1975_prec",1,".asc", sep=""))
b <- raster(paste(pc_clim,"1975_prec",2,".asc", sep=""))
d <- raster(paste(pc_clim,"1975_prec",3,".asc", sep=""))
e <- raster(paste(pc_clim,"1975_prec",4,".asc", sep=""))
f <- raster(paste(pc_clim,"1975_prec",5,".asc", sep=""))
g <- raster(paste(pc_clim,"1975_prec",6,".asc", sep=""))
i <- raster(paste(pc_clim,"1975_prec",7,".asc", sep=""))
j <- raster(paste(pc_clim,"1975_prec",8,".asc", sep=""))
k <- raster(paste(pc_clim,"1975_prec",9,".asc", sep=""))
l <- raster(paste(pc_clim,"1975_prec",10,".asc", sep=""))
m <- raster(paste(pc_clim,"1975_prec",11,".asc", sep=""))
n <- raster(paste(pc_clim,"1975_prec",12,".asc", sep=""))

o <- a + b + d
p <- b + d + e
r <- d + e + f
u <- e + f + g
v <- f + g + i
w <- g + i + j
x <- i + j + k
y <- j + k + l
z <- k + l + m
# Try it this this to see if the double character object name are the 
problem.
A <- l + m + n
B <- m + n + a
E <- n + a + b
# I get the following:
ad <- calc(stack(o,p,r,u,v,w,x,y,z,A,B,E), fun= which.max)
#Error in .local(x, values) : values must be numeric, integer or logical.

# Try stacking it:
G <- stack(o,p,r,u,v,w,x,y,z,A,B,E)
ad <- calc(G, fun=which.max)
#Error in .local(x, values) : values must be numeric, integer or logical.

Jacob made some suggestions that also produced a similar error.

Just in case:
 > sessionInfo()
R version 2.11.0 (2010-04-22)
i386-pc-mingw32

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United 
States.1252    LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
  [1] rgdal_0.6-27    dismo_0.5-6     rJava_0.8-7     raster_1.6-10   
maps_2.1-3      gpclib_1.5-1    maptools_0.7-34 lattice_0.18-5  
sp_0.9-64       foreign_0.8-40

loaded via a namespace (and not attached):
[1] grid_2.11.0  tools_2.11.0

My extent is western North America from Canada to Mexico with a huge 
amount of NA cells over the ocean, if this helps.
Thank you for the help.

Cheers,
Brian
#
Hi Brian,

This:
does not work because overlay requires multiple (at least 2) Raster
objects. In your case RasterLayer objects

avg <- overlay(a, b, c, etc... , fun=maxmonth)

An alternative would be to use the list of RasterLayers in the
RasterStack and the do.call mechanism:

avg <- do.call(overlay, c(mon_stack at layers, fun=maxmonth))

After fixing the which.max problem as Jacob indicated. I have also
fixed dismo::biovars to deal with that.

Robert
On Mon, Nov 8, 2010 at 5:29 PM, Brian Oney <zenlines at gmail.com> wrote: