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