From georgi.boshnakov at manchester.ac.uk  Thu Nov 15 13:43:35 2012
From: georgi.boshnakov at manchester.ac.uk (Georgi Boshnakov)
Date: Thu, 15 Nov 2012 12:43:35 +0000
Subject: [Rd] R-devel Digest, Vol 117, Issue 13
In-Reply-To: <mailman.29.1352977208.18757.r-devel@r-project.org>
References: <mailman.29.1352977208.18757.r-devel@r-project.org>
Message-ID: <438D2EC9EAFE5946B2D5864670EA468E3AB4A3CF@MBXP01.ds.man.ac.uk>

Hi, 

> ... Wrong. It looks like internally a[[1]] is always used instead of a[[i]].
> The real problem it seems is that 'a' is treated as if it was of
> ength 1:
>
>  > mapply(function(x, y) {x * y}, a, 1:3)
>  [1] 101 202 303
>   > mapply(function(x, y) {x * y}, a, 5)
>   [1] 505
>
> In other words, internal dispatch works for [[ but not for length().

Documentation of mapply says 
> Arguments are recycled if necessary.

So, the function seems to work as documented. 

One may be tempted to expect that what 'length()' says should take precedence but  
the '...' arguments in 'mapply' are documented as
>  ...: arguments to vectorize over (vectors or lists of strictly
>          positive length, or all of zero length).

So, the defining feature is that the arguments are vectors.  
Since class A is not defined as a vector class, object 'a' is a scalar (vector of length 1 in R) and therefore recycled. 

It is probably not a good idea to redefine length() for class A without making it a subclass of 'vector' (or something equivalent) since doing so redefines a fundamental basic feature behind R's back. 

Best regards,
Georgi

--
Dr Georgi Boshnakov               tel: (+44) (0)161 306 3684
School of Mathematics             fax: (+44) (0)161 306 3669
Alan Turing Building 1.125
The University of Manchester      email: Georgi.Boshnakov at manchester.ac.uk
Oxford Road
Manchester M13 9PL
UK



Message: 7
Date: Wed, 14 Nov 2012 21:42:07 -0800
From: Herv? Pag?s <hpages at fhcrc.org>
To: R-devel at r-project.org
Subject: [Rd] bug with mapply() on an S4 object
Message-ID: <50A480AF.1030901 at fhcrc.org>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hi,

Starting with ordinary vectors, so we know what to expect:

   > mapply(function(x, y) {x * y}, 101:106, rep(1:3, 2))
   [1] 101 204 309 104 210 318

   > mapply(function(x, y) {x * y}, 101:106, 1:3)
   [1] 101 204 309 104 210 318

Now with an S4 object:

   setClass("A", representation(aa="integer"))
   a <- new("A", aa=101:106)

   > length(a)
   [1] 1

Implementing length():

   setMethod("length", "A", function(x) length(x at aa))

Testing length():

   > length(a)  # sanity check
   [1] 6

No [[ yet for those objects so the following error is expected:

   > mapply(function(x, y) {x * y}, a, rep(1:3, 2))
   Error in dots[[1L]][[1L]] : this S4 class is not subsettable

Implementing [[:

   setMethod("[[", "A", function(x, i, j, ...) x at aa[[i]])

Testing [[:

   > a[[1]]
   [1] 101
   > a[[5]]
   [1] 105

Trying mapply again:

   > mapply(function(x, y) {x * y}, a, rep(1:3, 2))
   [1] 101 202 303 101 202 303

Wrong. It looks like internally a[[1]] is always used instead of a[[i]].

The real problem it seems is that 'a' is treated as if it was of
length 1:

   > mapply(function(x, y) {x * y}, a, 1:3)
   [1] 101 202 303
   > mapply(function(x, y) {x * y}, a, 5)
   [1] 505

In other words, internal dispatch works for [[ but not for length().

Thanks,
H.

--
Herv? Pag?s

Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024

E-mail: hpages at fhcrc.org
Phone:  (206) 667-5791
Fax:    (206) 667-1319







[Rd] R-devel Digest, Vol 117, Issue 13
Georgi Boshnakov