From hpages at fhcrc.org  Thu Nov 15 06:42:07 2012
From: hpages at fhcrc.org (=?ISO-8859-1?Q?Herv=E9_Pag=E8s?=)
Date: Wed, 14 Nov 2012 21:42:07 -0800
Subject: [Rd] bug with mapply() on an S4 object
Message-ID: <50A480AF.1030901@fhcrc.org>

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] bug with mapply() on an S4 object
=?ISO-8859-1?Q?Herv=E9_Pag=E8s?=