MichaelChirico / r-bugs

A ⚠️read-only⚠️mirror of https://bugs.r-project.org/
20 stars 0 forks source link

[BUGZILLA #918] several bugs #952

Closed MichaelChirico closed 4 years ago

MichaelChirico commented 4 years ago

From: Rich Heiberger <rmh@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>> # Your mailer is set to "none" (default on Windows), # hence we cannot send the bug report directly from R. # Please copy the bug report (after finishing it) to # your favorite email program and send it to # # r-bugs@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>-project.org # ######################################################

  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")

as.double

function (x, ...) UseMethod("as.double")

S:

as.numeric

function(x) .Internal(as.numeric(x), "As_vector", T, 4)

as.double

function(x) .Internal(as.double(x), "As_vector", T, 4)

As a consequence, a user function as.numeric.mv doesn't work as a method in R because it never gets called when accessed as as.numeric(x).

objects()

character(0)

a <- list(NA)
attr(a[[1]],"mv") <- "default"
class(a) <- "mv"

a

[[1]] [1] NA attr(,"mv") [1] "default"

attr(,"class") [1] "mv"

as.numeric(a)

[1] NA

as.numeric.mv <- function(x, ...) {

+ print("we got here") + x + }


as.numeric(a)  ## the function as.numeric.mv was not called

[1] NA

as.numeric.mv(a)

[1] "we got here" [1] NA

  1. 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

  1. 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

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

  1. 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

  2. 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?

b. S-Plus 6 uses the function oldClass Can you add these functions and default definitions to R? oldClass <- function(...) class(...)
"oldClass<-" <- function(...) "class<-"(...)

  1. 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

--please do not edit the information below--

Version: platform = i386-pc-mingw32 arch = x86 os = Win32 system = x86, Win32 status = major = 1 minor = 2.1 year = 2001 month = 01 day = 15 language = R

Windows 9x 4.0 (build 1212) B

Search Path: .GlobalEnv, package:ctest, Autoloads, package:base


METADATA

MichaelChirico commented 4 years ago

From: Thomas Lumley <tlumley@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>>

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@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::> 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

"%*%.default"<-get("%*%")
"%*%"<-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")

Indeed.

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

Thomas Lumley Asst. Professor, Biostatistics tlumley@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::> University of Washington, Seattle


METADATA

MichaelChirico commented 4 years ago

From: Rich Heiberger <rmh@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>> ## Thomas rightly points out that list() is not the best structure for ## homogeneous data. My example was the simplest that generated the ## error of a matrix structure that that doesn't work. The application ## that this is simplified from needs lists because the data isn't ## homogeneous. I am attempting to write a missing value class, where ## each item is a list. In the simplest instance, if the datum is missing ## then the attribute contains the reason. ## ## Both of the 'bugs'/'unimplemented features' ## 3. a <- matrix(list(1,2,3,4,5,6), 2, 3) ## 6. bug in "[" for lists ## show up in this example. Thus

x <- list(1,2,3,4,5,6) dim(x) <- c(2,3) x[[2,3]] <- NA attr(x[[2,3]],"mv") <- "absent" x for(i in x) print(i) x[2,] x[1,1] x[2,3]

Rich


METADATA

MichaelChirico commented 4 years ago

From: Rich Heiberger <rmh@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>> ### I got bit again by the same bugs I wrote about a year ago. ### The bugs are related to matrices and arrays of lists.

### 1. There is a clear inconsistency in how R handles two ### functionally equivalent statements. ### array() is able to take a list and create a matrix. ### matrix() is unable to create that matrix.

vector("list", 2)

[[1]] NULL

[[2]] NULL

array(vector("list", 2), dim=c(2,1))
 [,1]  

[1,] "NULL" [2,] "NULL"

tmpa <- array(vector("list", 2), dim=c(2,1))
class(tmpa)

NULL

is.array(tmpa)

[1] TRUE

is.matrix(tmpa)

[1] TRUE

tmpm <- matrix(vector("list", 2), nrow=2)

Error in matrix(vector("list", 2), nrow = 2) : Unimplemented feature in copyVector

### 2. Here the matrix single-[ subscript is doing the wrong thing, ### without giving a warning.

tmp <- array(vector("list", 2), 1:2)
tmp
 [,1]   [,2]  

[1,] "NULL" "NULL"

tmp[1]

[[1]] NULL

tmp[[1]]

NULL

tmp[1,1]

[[1]] NULL

tmp[[1,1]]

NULL

list("abc")

[[1]] [1] "abc"

tmp[1] <- list("abc")  ## assignment
tmp[1]

[[1]] [1] "abc"

tmp[[1]]

[1] "abc"

tmp[1,1]     ## incorrect retrieval

[[1]] NULL

tmp[[1,1]]

[1] "abc"

tmp[1,2] <- list("def")  ## refuse to do similar assignment

Error: incompatible types in subset assignment

### 3. subsetting a vector of lists doesn't behave the way I anticipate. ### It looks like NULL is not handled consistently inside a vector. ### Sometimes it can be an element, sometimes not.

tmpv <- vector("list", 2)
tmpv

[[1]] NULL

[[2]] NULL

tmpv[1] <- "abcd"  ## I assigned to the first element.
tmpv               ## Both elements are still here.

[[1]] [1] "abcd"

[[2]] NULL

tmpv[1] <- NULL    ## I assigned to the first element.
tmpv               ## The second element is gone.

[[1]] NULL

### This time the issue came up in an attempt to make abind work with R. ### abind() is a generalization of rbind and cbind to arrays. ### Tony Plate and I posted it to StatLib in 1996 ### (http://lib.stat.cmu.edu/S/abind).

### I would like you to consider adding abind to R. ### The posted abind doesn't work in R, for the reasons above and due to ### a difference in behavior of match.call between S -Plusand R that I am ### reporting in a separate bug report. ### There are two revised files, currently available at ### http://surfer.sbm.temple.edu/~rmh/abind.r ### http://surfer.sbm.temple.edu/~rmh/abind.test.in.r ### The documentation in statlib applies to these files. ### I will update the statlib version after I understand why R differs.

version
     _              

platform i386-pc-mingw32 arch x86
os Win32
system x86, Win32
status
major 1
minor 4.1
year 2002
month 01
day 30
language R


METADATA

MichaelChirico commented 4 years ago

From: ripley@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::> Points 1 and 2 are already fixed in R-devel, as I did indicate on R-help, yesterday.

Point 3 is in the FAQ, no less:

Please don't mix up unrelated reports: point 3 has nothing to do with matrix lists.

On Wed, 13 Mar 2002 rmh@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::> wrote:

### I got bit again by the same bugs I wrote about a year ago.
### The bugs are related to matrices and arrays of lists.

### 1. There is a clear inconsistency in how R handles two
### functionally equivalent statements.
### array() is able to take a list and create a matrix.
### matrix() is unable to create that matrix.

> vector("list", 2)
[[1]]
NULL

[[2]]
NULL

> array(vector("list", 2), dim=c(2,1))
[,1]
[1,] "NULL"
[2,] "NULL"
> tmpa <- array(vector("list", 2), dim=c(2,1))
> class(tmpa)
NULL
> is.array(tmpa)
[1] TRUE
> is.matrix(tmpa)
[1] TRUE
> tmpm <- matrix(vector("list", 2), nrow=2)
Error in matrix(vector("list", 2), nrow = 2) :
Unimplemented feature in copyVector
>

### 2. Here the matrix single-[ subscript is doing the wrong thing,
### without giving a warning.

> tmp <- array(vector("list", 2), 1:2)
> tmp
[,1]   [,2]
[1,] "NULL" "NULL"
> tmp[1]
[[1]]
NULL

> tmp[[1]]
NULL
> tmp[1,1]
[[1]]
NULL

> tmp[[1,1]]
NULL
> list("abc")
[[1]]
[1] "abc"

> tmp[1] <- list("abc")  ## assignment
> tmp[1]
[[1]]
[1] "abc"

> tmp[[1]]
[1] "abc"
> tmp[1,1]     ## incorrect retrieval
[[1]]
NULL

> tmp[[1,1]]
[1] "abc"

> tmp[1,2] <- list("def")  ## refuse to do similar assignment
Error: incompatible types in subset assignment
>

### 3. subsetting a vector of lists doesn't behave the way I anticipate.
### It looks like NULL is not handled consistently inside a vector.
### Sometimes it can be an element, sometimes not.

> tmpv <- vector("list", 2)
> tmpv
[[1]]
NULL

[[2]]
NULL

> tmpv[1] <- "abcd"  ## I assigned to the first element.
> tmpv               ## Both elements are still here.
[[1]]
[1] "abcd"

[[2]]
NULL

> tmpv[1] <- NULL    ## I assigned to the first element.
> tmpv               ## The second element is gone.
[[1]]
NULL

>

### This time the issue came up in an attempt to make abind work with R.
### abind() is a generalization of rbind and cbind to arrays.
### Tony Plate and I posted it to StatLib in 1996
### (http://lib.stat.cmu.edu/S/abind).

### I would like you to consider adding abind to R.
### The posted abind doesn't work in R, for the reasons above and due to
### a difference in behavior of match.call between S -Plusand R that I am
### reporting in a separate bug report.
### There are two revised files, currently available at
### http://surfer.sbm.temple.edu/~rmh/abind.r
### http://surfer.sbm.temple.edu/~rmh/abind.test.in.r
### The documentation in statlib applies to these files.
### I will update the statlib version after I understand why R differs.

> version
_
platform i386-pc-mingw32
arch     x86
os       Win32
system   x86, Win32
status
major    1
minor    4.1
year     2002
month    01
day      30
language R
>

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._

-- Brian D. Ripley, ripley@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::> Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ <CENSORING FROM DETECTED PHONE NUMBER ONWARDS; SEE BUGZILLA>


METADATA

MichaelChirico commented 4 years ago

NOTES:

  1. as.numeric -> use as.double.FOO for methods -- doc.fixed for 1.2.3
    1. cannot set attribute on NULL -- no bug
    2. rep(list() ... ) : a wish fulfilled for 1.3.x
    3. %*% is not a generic in R (but is fast!) but in S+ -- not a bug
    4. S-plus (S4) compatibility -- a wish but not for now
    5. list()s with dim() attribute -- an ongoing `research topic' :-)

Points 1 and 2 in the follow up are already fixed in R-devel, to be 1.5.0


METADATA

MichaelChirico commented 4 years ago

Audit (from Jitterbug): Tue Apr 24 17:35:09 2001 maechler changed notes Tue Apr 24 17:35:09 2001 maechler foobar Tue Apr 24 17:35:09 2001 maechler moved from incoming to TooMuchAtOnce Thu Jun 21 08:42:17 2001 ripley moved from TooMuchAtOnce to TooMuchAtOnce-fixed Wed Mar 13 10:36:46 2002 ripley changed notes Wed Mar 13 10:36:46 2002 ripley foobar


METADATA