[Rd] several bugs (PR#918)

Thomas Lumley tlumley@u.washington.edu
Mon, 23 Apr 2001 09:37:05 -0700 (PDT)

Some of these are indeed bugs. Some are merely incompatibilities, in
particular between R and S4. R is intended to be largely compatible with S
version 3, but not (currently at least) with S version 4.

Incidentally, it's easier to  keep track of bugs if they come one to a
message. That way they get separate bug numbers.

On Mon, 23 Apr 2001 rmh@surfer.sbm.temple.edu wrote:
> 1. as.numeric behaves differently in R than in S and I think this
> shows a bug in how S3 classes are implemented.
> R:
> > as.numeric
> function (x, ...)
> UseMethod("as.double")

It is a bug, but not in how S3 classes are implemented (well, it's a bug
in the design of S3 classes that this can happen).  R has only one
floating point data type, which means that as.numeric and as.double do the
same thing.  The bug is that it isn't documented under help(as.numeric)
that you need to set up methods for as.double().

> 2. works in S-Plus 4.5, not in R.  What is the rationale for this difference?
> a <- list(NULL)
> attr(a[[1]],"mv") <- "default"
> R gives the message
> Error: attempt to set an attribute on NULL

The rationale is that you can't set an attribute on NULL. There are two
reasons.  The implementation reason is that there's only one of it: all
NULLs are references to the same object.  The interface reason is that if
you  want to set attributes on it you don't want a NULL (think of the NULL
pointer in C or nil in Pascal).

 You probably want numeric(0).

> 3. Unimplemented features in rep, copyVector
> > rep(list(1),1)
> [[1]]
> [1] 1
> > rep(list(1,2,3),1)
> Error in rep(list(1, 2, 3), 1) : Unimplemented feature in rep

Yes, it's an unimplemented feature. We clearly know about it, since you
got the message, so it isn't a bug. It is implemented in the pre1.3
development version.

> > a <- matrix(list(1,2,3,4,5,6), 2, 3)
> Error in matrix(list(1, 2, 3, 4, 5, 6), 2, 3) :
> 	Unimplemented feature in copyVector

This one isn't implemented in the development version, for a good reason.
Matrices and lists can hold very different sorts of things.  You should do
	a <- matrix(c(1,2,3,4,5,6), 2, 3)
This may well be what you should do in the previous case, as well. It's
more efficient to store homogeneous, one-dimensional data in a vector
rather than a list.

> 4. methods in S-Plus that aren't methods in R.
> a. %*% is a method in S-Plus 4.5 and is a primitive in R.
>    Therefore a user function "%*%.mv" doesn't get called by  a %*% b

This might be worth implementing, but we would have to worry about the
overhead: matrix multiplication is a speed-critical function (like all the
remaining primitives).  You can easily make it generic for yourself

 	"%*%"<-function(x,y,...) UseMethod("%*%")

This wouldn't despatch on the second argument, but that could be fixed
with a bit more work.

> 5. S-Plus 6 compatibility issues
> a. S+4 and R use the function
>      exists("function.name", mode="function")
>    S+6 use the function
>      existsFunction("function.name")


> More generally, S-Plus 6 has the following functions
> > objip("exists")
> $splus:
> [1] "exists"         "existsFunction" "file.exists"
> $main:
> [1] "dbexists"       "dbexistsOld"    "dyn.exists"     "existsClass"
> [5]  "existsClassDef" "existsDoc"     "existsMethod"
> Can you add these function names to R with sensible defaults until the S4
> methods are fully in place?

No. You can, though.

R is not a clone of S-PLUS, especially not of S-PLUS 6. We are working
towards compatibility with S4 on certain important features, but not
detail by detail.

You may want to look at http://www.omegahat.org/RSMethods/index.html
which describes an implementation of S4 classes for R by John Chambers.

> 6. bug in "[" for lists
> a <- list(1,2,3,4,5,6)
> dim(a) <- c(2,3)
> unlist(a)
> > a[,1:2]
>      [,1]   [,2]
> [1,] "NULL" "NULL"
> [2,] "NULL" "NULL"
> The same code in S+4 gives
> > a[,1:2]
>      [,1] [,2]
> [1,] 1    3
> [2,] 2    4

If there's a bug here it's that an error isn't returned.  You can't go
around setting dim() on things and expecting it to work.  A properly
object-oriented language wouldn't let you even try. You took a list of
six objects (which could be *any* six objects, as different as chalk and
Wednesday) and told it that it was a 2x3 array.  It believed you. Not
surprisingly, it got confused.

 It does work if a is a vector rather than a list, as do some other things
you tried, so in general you might be happier if you used c() rather than
list() for homogeneous data.

It's true that some versions of S allow it. Some versions of S also allow
   a<-as.matrix(lm(Fuel ~ . , fuel.frame))
for example. The S languages could do with a clearer distinction between
high level functions that check their arguments for compatibility and the
low-level functions that are needed to implement these.


Thomas Lumley			Asst. Professor, Biostatistics
tlumley@u.washington.edu	University of Washington, Seattle

r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch