Question: Why does the colnames
function generate a tibble, when used with the pipe operator %>%
and the [
selector?
Example: Given the following tibble:
library(tidyverse)
x <- tribble(
~a, ~b,
1, 0,
0, 1
)
Problem: The colnames function generates a tibbe, when used with the pipe operator and the [
selector:
x %>% colnames(.)[1]
#> # A tibble: 2 x 1
#> a
#> <dbl>
#> 1 NA
#> 2 NA
Whereas I would expect it to generate a vector, as if no pipe operator was used:
colnames(x)[1]
#> [1] "a"
Because %>%
auto-inserts .
as the first parameter of the right-hand side, unless .
is already used as a top-level parameter of the right-hand side.
Your right-hand side is colnames(.)[1]
— and .
is not a top-level parameter here. In fact, the expression colnames(.)[1]
is exactly equivalent to
`[`(colnames(.), 1)
So the top-level parameters of this expression are colnames(.)
and 1
. Neither is .
. So %>%
transforms your expression to
`[`(x, colnames(x), 1)
Which is once again equivalent to
x[colnames(x), 1]
And that expression doesn’t really make sense, and happens to result in what you’ve observed.
To avoid .
auto-insertion, you can wrap the expression into {…}
as shown by akrun. Or you can split up the compound expressions into its constituent parts:
x %>% colnames() %>% `[`(1L)