The asymmetry is just the symptom of a more fundamental issue: There are no operator methods currently defined for "vector" classes, either combined with each other or with a non-S4 object.

The consequence is that computations drop through to the primitive C code. Not a good idea, because that code does various things to objects with attributes, some of them bizarre and most of them not what should logically happen for S4 classes.

Consider two classes with slightly more content than "test":
> setClass("test1",contains = "vector", representation(label = "character"))
[1] "test1"
> setClass("test2",contains = "vector", representation(flag = "logical"))
[1] "test2"

These two classes both inherit from "vector" but are unrelated to each other.

What should happen for arithmetic and other operators combining these two classes? There's some scope for discussion, but a reasonable policy is that the vector parts should be used and a result returned that is a simple vector. What should NOT happen is that one class is retained and the other thrown away--that's not a meaningful interpretation of the two definitions here. Unfortunately, that's what does happen with the primitives. Example below.

We need to develop some methods for combinations of "vector" and "ANY" reflecting what's sensible. I'll put some first attempts on r-devel and we can discuss what's wanted. (May not happen right away, but hopefully in a week or two.)

John

---------------------

Example:

If the objects are equal in length, the left operand wins, or seems to:

> x1 = new("test1", 1:10, label = "Something")
> x2 = new("test2", 10:1, flag = rep(TRUE, 10))
> x1+x2
An object of class “test1”
[1] 11 11 11 11 11 11 11 11 11 11
Slot "label":
[1] "Something"

> x2+x1
An object of class “test2”
[1] 11 11 11 11 11 11 11 11 11 11
Slot "flag":
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

But in fact, it's weirder than that, because _all_ the attributes are retained:

> names(attributes(x1+x2))
[1] "flag" "class" "label"
> names(attributes(x2+x1))
[1] "label" "class" "flag"


That was with equal lengths. Otherwise, the code uses the longer object's attributes, including the class.

> x11 = new("test1", 101:105,label = "Smaller")
> x11 +x2
An object of class “test2”
[1] 111 111 111 111 111 106 106 106 106 106
Slot "flag":
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

> x2+x11
An object of class “test2”
[1] 111 111 111 111 111 106 106 106 106 106
Slot "flag":
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> names(attributes(x11+x2))
[1] "flag" "class"



Simon Urbanek wrote:

On Oct 27, 2008, at 12:25 , [EMAIL PROTECTED] wrote:

Hello all,
It appears that for the simplest of S4 objects, z+1 does not equal 1+z.
Presumably this is a bug, as 1+z seems to make a malformed object (at
least malformed as an input to str).

FWIW the difference is that z+1 has the S4 bit set, 1+z does not. The objects are otherwise identical. AFAICS the same behavior is reproducible with any binary arithmetic operator (i.e. non-S4 %op% S4 will produce a result with S4 bit cleared yet valid S4 attributes).

Cheers,
S




setClass("test", representation("vector"))
[1] "test"
z <- new("test", 1)
identical(z+1, 1+z)
[1] FALSE
str(z+1)
Formal class 'test' [package ".GlobalEnv"] with 1 slots
..@ .Data: num 2
str(1+z)
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Class 'test' Class 'test' Class 'test' Class
'test' Class 'test' Class 'test' Class 'test' Class 'test' Class 'test'
Class 'test' Class 'test' Error: evaluation nested too deeply: infinite
recursion / options(expressions=3D)?

R.version
_ =20
platform x86_64-unknown-linux-gnu =20
arch x86_64 =20
os linux-gnu =20
system x86_64, linux-gnu =20
status =20
major 2 =20
minor 8.0 =20
year 2008 =20
month 10 =20
day 20 =20
svn rev 46754 =20
language R =20
version.string R version 2.8.0 (2008-10-20)

______________________________________________
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


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

Reply via email to