Bruno
Bruno

Reputation: 115

piping with dot inside dplyr::filter

I'm struggling to pipe stuff to another argument inside the function filter from dplyr using %>% margritr.

I would assume that this should work:

library(dplyr)
library(margritr)

d <- data.frame(a=c(1,2,3),b=c(4,5,6))
c(2,2) %>% filter(d, a %in% .)

But I get this:

# Error in UseMethod("filter_") : 
#  no applicable method for 'filter_' applied to an object of class "c('double', 'numeric')"

I would expect it to work in the same way as this:

filter(d, a %in% c(2,2))
#   a b
# 1 2 5

What am I doing wrong?

Upvotes: 5

Views: 1883

Answers (2)

Brian
Brian

Reputation: 8275

The pipe is designed to compose the function around its first argument when you pass it. When you want to circumvent this behavior, you can generate an anonymous environment that is more flexible. You do this with curly braces, just like when you're writing a function.

5 %>% 
  {filter(iris, Sepal.Length == .)}

For why this works, writing {somefunctions(x, y)} is equivalent to writing function(...) {somefunctions(x, y)}. So the function above ignores its arguments, but just evaluates the variables in its environment. The . pronoun is defined for it by the pipe, and it searches for other variables (like iris) in the global environment.

Upvotes: 8

Zafar
Zafar

Reputation: 2016

By default it will pipe to the first argument. The only way around it is to name the first arg explicitly:

c(2,2) %>% 
  filter(.data = d, a %in% .)

but looks like this doesn't work very well:

  a b
1 2 5
Warning message:
In (~.) & (~a %in% .) :
  longer object length is not a multiple of shorter object length

P.S. you don't need to load magrittr explicitly as %>% is already in dplyr

Upvotes: 0

Related Questions