Skip to content

Default argument value for "["

5 messages · Iago Mosqueira, John Chambers

#
Dear all,

After installing R 2.4.0, a definition of "[" for an S4 class has
stopped working as the default for drop in the generic, TRUE, appears to
override the default in the method

The method is defined for demonstration purposes as

setMethod("[", signature(x="FLQuant"),
	function(x, i="missing", j="missing", k="missing", l="missing",
		m="missing", ..., drop=FALSE) {

		print(drop)
	}
)

When called as

new('FLQuant')[1,]

drop is TRUE, instead of FALSE. Am I missing something? Has there been a
change in R 2.4.0 of relevance here? I could not find it in the NEWS
file.

Many thanks,


Iago Mosqueira
#
I think the problem in your case comes from the mechanism used to handle 
non-standard argument lists; notice that you have added 3 new 
arguments.  If you look at the body of the resulting method you will see 
that the mechanism used to handle this (defining a function .local) 
fails to copy the default value from the method, as in the simpler 
example below:

 > setMethod("[", c("mm"), function(x, i, j, k..., drop=FALSE)browser())
[1] "["
 > selectMethod("[", "mm")
Method Definition:

function (x, i, j, ..., drop = TRUE)
{
    .local <- function (x, i, j, k..., drop = FALSE)
    browser()
    .local(x, i, j, ..., drop = drop)
}


We can probably fix this.  Meanwhile, the workaround is to use the same 
mechanism yourself, but get the  default value right.  Define your 
method as a function (like the .local you see when printing the current 
method) and then define a method with the formally correct arguments 
(function(x, i, j, ..., drop=FALSE)) and call your function from that 
method.

Beware there is _another_ related "bug":  if you use callNextMethod(), 
it does not seem to copy the default value of drop= either.  (It's a bit 
more debatable what callNextMethod() with no arguments should do in this 
case, so the problem here may be an "undesired feature" rather than a 
bug.)  You didn't show your real method, so this may not apply in your 
example.

By the way, I would be a little surprised if this had anything to do 
with changes in 2.4.0, at least those I'm aware of.
Iago Mosqueira wrote:
#
El mi?, 04-10-2006 a las 09:52 -0400, John Chambers escribi?:
Yes, our object is always 5 dimensional. We could use (...) but it
looked overly complex.
OK, many thanks.
I am adding the whole method below, but I do not thing this applies as
it is currently written.
This maybe the case, but it was working fine in 2.3.1.

Cheers,


Iago

setMethod("[", signature(x="FLQuant"),
	function(x, i="missing", j="missing", k="missing", l="missing",
m="missing",
		..., drop=FALSE) {

		if (missing(i))
			#i  <-  dimnames(x at .Data)[1][[1]]
			i  <-  seq(1, length(dimnames(x at .Data)[1][[1]]))
		if (missing(j))
			j  <-  dimnames(x at .Data)[2][[1]]
   		if (missing(k))
   			k  <-  dimnames(x at .Data)[3][[1]]
		if (missing(l))
			l  <-  dimnames(x at .Data)[4][[1]]
		if (missing(m))
			m  <-  dimnames(x at .Data)[5][[1]]

   		if (!drop) {
	  		flq	 <- FLQuant(x at .Data[i, j, k, l, m, drop=FALSE])
			units(flq) <- units(x)
			quant(flq) <- quant(x)
		}
		else if(drop)
             flq  <- x at .Data[i, j, k, l, m, ..., drop=TRUE]

   		return(flq)
	}
)
1 day later
2 days later
#
El vie, 06-10-2006 a las 10:16 -0400, John Chambers escribi?:
Hi,

I am now working with R-devel. I am finding this problem with the same
code. When the package is installed and loaded, '[' fails with
Error: subindex out of limits
Erro en FLQuant(x at .Data[i, j, k, l, m, drop = FALSE]) : 
        error in evaluating the argument 'object' in selecting a method
for function 'FLQuant'

but if I redefine the method by sourcing the same code inside the
session, it works fine. Calling getMethod('[','FLQuant') before and
after this operation shows no difference.
Method Definition:

function (x, i = "missing", j = "missing", ..., drop = FALSE) 
{
    .local <- function (x, i = "missing", j = "missing", k = "missing", 
        l = "missing", m = "missing", ..., drop = FALSE) 
    {
        if (missing(i)) 
            i <- seq(1, length(dimnames(x at .Data)[1][[1]]))
        if (missing(j)) 
            j <- dimnames(x at .Data)[2][[1]]
        if (missing(k)) 
            k <- dimnames(x at .Data)[3][[1]]
        if (missing(l)) 
            l <- dimnames(x at .Data)[4][[1]]
        if (missing(m)) 
            m <- dimnames(x at .Data)[5][[1]]
        if (drop == FALSE) {
            flq <- FLQuant(x at .Data[i, j, k, l, m, drop = FALSE])
            units(flq) <- units(x)
            quant(flq) <- quant(x)
        }
        else flq <- x at .Data[i, j, k, l, m, ..., drop = TRUE]
        return(flq)
    }
    .local(x, i, j, ..., drop = drop)
}

Signatures:
        x        
target  "FLQuant"
defined "FLQuant"

Any idea where the problem might originate?

Thanks,


Iago