11

I am taking a list of values and trying to find those that are not NA using magrittr. Here is a simple example:

data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% is.na

which yields the correct result:

      data
[1,] FALSE
[2,] FALSE
[3,]  TRUE
[4,] FALSE
[5,] FALSE
[6,]  TRUE
[7,] FALSE

When I put the not operator ! in front of is.na, I get an error:

data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% !is.na

gives me

Error in FUN(left, right) : operations are possible only for numeric, logical or complex types

After many trials, I stumbled upon this, which works:

 data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% is.na %>% !.

      data
[1,]  TRUE
[2,]  TRUE
[3,] FALSE
[4,]  TRUE
[5,]  TRUE
[6,] FALSE
[7,]  TRUE

My question is whether there is a different way to do this. There are other alias options in the package but I don't see any examples of them. One is "not". Maybe I should be using that instead?

I realize that I have answered my question to some degree, but I would like to know if this can be done without having to resort to %>% !. at the end.

Mark Danese
  • 2,331
  • 1
  • 20
  • 25

3 Answers3

7

You can use backticks to pipe your result into the function underlying the operator:

> data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% is.na %>% `!`
      data
[1,]  TRUE
[2,]  TRUE
[3,] FALSE
[4,]  TRUE
[5,]  TRUE
[6,] FALSE
[7,]  TRUE

Alternatively use the Negate function:

> data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% Negate(is.na)()
      data
[1,]  TRUE
[2,]  TRUE
[3,] FALSE
[4,]  TRUE
[5,]  TRUE
[6,] FALSE
[7,]  TRUE
jdharrison
  • 30,085
  • 4
  • 77
  • 89
  • 2
    OK. That makes sense. That works and I also replaced `\`!`\` with `not` which also works. And that explains the purpose of the alias. – Mark Danese Aug 17 '14 at 00:40
  • Yes `not` is defined as `function (x) .Primitive("!")` which is the same as calling the function underlying the `!` operator. – jdharrison Aug 17 '14 at 00:48
  • 1
    I also considered adding ...not as an alias to make it really expressive ;) – Stefan Aug 17 '14 at 07:03
  • I like this answer because it both leaves the operator in the location where you'd "expect" to read it and because it shows how to separate an operator from the `magrittr` pipe operators. – Carl Witthoft Aug 17 '14 at 12:13
  • Both of these answers are good. I would accept both if I could. – Mark Danese Aug 17 '14 at 19:37
5

Why not just move the negation to the "front". This is how you typically negate the %in% infix operatiuon

 !data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% is.na

      data
[1,]  TRUE
[2,]  TRUE
[3,] FALSE
[4,]  TRUE
[5,]  TRUE
[6,] FALSE
[7,]  TRUE
IRTFM
  • 258,963
  • 21
  • 364
  • 487
5

Or even

data.frame(data = c(1:2, NA, 4:5, NA, 7)) %>% 
  is.na %>% 
 `n'est pas`
Stefan
  • 1,835
  • 13
  • 20