4

I realize this question has been asked before but it's not clicking. There's really no placeholder?

Example:

my_mtcars <- mtcars %>% mutate(bla = c(1:nrow(.)))
my_mtcars$bla[10] <- NA
my_mtcars$bla[15] <- NA

Works:

# magritr pipe to return NA rows while debugging a df
my_mtcars %>% filter(!complete.cases(.)) %>% glimpse

Does not work:

# native piple equivilent
my_mtcars |> filter(!complete.cases(.)) |> glimpse()

What's the 'right' way to do what I'm trying to do with the native pipe?

Doug Fir
  • 19,971
  • 47
  • 169
  • 299
  • 2
    I'd argue the most "native" way currently is solution 2b in the [linked](https://stackoverflow.com/a/67638063/8107362) answer: e.g. `|> {function(x) grepl("at", x)}()`. Please note the `()` after the anonymous function, since you must call the function, not just define it – mnist Dec 07 '21 at 23:41
  • Be careful with your brackets/braces - `my_mtcars |> (\(x) filter(x, !complete.cases(x)))() |> glimpse()` – thelatemail Dec 07 '21 at 23:46
  • 1
    Perhaps this example may help, it requires setting the environment variable thelatemail mentioned. `1:5 |> (\(.) .*2)() |> x => (\`<<-\`)(y, x) |> z => (\`*\`)(z, 2) * y` – Donald Seinen Dec 08 '21 at 03:15

1 Answers1

5

The native R pipe does not use dot. It always inserts into the first argument. To get the effect of dot define a function or if it is at the beginning combine it yourself repeating the input (or break it up into two pipelines and do the same -- not shown since doesn't apply here).

library(dplyr)

mtcars |>
  (\(x) filter(x, complete.cases(x)))() |>
  summary()

or

f <- function(x) filter(x, complete.cases(x))
mtcars |> f() |> summary()

or

filter(mtcars, complete.cases(mtcars)) |> summary()

Sometimes with can be used to create a workaround. This creates a list with one element named x and then uses that in the next leg of the pipe.

mtcars |>
  list() |>
  setNames("x") |>
  with(filter(x, complete.cases(x))) |>
  summary()

Note that you can do this with only base R -- the Bizarro pipe which is not really a pipe but looks like one.

mtcars ->.;
  filter(., complete.cases(.)) ->.;
  summary(.)

Update

Since this question appeared R has added a _ placeholder so the with example could be shortened to:

# needs R 4.2 or later
mtcars |>
  list(x = _) |>
  with(filter(x, complete.cases(x))) |>
  summary()
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Hello, are you sure that the way you use complete.cases with the native pipe is robust? See the answer to my post here https://stackoverflow.com/a/72801062/2952838 . I think you would experience problems if in the tibble there was a column named "x". – larry77 Jun 29 '22 at 23:36
  • You can choose the name to be whatever you want. You don't have to use x. Use .x or something else unlikely to conflict if you are worried. – G. Grothendieck Jun 30 '22 at 12:25
  • Right, but if you look at the link I posted, it appears that with a simple !!x, you avoid any possible conflict. – larry77 Jul 07 '22 at 10:31
  • rlang only works in tidyverse so it is not a general solution. – G. Grothendieck Jul 07 '22 at 11:20
  • With `_` placeholder you need to pass the name of the argument that will receive the `_` placeholder. Like `x = _` in above case. – vasili111 Aug 31 '22 at 15:50