Jim, yes, I have dealt with that particular challenge that list(...) throws an error for a call like f(x,,,) where the empty args match to a ... formal argument. Here's some fragments of code that I used to cope with this:

    # to find the empty anon args, must work with the unevaluated dot args
    dot.args.uneval <- match.call(expand.dots=FALSE)$...
    if (length(dot.args.uneval))
missing.dot.args <- sapply(dot.args.uneval, function(arg) is.symbol(arg) && as.character(arg)=="")
    else
        missing.dot.args <- logical(0)
...
    # Now we can work with evaluated dot args.
    # Can't do dot.args <- list(...) because that will
    # stop with an error for missing args.
dot.args <- mapply(dot.args.uneval, missing.dot.args, FUN=function(arg, m) if (!m) eval(arg) else NULL)

Let me know if you need any further explanation.

Several warnings:
* I was using this code with S3 generics and methods.
* There are quite possibly better ways of detecting empty unevaluated arguments than 'is.symbol(arg) && as.character(arg)==""'. * You'll probably want to be careful that the eval() in the last line is using the appropriate environment for your application.

I didn't read your code in detail, so apologies if the above is off-the-point, but your verbal description of the problem and the coding style and comments in the "[" method for "myExample" triggered my memory.

-- Tony Plate

On 05/17/2010 07:48 PM, James Bullard wrote:
Apologies if I am not understanding something about how things are being
handled when using S4 methods, but I have been unable to find an answer to
my problem for some time now.

Briefly, I am associating the generic '[' with a class which I wrote
(here: myExample). The underlying back-end allows me to read contiguous
slabs, e.g., 1:10, but not c(1, 10). I want to shield the user from this
infelicity, so I grab the slab and then subset in memory. The main problem
is with datasets with dim(.)>  2. In this case, the '...' argument doesn't
seem to be in a reasonable state. When it is indeed missing then it
properly reports that fact, however, when it is not missing it reports
that it is not missing, but then the call to: list(...) throws an argument
is missing exception.

I cannot imagine that this has not occurred before, so I am expecting
someone might be able to point me to some example code. I have attached
some code demonstrating my general problem ((A) and (B) below) as well as
the outline of the sub-selection code. I have to say that coding this has
proven non-trivial and any thoughts on cleaning up the mess are welcome.

As always, thanks for the help.

Jim

require(methods)

setClass('myExample', representation = representation(x = "array"))

myExample<- function(dims = c(1,2)) {
   a<- array(rnorm(prod(dims)))
   dim(a)<- dims
   obj<- new("myExample")
   o...@x<- a
   return(obj)
}

setMethod("dim", "myExample", function(x) return(dim(x...@x)))

functionThatCanOnlyGrabContiguous<- function(x, m, kall) {
   kall$x<- x...@x
   for (i in 1:nrow(m)) {
     kall[[i+2]]<- seq.int(m[i,1], m[i,2])
   }
   print(as.list(kall))
   return(eval(kall))
}

setMethod("[", "myExample", function(x, i, j, ..., drop = TRUE) {
   if (missing(...)){
     print("Missing!")
   }
   e<- list(...)
   m<- matrix(nrow = length(dim(x)), ncol = 2)

   if (missing(i))
     m[1,]<- c(1, dim(x)[1])
   else
     m[1,]<- range(i)

   if (length(dim(x))>  1) {
     if (missing(j))
       m[2,]<- c(1, dim(x)[2])
     else
       m[2,]<- range(j)

     k<- 3
     while (k<= nrow(m)) {
       if (k-2<= length(e))
         m[k,]<- range(e[[k-2]])
       else
         m[k,]<- c(1, dim(x)[k])
       k<- k + 1
     }
   }
   kall<- match.call()
   d<- functionThatCanOnlyGrabContiguous(x, m, kall)

   kall$x<- d
   if (! missing(i)) {
     kall[[3]]<- i - min(i) + 1
   }
   if (! missing(j)) {
     kall[[4]]<- j - min(j) + 1
   } else {
     if (length(dim(x))>  1)
       kall[[4]]<- seq.int(1, dim(x)[2])
   }
   ## XXX: Have to handle remaining dimensions, but since I can't
   ## really get a clean '...' it is on hold.

   eval(kall)
})

## ############### 1-D
m<- myExample(10)
m...@x[c(1,5)] == m[c(1, 5)]

## ############### 2-D
m<- myExample(c(10, 10))
m...@x[c(1,5), c(1,5)] == m[c(1,5), c(1,5)]
m...@x[c(5, 2),] == m[c(5,2),]

## ############### 3-D
m<- myExample(c(1,3,4))

## (A) doesn't work
m...@x[1,1:2,] == m[1,1:2,]

## (B) nor does this for different reasons.
m[1,,1]
m...@x[1,,1]

sessionInfo()
R version 2.11.0 (2010-04-22)
x86_64-pc-linux-gnu

locale:
  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
  [5] LC_MONETARY=C              LC_MESSAGES=en_US.UTF-8
  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
  [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

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

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

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel




______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to