5

I'm seeing some unexpected behavior with dplyr. I have a specific use case but I will setup a dummy problem to illustrate my point. Why does this work,

library(dplyr)
temp <- bind_cols(mtcars %>% select(-mpg), mtcars %>% select(mpg))
head(temp)

cyl  disp  hp drat    wt  qsec vs am gear carb  mpg
6 160.0 110 3.90 2.620 16.46  0  1    4    4 21.0
6 160.0 110 3.90 2.875 17.02  0  1    4    4 21.0

But not this,

library(dplyr)
temp <- mtcars %>% bind_cols(. %>% select(-mpg), . %>% select(mpg))

Error in cbind_all(x) : Argument 2 must be length 1, not 32

Thanks for the help.

Taran
  • 265
  • 1
  • 11
  • 1
    @markdly if you examine your solution using `mtcars %>% bind_cols(select(., -mpg), select(., mpg))` the result isnt correct. It simply applies bind_cols to 2 copies of mtcars. i.e. the select is ignored – Taran Dec 14 '17 at 22:02
  • oops! yes you're right – markdly Dec 14 '17 at 22:06

2 Answers2

3

You need to wrap your function with {} to pipe mtcars into a function within another function like the following:

library(dplyr)

temp1 = mtcars %>% {bind_cols(select(., -mpg), select(., mpg))}
temp2 = bind_cols(mtcars %>% select(-mpg), mtcars %>% select(mpg))

# > identical(temp1, temp2)
# [1] TRUE
acylam
  • 18,231
  • 5
  • 36
  • 45
  • Yea that seems to do better. But using this `mtcars %>% {bind_cols(. %>% select(-mpg), . %>% select(mpg))}` still fails with `Error in cbind_all(x) : STRING_ELT() can only be applied to a 'character vector', not a 'NULL' `. Thoughts? – Taran Dec 14 '17 at 22:10
  • @Taran Yea, not too sure why this doesn't work. my solution has less typing though. – acylam Dec 14 '17 at 22:15
  • 1
    true! Its curious though. Thanks for the correct solution! – Taran Dec 14 '17 at 22:15
0

Another solution:

myfun <- function(x) {
  bind_cols(x %>% select(-mpg), x %>% select(mpg))
}
temp <- mtcars %>% myfun
Marco Sandri
  • 23,289
  • 7
  • 54
  • 58