Skip to content

"not in" operator %!in% #4152

Description

@jangorecki

FR to propose a not-in operator

`%!in%` = function(x, y) !(x%in%y)

Motivation is to have a single call that we could optimise. Otherwise we have to investigate unevaluated expression tree more deeply (and in a much more complex way) to know when user is doing a not-in operation.
Pseudo code in R C api

CAR(x %!in% 1:10)
#`%!in%`
CAR(! x %in% 1:10)
#`!`

Activity

  1. changed the title [-]"not in" operator[/-] [+]"not in" operator `%!in%`[/+] on Dec 31, 2019
  2. jangorecki commented on Jan 2, 2020

    @jangorecki
    MemberAuthor

    Actually we still need to handle ! because !x%in% was just one example, another example is !x%like%y (where we would need x%!like%y). It is definitely not robust to ask users to rewrite their code from base R style to our functions so we can optimize them. And it turns out it was not that difficult to handle !. I will leave this issue open because there are upvotes, so it seems such helper function might be useful anyway.

  3. jaapwalhout commented on Jan 5, 2020

    @jaapwalhout

    Such a function is certainly useful! I would prefer to write it as %nin% though, which is easier to type (imho)

  4. legendre6891 commented on Mar 6, 2021

    @legendre6891

    I would really welcome the addition of %notin%, even if unoptimized; it is quite handy to have.

  5. added a commit that references this issue on Mar 7, 2021
    1561017
  6. mczek commented on Mar 9, 2021

    @mczek
    Contributor

    I've been working on this and I'm wondering if someone can explain something for me. How does this function call get evaluated?
    chmatch("a", c(), 5)
    It returns 5, but as far as I can tell it dispatches to chmatchMain and it should return a vector allocVector(chin?LGLSXP:INTSXP, xlen) of length 0 which is logical(0) but somehow it returns 5 from R. There's no reference to the nomatch parameter before it returns.

  7. MichaelChirico commented on Mar 9, 2021

    @MichaelChirico
    Member

    That's happening here:

    data.table/src/chmatch.c

    Lines 30 to 36 in 788c585

    const int tablelen = length(table);
    if (tablelen==0) {
    const int val=(chin?0:nomatch), n=xlen;
    for (int i=0; i<n; ++i) ansd[i]=val;
    UNPROTECT(nprotect);
    return ans;
    }

    Note that this does match the corresponding match() behavior:

    match("a", NULL, 5)
    # [1] 5
    
  8. added this to the 1.14.3 milestone on Jul 19, 2022
  9. modified the milestones: 1.14.9, 1.15.0 on Oct 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions