Pasting into tidyverse's select()

Viewed 702

The dataset I am working on looks like this

a   b     vara_1 vara_2 vara_3 vara_4 vara_5 .... varb_1 varb_2 varb_3 varb_4
-----------------------------------------------------------------------------
100 120   a      b      c      d      e           w      x      y      z

I would like to change the column order of a dataset according to this particular order generated by the paste0 function:

> paste0(c("vara_", "varb_"),rep(1:10, each=2))
 [1] "vara_1"  "varb_1"  "vara_2"  "varb_2"  "vara_3"  "varb_3"  "vara_4"  "varb_4"  "vara_5"  "varb_5" 
[11] "vara_6"  "varb_6"  "vara_7"  "varb_7"  "vara_8"  "varb_8"  "vara_9"  "varb_9"  "vara_10" "varb_10"

so the final look of the dataset would become

a   b     vara_1 varb_1 vara_2 varb_2 vara_3 varb_3 ....
-----------------------------------------------------------------------------
100 120   a      w      b      x      c      y  ....

is there anyway to put this into a format readable by tidyverse's select() function?

I have tried

condition <- paste0(c("vara_", "varb_"),rep(1:10, each=2)
data <- data %>% select(a, b, condition)

and also data <- data %>% noquote(select(a, b, condition)) with no luck.

Is the approach of listing out all the variable/ column orders possible for select()? Any help or alternative way of achieving the same goal is appreciated!

2 Answers

You should use select_at rather than select

Data

df <- data.frame(a=100, b=120, vara_1="a", vara_2 = "b", vara_3 = "c",
            varb_1 = "d", varb_2 = "e", varb_3 = "f")

    # a   b vara_1 vara_2 vara_3 varb_1 varb_2 varb_3
# 1 100 120      a      b      c      d      e      f

Specify columns

thesecols <- c("a", "b", paste0(c("vara_", "varb_"),rep(1:3, each=2)))

Using select_at

library(dplyr)
df %>%
    select_at(vars(thesecols))

    # a   b vara_1 varb_1 vara_2 varb_2 vara_3 varb_3
# 1 100 120      a      d      b      e      c      f

You can use syms with !!! to splice the column names with specific order in select function:

library(rlang)
condition <- paste0(c("vara_", "varb_"),rep(1:10, each=2))
data %>% select(a, b, !!!syms(condition))
#  a b vara_1 varb_1 vara_2 varb_2 vara_3 varb_3 vara_4 varb_4 vara_5 varb_5 vara_6 varb_6 vara_7 varb_7 vara_8 varb_8 vara_9 varb_9 vara_10 varb_10
#1 1 2      3     13      4     14      5     15      6     16      7     17      8     18      9     19     10     20     11     21      12      22

Dummy data:

dput(data)
structure(list(a = 1L, b = 2L, vara_1 = 3L, vara_2 = 4L, vara_3 = 5L, 
    vara_4 = 6L, vara_5 = 7L, vara_6 = 8L, vara_7 = 9L, vara_8 = 10L, 
    vara_9 = 11L, vara_10 = 12L, varb_1 = 13L, varb_2 = 14L, 
    varb_3 = 15L, varb_4 = 16L, varb_5 = 17L, varb_6 = 18L, varb_7 = 19L, 
    varb_8 = 20L, varb_9 = 21L, varb_10 = 22L), .Names = c("a", 
"b", "vara_1", "vara_2", "vara_3", "vara_4", "vara_5", "vara_6", 
"vara_7", "vara_8", "vara_9", "vara_10", "varb_1", "varb_2", 
"varb_3", "varb_4", "varb_5", "varb_6", "varb_7", "varb_8", "varb_9", 
"varb_10"), row.names = c(NA, -1L), class = "data.frame")
Related