Q:

standard deviation function throws error when na.rm=TRUE while using calc() in raster package

I am attempting to calculate a simple standard deviation function from a raster brick object using the calc() function in the raster package. I have missing values and want them to be excluded. I think I should be able to exclude them by including the na.rm=TRUE argument, but when I do I receive an error: 
Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) :
cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments? 

Below I have created a trivial example to demonstrate (note: I have written my own standard deviation function for a population as the built-in sd function is for sample standard deviation. However, it throws the same error)
r <- raster(nrow=10, ncol=10)
r1 <- setValues(r, 5)
r2 <- setValues(r, 10)
r3 <- setValues(r, 11)
r4 <- setValues(r, NA)
s <- stack(r1, r2,r3,r4)

pop.sd=function(x)(sqrt(var(x)*(length(x)-1)/length(x)))

stdv<-calc(s, fun=pop.sd, na.rm=T)

a raster layer full of 2.624 should be returned. Any thoughts?

A:

It is because your function does not take the argument na.rm. The help file for calc says na.rm if supported by 'fun'. The following function fixes this:
pop.sd=function(x, na.rm){
  v = var(x,na.rm = na.rm)
  l = if(na.rm) sum(!is.na(x)) else length(x)
  sqrt(v*(l-1)/l)
}

stdv<-calc(s, fun=pop.sd, na.rm=TRUE)

The if statement makes sure that the length of x being used is correct for the adjustment, also stripping out NA values.
You can also pass additional arguments to functions using the ... notation. So you could have 
pop.sd=function(x, ...){
  v = var(x,...)
  l = sum(!is.na(x))
  sqrt(v*(l-1)/l)
}

In this case since var returns NA if there are NA values that haven't been stripped out the need to check the same condition for length is not necessary. 

