On 05/15/2018 09:13 PM, Michael Lawrence wrote:
My understanding is that array (or any other structure) does not
"simply" inherit from vector, because structures are not vectors in
the strictest sense. Basically, once a vector gains attributes, it is
a structure, not a vector. The methods package accommodates this by
defining an "is" relationship between "structure" and "vector" via an
"explicit coerce", such that any "structure" passed to a "vector"
method is first passed to as.vector(), which strips attributes. This
is very much by design.

It seems that the problem is really with matrices and arrays, not
with "structures" in general:

  f <- factor(c("z", "x", "z"), levels=letters)
  m <- matrix(1:12, ncol=3)
  df <- data.frame(f=f)
  x <- structure(1:3, titi="A")

Only the matrix looses its attributes when passed to a "vector"
method:

  setGeneric("foo", function(x) standardGeneric("foo"))
  setMethod("foo", "vector", identity)

  foo(f)     # attributes are preserved
  # [1] z x z
  # Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

  foo(m)     # attributes are stripped
  # [1]  1  2  3  4  5  6  7  8  9 10 11 12

  foo(df)    # attributes are preserved
  #   f
  # 1 z
  # 2 x
  # 3 z

  foo(x)     # attributes are preserved
  # [1] 1 2 3
  # attr(,"titi")
  # [1] "A"

Also if structures are passed to as.vector() before being passed to
a "vector" method, shouldn't as.vector() and foo() be equivalent on
them? For 'f' and 'x' they're not:

  as.vector(f)
  # [1] "z" "x" "z"

  as.vector(x)
  # [1] 1 2 3

Finally note that for factors and data frames the "vector" method gets
selected despite the fact that is( , "vector") is FALSE:

  is(f, "vector")
  # [1] FALSE

  is(m, "vector")
  # [1] TRUE

  is(df, "vector")
  # [1] FALSE

  is(x, "vector")
  # [1] TRUE

Couldn't we recognize these problems as real, even if they are by
design? Hopefully we can all agree that:
- the dispatch mechanism should only dispatch, not alter objects;
- is() and selectMethod() should not contradict each other.

Thanks,
H.


Michael


On Tue, May 15, 2018 at 5:25 PM, Hervé Pagès <hpa...@fredhutch.org> wrote:
Hi,

This was quite unexpected:

   setGeneric("foo", function(x) standardGeneric("foo"))

   setMethod("foo", "vector", identity)

   foo(matrix(1:12, ncol=3))
   # [1]  1  2  3  4  5  6  7  8  9 10 11 12

   foo(array(1:24, 4:2))
   # [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
24

If I define a method for array objects, things work as expected though:

   setMethod("foo", "array", identity)

   foo(matrix(1:12, ncol=3))
   #      [,1] [,2] [,3]
   # [1,]    1    5    9
   # [2,]    2    6   10
   # [3,]    3    7   11
   # [4,]    4    8   12

So, luckily, I have a workaround.

But shouldn't the dispatch mechanism stay away from the business of
altering objects before passed to it?

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: hpa...@fredhutch.org
Phone:  (206) 667-5791
Fax:    (206) 667-1319

______________________________________________
R-devel@r-project.org mailing list
https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIFaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=gynT4YhbmVKZhnX4srXlCWZZRyVBMXG211CKgftdEs0&s=_I0aFHQVnXdBfB5kTLg9TxK_2LHdSuaB6gqZwSx1orQ&e=


--
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: hpa...@fredhutch.org
Phone:  (206) 667-5791
Fax:    (206) 667-1319

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

Reply via email to