3

How can I select all columns after a designated column using R (ideally dplyr only but non-dplyr solutions welcome). For example, say in the dataframe mtcars, I want to grab all columns after the vs that would be am gear carb. But I want a function to accomplish this wherein I simply feed the column of choice and the dataframe that's returned only includes those columns after the designated column. I cannot think of a way to accomplish this to get things going.

                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4

I'd like the result of the function to be the following (but im much less interested in the result than the logic as the result can be obtained in myriad ways but the logic is generalizable to complex cases (large number of columns, changing parameters, etc.).

                    am gear carb
Mazda RX4            1    4    4
Mazda RX4 Wag        1    4    4
Datsun 710           1    4    1
Hornet 4 Drive       0    3    1
Hornet Sportabout    0    3    2
Valiant              0    3    1
Duster 360           0    3    4
Cyrus Mohammadian
  • 4,982
  • 6
  • 33
  • 62
  • sorry, i should have been more clear, not necessarily a user defined function but something within dplyr's arsenal of functions/verbs). – Cyrus Mohammadian Jul 15 '21 at 15:38

4 Answers4

6

One option could be:

mtcars %>%
 select(vs:last_col(), -vs)

                    am gear carb
Mazda RX4            1    4    4
Mazda RX4 Wag        1    4    4
Datsun 710           1    4    1
Hornet 4 Drive       0    3    1
Hornet Sportabout    0    3    2
Valiant              0    3    1
Duster 360           0    3    4
Merc 240D            0    4    2
Merc 230             0    4    2

Or:

mtcars %>%
 select((which(names(.) == "vs") + 1):last_col())
tmfmnk
  • 38,881
  • 4
  • 47
  • 67
3

In base R you could do:

my_select <- function(data, col_after){
   data[-seq_len(grep(col_after, names(data)))]
}

my_select(head(mtcars), "vs")
                  am gear carb
Mazda RX4          1    4    4
Mazda RX4 Wag      1    4    4
Datsun 710         1    4    1
Hornet 4 Drive     0    3    1
Hornet Sportabout  0    3    2
Valiant            0    3    1

In dplyr you would do:

my_select1 <- function(data, col_after){
  data %>%
    select(!1:{{col_after}})
}

my_select1(head(mtcars), vs)
                 am gear carb
Mazda RX4          1    4    4
Mazda RX4 Wag      1    4    4
Datsun 710         1    4    1
Hornet 4 Drive     0    3    1
Hornet Sportabout  0    3    2
Valiant            0    3    1
Onyambu
  • 67,392
  • 3
  • 24
  • 53
1

You can first find the index of vs and use last_col like so:

library(tidyverse)
vs_index = which(colnames(mtcars)=="vs")
mtcars %>% 
        select((vs_index + 1):last_col())
bird
  • 2,938
  • 1
  • 6
  • 27
1

You could use match for this:

mtcars %>%
  select((match("vs", names(mtcars))+1):ncol(mtcars))
koolmees
  • 2,725
  • 9
  • 23