3

What are good ways to select multiple columns of a data frame in base R using the native pipe |>? (i.e., without the tidyverse/dplyr to reduce external dependencies).

If we have the data frame

dtf <- data.frame(a = 1:3, b = 4:6, c = 7:9)

then we can select columns b and c with

> dtf[c("b", "c")]
  b c
1 4 7
2 5 8
3 6 9

An elegant way to do this in the tidyverse with the native pipe is

> dtf |> dplyr::select(b, c)
  b c
1 4 7
2 5 8
3 6 9

My best base R attempt with the native pipe was

> dtf |> subset(select = c("b", "c"))
  b c
1 4 7
2 5 8
3 6 9

A more concise (but failed attempt) was

> dtf |> `[`(c("b", "c"))
Error: function '[' not supported in RHS call of a pipe

Are there better ways to do this that I'm missing?

Note: If you wanted only a single column and were okay with dropping into a vector, then getElement could be used:

> dtf |> getElement("b")
[1] 4 5 6
jfrench
  • 315
  • 1
  • 10
  • 3
    Something more elegant than the canonical use of `subset`? Nope, that's the best way in base R. (BTW, you can do `X <- \`[\`'; dtf |> X(c("b", "c"))` as a workaround for base R not wanting you to use `\`[\`` in a pipe like that. Suggested by a comment in [data.table#4872](https://github.com/Rdatatable/data.table/issues/4872#issuecomment-845022020).) – r2evans Jan 07 '22 at 17:52
  • 1
    Have a look here – TarJae Jan 07 '22 at 18:06
  • See: [Pipe purely in base R ('base pipe')?](https://stackoverflow.com/q/65329335/10488504) – GKi Apr 25 '22 at 19:17

2 Answers2

1

Here is one way:

dtf |> (\(x) `[`(x, c("b", "c")))()
#  b c
#1 4 7
#2 5 8
#3 6 9

You must use the anonymous function \(x) and pass it as an argument to [. Don't forget to end with the parenthesis ().

Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
  • Thanks @Rui for clarifying how to do this with the new anonymous function syntax. Very instructive. – jfrench Jan 07 '22 at 20:10
1

Just put brackets around:

dtf |> (`[`)(c("b", "c"))
#  b c
#1 4 7
#2 5 8
#3 6 9

or call it over :::

dtf |> base::`[`(c("b", "c"))
#  b c
#1 4 7
#2 5 8
#3 6 9
GKi
  • 37,245
  • 2
  • 26
  • 48