1

I have a data frame, say mtcars:

> glimpse(mtcars)
Observations: 32
Variables: 11
$ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, …
$ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4
$ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 167.6, 167.6, 275.8, 275.8, 275.8, 472.0, 460.0, 440.0, 78.7, 75.7, 71.1, 120.1, 318.0,…
$ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109
$ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.07, 3.07, 2.93, 3.00, 3.23, 4.08, 4.93, 4.22, 3.70, 2.76, 3.15, 3.73, 3.08, …
$ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.440, 3.440, 4.070, 3.730, 3.780, 5.250, 5.424, 5.345, 2.200, 1.615, 1.835, 2.465, 3.5…
$ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18.30, 18.90, 17.40, 17.60, 18.00, 17.98, 17.82, 17.42, 19.47, 18.52, 19.90, 20.01, 16.…
$ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1
$ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1
$ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 4
$ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1, 2, 2, 4, 6, 8, 2

Suppose I want to reorder the features so that hp is the first column to appear in the data frame as opposed to mpg.

I know that I could use dplyr like so:

> glimpse(mtcars %>% select_at(vars(hp, mpg:disp, drat:carb)))
Observations: 32
Variables: 11
$ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109
$ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, …
$ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4
$ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 167.6, 167.6, 275.8, 275.8, 275.8, 472.0, 460.0, 440.0, 78.7, 75.7, 71.1, 120.1, 318.0,…
$ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.07, 3.07, 2.93, 3.00, 3.23, 4.08, 4.93, 4.22, 3.70, 2.76, 3.15, 3.73, 3.08, …
$ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.440, 3.440, 4.070, 3.730, 3.780, 5.250, 5.424, 5.345, 2.200, 1.615, 1.835, 2.465, 3.5…
$ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18.30, 18.90, 17.40, 17.60, 18.00, 17.98, 17.82, 17.42, 19.47, 18.52, 19.90, 20.01, 16.…
$ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1
$ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1
$ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 4
$ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1, 2, 2, 4, 6, 8, 2

Is there a shorter, more elegant way of doing this?

(tidyverse or base r solutions particularly welcome)

Doug Fir
  • 19,971
  • 47
  • 169
  • 299
  • 1
    `mtcars %>% select(hp, everything())` – camille Mar 08 '19 at 20:49
  • 1
    You generally only need `select_at` for helper functions, like `starts_with`. For simple column selection and bare column names, just use `select` – camille Mar 08 '19 at 20:50
  • Tyank you @camille. I never knew about everything(). I'll accept as answer if you want some SO karma brownie points? – Doug Fir Mar 08 '19 at 20:51
  • Related [Move a column conveniently](https://stackoverflow.com/questions/52096919/move-a-column-conveniently) – markus Mar 08 '19 at 20:59

2 Answers2

2
library(tidyverse)

mtcars %>% 
  select(hp, everything())
#>                      hp  mpg cyl  disp drat    wt  qsec vs am gear carb
#> Mazda RX4           110 21.0   6 160.0 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag       110 21.0   6 160.0 3.90 2.875 17.02  0  1    4    4
#> Datsun 710           93 22.8   4 108.0 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive      110 21.4   6 258.0 3.08 3.215 19.44  1  0    3    1
#> Hornet Sportabout   175 18.7   8 360.0 3.15 3.440 17.02  0  0    3    2
#> Valiant             105 18.1   6 225.0 2.76 3.460 20.22  1  0    3    1
#> Duster 360          245 14.3   8 360.0 3.21 3.570 15.84  0  0    3    4
#> Merc 240D            62 24.4   4 146.7 3.69 3.190 20.00  1  0    4    2
#> Merc 230             95 22.8   4 140.8 3.92 3.150 22.90  1  0    4    2
#> Merc 280            123 19.2   6 167.6 3.92 3.440 18.30  1  0    4    4
#> Merc 280C           123 17.8   6 167.6 3.92 3.440 18.90  1  0    4    4
#> Merc 450SE          180 16.4   8 275.8 3.07 4.070 17.40  0  0    3    3
#> Merc 450SL          180 17.3   8 275.8 3.07 3.730 17.60  0  0    3    3
#> Merc 450SLC         180 15.2   8 275.8 3.07 3.780 18.00  0  0    3    3
#> Cadillac Fleetwood  205 10.4   8 472.0 2.93 5.250 17.98  0  0    3    4
#> Lincoln Continental 215 10.4   8 460.0 3.00 5.424 17.82  0  0    3    4
#> Chrysler Imperial   230 14.7   8 440.0 3.23 5.345 17.42  0  0    3    4
#> Fiat 128             66 32.4   4  78.7 4.08 2.200 19.47  1  1    4    1
#> Honda Civic          52 30.4   4  75.7 4.93 1.615 18.52  1  1    4    2
#> Toyota Corolla       65 33.9   4  71.1 4.22 1.835 19.90  1  1    4    1
#> Toyota Corona        97 21.5   4 120.1 3.70 2.465 20.01  1  0    3    1
#> Dodge Challenger    150 15.5   8 318.0 2.76 3.520 16.87  0  0    3    2
#> AMC Javelin         150 15.2   8 304.0 3.15 3.435 17.30  0  0    3    2
#> Camaro Z28          245 13.3   8 350.0 3.73 3.840 15.41  0  0    3    4
#> Pontiac Firebird    175 19.2   8 400.0 3.08 3.845 17.05  0  0    3    2
#> Fiat X1-9            66 27.3   4  79.0 4.08 1.935 18.90  1  1    4    1
#> Porsche 914-2        91 26.0   4 120.3 4.43 2.140 16.70  0  1    5    2
#> Lotus Europa        113 30.4   4  95.1 3.77 1.513 16.90  1  1    5    2
#> Ford Pantera L      264 15.8   8 351.0 4.22 3.170 14.50  0  1    5    4
#> Ferrari Dino        175 19.7   6 145.0 3.62 2.770 15.50  0  1    5    6
#> Maserati Bora       335 15.0   8 301.0 3.54 3.570 14.60  0  1    5    8
#> Volvo 142E          109 21.4   4 121.0 4.11 2.780 18.60  1  1    4    2

Created on 2019-03-08 by the reprex package (v0.2.1)

dylanjm
  • 2,011
  • 9
  • 21
0

dplyr imports the tidyselect helper function everything, which, as its name implies, selects everything. This can be used in combination with other column selection, so that in this case, you select hp, then everything—since a column can only occur once, this takes on the meaning hp and then everything else.

library(dplyr)

mtcars %>%
  select(hp, everything()) %>%
  head()
#>                    hp  mpg cyl disp drat    wt  qsec vs am gear carb
#> Mazda RX4         110 21.0   6  160 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag     110 21.0   6  160 3.90 2.875 17.02  0  1    4    4
#> Datsun 710         93 22.8   4  108 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive    110 21.4   6  258 3.08 3.215 19.44  1  0    3    1
#> Hornet Sportabout 175 18.7   8  360 3.15 3.440 17.02  0  0    3    2
#> Valiant           105 18.1   6  225 2.76 3.460 20.22  1  0    3    1

A couple base R ways could involve cbinding columns based on position. In this case, hp is the 4th column, so I bind together the 4th column of mtcars with everything but the 4th column of mtcars (same output as above):

cbind(mtcars[4], mtcars[-4])

Or based on name, where I'm subsetting first for column names equal to "hp", then not equal to "hp":

cbind(mtcars[names(mtcars) == "hp"], mtcars[names(mtcars) != "hp"])

I'm sure there are other base R ways as well--definitely could rig something up with subset.

camille
  • 16,432
  • 18
  • 38
  • 60