From wdunlap at tibco.com  Tue Jun  2 20:29:03 2009
From: wdunlap at tibco.com (William Dunlap)
Date: Tue, 2 Jun 2009 11:29:03 -0700
Subject: [Rd] setdiff bizarre
In-Reply-To: <4A256978.3020703@idi.ntnu.no>
References: <a695148b0905292135g1c1bee38xb70687a43ccaa934@mail.gmail.com>	<8b356f880905300550y39c76b02h2d908b1c6b0ef0e4@mail.gmail.com>	<a695148b0905300721x6e291e0bg66fefcf0931f2ce2@mail.gmail.com>	<8b356f880905300859i5ba5800q5594bfce659373fe@mail.gmail.com><8b356f880906020813w6b7075b6g411fc177b508709e@mail.gmail.com>
	<4A254F11.3060207@idi.ntnu.no>
	<77EB52C6DD32BA4D87471DCD70C8D7000147B788@NA-PA-VBE03.na.tibco.com>
	<4A256978.3020703@idi.ntnu.no>
Message-ID: <77EB52C6DD32BA4D87471DCD70C8D7000147B7EF@NA-PA-VBE03.na.tibco.com>


> > ...
> > The related functions, duplicated() and unique(), do have
> > row-wise data.frame methods.  E.g.,
> >    > duplicated(data.frame(x=c(1,2,2,3,3),y=letters[c(1,1,2,2,2)]))
> >    [1] FALSE FALSE FALSE FALSE  TRUE
> > Perhaps match() ought to have one also.  S+'s match is generic
> > and has a data.frame method (which is row-oriented) so there we get:
> >    >  match(data.frame(x=c(1,3,5), y=letters[c(1,3,5)]),
> > data.frame(x=1:10,y=letters[1:10]))
> >    [1] 1 3 5
> >    > is.element(data.frame(x=1:10,y=letters[1:10]),
> > data.frame(x=c(1,3,5), y=letters[c(1,3,5)]))
> >     [1]  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
> >
> > I think that %in% and is.element() ought to remain calls to match()
> > and that if you want them to work row-wise on data.frames then
> > match should get a data.frame method.
> >   
> 
> sounds good to me.  how is
> 
>     'a' %in% data.frame('a')
> 
> in S+?
> 
> thanks for the response.

S+ gives:
   >  'a' %in% data.frame(letters)
   [1] TRUE
   > 'a' %in% data.frame(letters[2:26])
   [1] FALSE
but that special case, x a scalar and table a data.frame with
one column, gets by more or less by accident.
   > 'a' %in% data.frame(letters, num=1:26)
   Problem in match.data.frame(x, table, nomatch, incom..: table must be
a list the same length as x
   > c('a', 'b') %in% data.frame(letters)
   Problem in match.data.frame(x, table, nomatch, incom..: table must be
a list the same length as x
The intent is that the x and table arguments to match be
compatible data.frames.

S+'s match works differently on lists than R's does.  It is set
up to work on data.frame-like things: x and table must be
lists of the the same length and within each list, each element
must have the same length.  It acts like
  match(do.call("paste",x), do.call("paste",table))
but doesn't actually do the conversion to character implied in
that (it hashes all the entries in each 'row' into one hash table
entry, using the usual type-specific hash number computation
on each entry and combining them to make the row hash number).
E.g.,
   > match(list(c(3,2), c(1,7), c(4,1)),
list(c(1,4,2,3),c(0,6,7,1),c(0,5,1,4)))
   [1] 4 3

(Its match.data.frame() doesn't actually call this, for
historical/inertial
reasons.  It goes the paste() route.)
 
Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com 



[Rd] setdiff bizarre
William Dunlap