[R] Passing arguments between S4 methods fails within a function:bug? example with raster package.

Niels Richard Hansen Niels.R.Hansen+lists at math.ku.dk
Thu Aug 26 17:43:32 CEST 2010


Joris,

I looked at the problem. Here is a minimal example reproducing
the error

setGeneric("myplus",function(x,y,...) standardGeneric("myplus"))
setMethod("myplus",c(x="numeric",y="numeric"),
           function(x,y,z=0) x+y+z
           )
setMethod("myplus",c(x="numeric",y="list"),
           function(x,y,...) callGeneric(x,unlist(y),...)
           )

myplus(1,1)   ## 2; OK
myplus(1,1,1) ## 3; OK

myplus(1,list(1)) ## 2; OK
myplus(1,list(1),z=1) ## 3; OK

a.c1 <- 1
myplus(1,list(1),z=a.c1) ## 3; OK

test <- function(x,y) {
   a.c <- 1    ## Problem occurs when using '.' in variable name
   myplus(a,y,z=a.c)
}

test(1,list(1)) ## error
test(1,1)  ## 3; OK

It looks like a bug. I went through all environments from inside
the call of myplus("numeric","numeric") and a.c is nicely located
in parent.frame(6) with the value 1. However, when it has a '.' (dot)
in the variable name, the variable is not found. If it has a name
without a '.' (dot) there is no problem:

test <- function(x,y) {
   a <- 1
   myplus(a,y,z=a)
}

test(1,list(1)) ## 3; OK

- Niels

On 26/08/10 15.32, Joris Meys wrote:
> Dear all,
>
> This problem came up initially while debugging a function, but it
> seems to be a more general problem of R. I hope I'm wrong, but I can't
> find another explanation. Let me illustrate with the raster package.
>
> For an object "RasterLayer" (which inherits from Raster), there is a
> method xyValues defined with the signature
> (object="RasterLayer",xy="matrix"). There is also a method with
> signature (object="Raster",xy="vector"). The only thing this method
> does, is change xy into a matrix and then pass on to the next method
> using callGeneric again. Arguments are passed.
>
> Now this all works smoothly, as long as you stay in the global environment :
> require(raster)
>
> a<- raster()
> a[]<- 1:ncell(a)
>
> origin<- c(-80,50)
> eff.dist<- 100000
>
> unlist(xyValues(a,xy=origin,buffer=eff.dist))
> [1] 14140 14141 14500 14501
>
> Now let's make a very basic test function :
>
> test<- function(x,orig.point){
>      eff.distance<- 100000
>      p<- unlist(xyValues(x,xy=orig.point,buffer=eff.distance))
>      return(p)
> }
>
> This gives the following result :
>> test(a,origin)
> Error in .local(object, xy, ...) : object 'eff.distance' not found
>
> huh? Apparently, eff.distance got lost somewhere in the parsetree (am
> I saying this correctly?)
>
> The funny thing is when we change origin to a matrix :
>> origin<- matrix(origin,ncol=2)
>
>> unlist(xyValues(a,xy=origin,buffer=eff.dist))
> [1] 14140 14141 14500 14501
>
>> test(a,origin)
> [1] 14140 14141 14500 14501
>
> It all works again! So something goes wrong with passing the arguments
> from one method to another using callGeneric. Is this a bug in R or am
> I missing something obvious?
>
> The relevant code from the raster package :
>
> setMethod("xyValues", signature(object='Raster', xy='vector'),
> 	function(object, xy, ...) {
> 		if (length(xy) == 2) {
> 			callGeneric(object, matrix(xy, ncol=2), ...)
> 		} else {
> 			stop('xy coordinates should be a two-column matrix or data.frame,
> or a vector of two numbers.')
> 		}
> 	} )
>
> setMethod("xyValues", signature(object='RasterLayer', xy='matrix'),
> 	function(object, xy, method='simple', buffer=NULL, fun=NULL, na.rm=TRUE) {
>
> 		if (dim(xy)[2] != 2) {
> 			stop('xy has wrong dimensions; it should have 2 columns' )
> 		}
>
> 		if (! is.null(buffer)) {
> 			return( .xyvBuf(object, xy, buffer, fun, na.rm=na.rm) )
> 		}
>
> 		if (method=='bilinear') {
> 			return(.bilinearValue(object, xy))
> 		} else if (method=='simple') {
> 			cells<- cellFromXY(object, xy)
> 			return(.readCells(object, cells))
> 		} else {
> 			stop('invalid method argument. Should be simple or bilinear.')
> 		}
> 	}	
> )	
>
>
>

-- 
Niels Richard Hansen                     Web:   www.math.ku.dk/~richard	
Associate Professor			 Email: Niels.R.Hansen at math.ku.dk
Department of Mathematical Sciences	        nielsrichardhansen at gmail.com
University of Copenhagen		 Skype: nielsrichardhansen.dk	
Universitetsparken 5			 Phone: +45 353 20783 (office)	
2100 Copenhagen Ø			        +45 2859 0765 (mobile)
Denmark



More information about the R-help mailing list