From: John Chambers <jmc_at_r-project.org>

Date: Tue 31 Oct 2006 - 23:18:08 GMT

R-devel@r-project.org mailing list

https://stat.ethz.ch/mailman/listinfo/r-devel Received on Wed Nov 01 15:41:18 2006

Date: Tue 31 Oct 2006 - 23:18:08 GMT

There's a two-level issue here, principle and practice.

The principle is that the behavior of basic R functions on basic R data types is considered "sealed". Math functions, arithmetic, etc. on basic vectors are not supposed to be alterable.

The function "[<-" is one of those functions. If x is a basic vector type, then x[i] <- value is considered sealed. That's what the error message is telling you. (By the way setReplaceMethod() has nothing to do with the issue; it's just a way of relieving the programmer from knowing that x[i]<-value is really a call to the function "[<-"; again, the error message shows that.)

Since you are writing the method for x having class "ANY", that is even stronger than changing the behavior for a specific basic type.

If you were to convince the R management that in principle having a special class on the right side justified breaking the seal (and that would take some arguing), then there is a practical problem.

The current implementation of primitives in C code examines the first argument only (except for binary operators, where both arguments are examined). The object is examined for having a non-basic class. If it's a basic data type, no further checking for methods occurs. So even if you were allowed to define the method, it wouldn't get called if x was a numeric vector, for example. Changing that would require changes at a low level, and almost certainly add some overhead to all calls. Expect opposition.

Otherwise, you must define some class and only expect your assignment to promote x if x inherits from that class. Or have another function, not "[<-", as the generic.

By the way, your method definition is not what you wanted in any case.

The signature you meant to have was signature(x="ANY", value = "brob"). At least I assume it was the right-hand side and not argument "i" that you meant to have class "brob". You don't actually need the x="ANY"part, that is the default for omitted arguments--but it's clearer in this case to be explicit.

Robin Hankin wrote:

*> Hi
**>
*

> If x <- 1:10 then x[5] <- 1i will promote

*> x to be a complex vector.
**>
**> Suppose I have an S4 class "brob", and have functions
**> is.brob(), as.brob(), as.numeric() and so forth (minimal self-contained
**> code below).
**>
**> If x is numeric (1:10, say) and y is a brob, what
**> is the best way to make
**>
**> x[5] <- y
**>
**> promote x to a brob in the same way as the complex example?
**>
**> Or is this not desirable for some reason?
**>
**>
**> My first idea was to use
**>
**> setReplaceMethod("[",signature("ANY","brob"), ...)
**>
**> but this gives a seal error:
**>
**> Error in setMethod(paste(f, "<-", sep = ""), ..., where = where) :
**> the method for function "[<-" and signature x="ANY", i="brob" is
**> sealed and cannot be re-defined
**>
**>
**>
**>
**> so this can't be right.
**>
**>
**>
**>
**>
**>
**>
**>
**>
**>
**>
**> setClass("swift",
**> representation = "VIRTUAL"
**> )
**>
**> setClass("brob",
**> representation = representation
**> (x="numeric",positive="logical"),
**> prototype = list(x=numeric(),positive=logical()),
**> contains = "swift"
**> )
**>
**> setAs("brob", "numeric", function(from){
**> out <- exp(from@x)
**> out[!from@positive] <- -out[!from@positive]
**> return(out)
**> } )
**>
**> setMethod("as.numeric",signature(x="brob"),function(x){as(x,"numeric")})
**> is.brob <- function(x){is(x,"brob")}
**>
**> "brob" <- function(x=double(),positive){
**> if(missing(positive)){
**> positive <- rep(TRUE,length(x))
**> }
**> if(length(positive)==1){
**> positive <- rep(positive,length(x))
**> }
**> new("brob",x=as.numeric(x),positive=positive)
**> }
**>
**> "as.brob" <- function(x){
**> if(is.brob(x)){
**> return(x)
**> } else if(is.complex(x)) {
**> warning("imaginary parts discarded")
**> return(Recall(Re(x)))
**> } else if(is.glub(x)){
**> warning("imaginary parts discarded")
**> return(Re(x))
**> } else {
**> return(brob(log(abs(x)), x>=0))
**> }
**> }
**>
**> setMethod("[", "brob",
**> function(x, i, j, drop){
**> brob(x@x[i], x@positive[i])
**> } )
**>
**> setReplaceMethod("[",signature(x="brob"),
**> function(x,i,j,value){
**> jj.x <- x@x
**> jj.pos <- x@positive
**> if(is.brob(value)){
**> jj.x[i] <- value@x
**> jj.pos[i] <- value@positive
**> return(brob(x=jj.x,positive=jj.pos))
**> } else {
**> x[i] <- as.brob(value)
**> return(x)
**> }
**> } )
**>
**>
**> setReplaceMethod("[",signature("ANY","brob"),
**>
**> function(x,i,j,value){
**> x <- as.brob(x)
**> x[i] <- as.brob(value)
**> return(x)
**> }
**> )
**>
**>
**>
**>
**> --
**> Robin Hankin
**> Uncertainty Analyst
**> National Oceanography Centre, Southampton
**> European Way, Southampton SO14 3ZH, UK
**> tel 023-8059-7743
**>
**> ______________________________________________
**> 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 Received on Wed Nov 01 15:41:18 2006

Archive maintained by Robert King, hosted by
the discipline of
statistics at the
University of Newcastle,
Australia.

Archive generated by hypermail 2.1.8, at Wed 01 Nov 2006 - 08:30:33 GMT.

*
Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel.
Please read the posting
guide before posting to the list.
*