Introduction
R has some neat functions, and even some weird quirks, that you aren’t likely to discover on your own but can either be immensely helpful or horribly confounding.
For example, the “+” operator (i.e. addition) is actually a function, and can even be called using the typical “bracket” notation:
1 + 2
## [1] 3
We can use backticks to evaluate the function as a “regular” function:
`+`
## function (e1, e2) .Primitive("+")
And can therefore call it as a “regular” function, using brackets to pass the arguments:
`+`(1, 2)
## [1] 3
One consequence of this is that it is possible to redefine how “+” works:
`+` <- function(x1, x2) x1 - x2
1 + 2
## [1] -1
Ok … admittedly that’s confusing. Why would you want to redefine “+”? Well, one example is given by the syntax of the ggplot2
package, which defines it’s own version of “+” that lets you string plotting functions together to build up a plot (e.g. see my post about plotting here).
The %in%
function
The %in%
function is one of those functions that just clicked when I started using R. It’s an elegant way to write conditional statements – it checks whether the object to the left of the operator occurs anywhere in the object on the right of the operator. An example:
Does the number 5 occur in the vector of 1 through 10?
5 %in% 1:10
## [1] TRUE
Yes, it does (obviously).
One thing that I often find myself doing however, is wanting to know if something doesn’t occur in another object. To make that work, I usually wrap the whole statement in brackets and then precede with an !
operator (logical negation). Like this:
!(11 %in% 1:10)
## [1] TRUE
This evaluates to TRUE
because 11 is not in the vector 1:10. While this works, it’s always bugged me because it just looks inelegant.
Well, while browsing Twitter recently, I came across this post from [@groundwalkergmb](https://twitter.com/groundwalkergmb):
Am I the only one that always does
— Gabe Becker (@groundwalkergmb) November 13, 2019
if(!(blah %in% woo))
instead of
if(!blah %in% woo)
because the latter makes me really uncomfortable even though it works fine (and equivalently to the former)? #rstats
First, note the (confusing) syntax that you don’t actually have to negate the entire expression. It is equivalent to write:
!11 %in% 1:10
## [1] TRUE
Ew. Gross! (@groundwalkergmb agrees with me about this)
But reading through the comments led me to this one:
— Brandon Hurr (@bhive01) November 13, 2019
%nin% <- Negate(
%in%`)
if(blah %nin% woo) {}
Basically, you can use the Negate()
function (never knew about this before) to create a new function which returns the logical negation of the output of the original.
`%nin%`<- Negate(`%in%`)
11 %nin% 1:10
## [1] TRUE
What?!? pic.twitter.com/24udunAkgV
— Clark Richards, PhD (@ClarkGRichards) November 13, 2019