From wdunlap at tibco.com  Wed Aug 26 18:03:59 2015
From: wdunlap at tibco.com (William Dunlap)
Date: Wed, 26 Aug 2015 09:03:59 -0700
Subject: [Rd] match()/%in% with language objects?
In-Reply-To: <21981.32451.725608.366953@stat.math.ethz.ch>
References: <55DC940B.8080701@gmail.com>
	<CAF8bMcbLb1FT2B4umf6jAYAB0hRBViaqA+c7W-XmDn5DrunoBA@mail.gmail.com>
	<21981.32451.725608.366953@stat.math.ethz.ch>
Message-ID: <CAF8bMcYJshr=0Tqwkpv1yy+Z-FQy49T0NjNv59cmwX=xXD3mog@mail.gmail.com>

>Did you support Ben's  wish to allow 'symbol' (aka 'name') objects as well,
>or even more general language objects (as by the subject's wording) ?

Do you mean should match treat
    match(quote(foo), list(as.name("bar"), as.name("foo"))) # error
the same as
    match(list(quote(foo)), list(as.name("bar"), as.name("foo"))) # 2
?  I don't think that would be good - 'x' needs to be a list or expression
in the length!=1 cases, so it should be one in all cases.

On the other hand it would be nice to fix up things like
  > list(list(quote(foo)), quote(list(foo))) %in% list(quote(list(foo)))
  [1] TRUE TRUE
either by using calls to identical() in the match/hashing code or
adding "quoteExpressions" when deparsing the language objects.
  x <- list(list(quote(foo)), quote(list(foo)))
  table <- list(quote(list(foo)))
  x %in% table
  #[1] TRUE TRUE
  lapply(x, deparse) %in% lapply(table, deparse)
  #[1] TRUE TRUE
  lapply(x, deparse, control="quoteExpressions") %in% lapply(table,
deparse, control="quoteExpressions")
  #[1] FALSE  TRUE

duplicated() already seems to do the right thing in that case:
  duplicated(x)
  #[1] FALSE FALSE
  duplicated(x[c(1,2,1)])
  #[1] FALSE FALSE  TRUE





Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Wed, Aug 26, 2015 at 1:54 AM, Martin Maechler <maechler at stat.math.ethz.ch
> wrote:

> >>>>> William Dunlap <wdunlap at tibco.com>
> >>>>>     on Tue, 25 Aug 2015 09:47:23 -0700 writes:
>
>     > match(x,table) and x%in%table work when x and table are lists of
> language
>     > objects or expressions.  E.g.,
>
>     > expression(quote(1+2), quote(log2(16))) %in% expression(3,
> quote(1+2), c(4L,5L,6L,7L))
>     > #[1]  TRUE FALSE
>     > list(quote(1+2), quote(log2(16))) %in% list(3, quote(1+2),
> c(4L,5L,6L,7L))
>     > #[1]  TRUE FALSE
>     > match(list(quote(1+2), quote(log2(16))),  list(3, quote(1+2),
> c(4L,5L,6L,7L)))
>     > #[1]  2 NA
>
> yes, or slightly more naturally for the first case,
>
>  > expression(1+2, log2(16)) %in% expression(3, 1+2, c(4L,5L,6L,7L))
>  [1]  TRUE FALSE
>
>
>     > With your example data:
>     > spList[1] %in% spList
>     > #[1] TRUE
>     > list(quote(foo)) %in% spList
>     > #[1] TRUE
>     > list(quote(nosuchsymbol)) %in% spList
>     > #[1] FALSE
>
> yes  indeed, that works because list()s and expression()s are
> "vector"s in the wide sense, as "we all" know.
>
> Did you support Ben's  wish to allow 'symbol' (aka 'name') objects as well,
> or even more general language objects (as by the subject's wording) ?
>
> Internally, in these cases the matches do happen with character
> coerced objects eventually; still I'd tend to agree that allowing some of
> these as arguments to match() in addition to the
> wide-sense-vectors (and NULL !) would make sense.
>
> Martin
>
>
>
>     > Bill Dunlap
>     > TIBCO Software
>     > wdunlap tibco.com
>
>     > On Tue, Aug 25, 2015 at 9:12 AM, Ben Bolker <bbolker at gmail.com>
> wrote:
>
>     >> -----BEGIN PGP SIGNED MESSAGE-----
>     >> Hash: SHA1
>     >>
>     >>
>     >> I haven't yet dug into the internals of match() yet to see what's
>     >> going on, but I'm wondering whether there's a design reason why I
>     >> can't use %in% (which is a wrapper for match()) on language objects.
>     >>
>     >> I'd like to test whether a language object is in a list of language
>     >> objects, but I get the error "'match' requires vector arguments":
>     >>
>     >> specials <- c("foo","bar")
>     >> spList <- lapply(specials,as.name)  ## convert to language objects
>     >> "a" %in% spList  ## works (FALSE)
>     >> spList[[1]] %in% spList ##   'match' requires vector arguments
>     >> quote(foo) %in% spList  ## ditto
>     >> quote(foo) == spList[[1]]  ## TRUE
>     >>
>     >> obviously I can go the other way, converting my target into text:
>     >>
>     >> deparse(spList[[1]]) %in% specials  ## TRUE
>     >>
>     >> I could also write my own function to loop through the list and stop
>     >> when I find it.  But I'd prefer to use built-in functionality if
> possible.
>     >>
>     >> Does anyone have any clues/see what I'm missing?
>     >>
>     >> cheers
>     >> Ben Bolker
>     >> -----BEGIN PGP SIGNATURE-----
>     >> Version: GnuPG v1.4.11 (GNU/Linux)
>     >>
>     >> iQEcBAEBAgAGBQJV3JQLAAoJEOCV5YRblxUHTEkIAJluX0F2bLGW1jt1FP2UEZs1
>     >> hucBzPGxpHdGE0CAE2Q2rPtKPmJsZdOpkpBPcxorLj4F6C70yY9QmdNlZ1i/spQB
>     >> k33EbUsD2XZGcfIVRGSnc1q9QS2vcWRuyC89GRle8xPVD8MfwiV/EMQi4hBk1v9q
>     >> TTOug7e1c+I+PtbvrQHpQrCc/1h609I7UqPCOdYbak3xwQC4VNSJ1A8n5w4N+RsV
>     >> UVEMkOmhLnwzk6pSSC0dbyOKUluklc5ZYBX8aEM0Cd9bUYhoqc2aXUc7ocsL3f9J
>     >> BHlDhy0kfjfwv4wqg/sFKLMIX2IQPxM2zrcd3v1hhEXOYGi7KoHHpZaihbFmEfQ=
>     >> =w3OR
>     >> -----END PGP SIGNATURE-----
>     >>
>     >> ______________________________________________
>     >> R-devel at r-project.org mailing list
>     >> https://stat.ethz.ch/mailman/listinfo/r-devel
>     >>
>
>     > [[alternative HTML version deleted]]
>
>     > ______________________________________________
>     > R-devel at r-project.org mailing list
>     > https://stat.ethz.ch/mailman/listinfo/r-devel
>

	[[alternative HTML version deleted]]



[Rd] match()/%in% with language objects?
William Dunlap