chipsin
chipsin

Reputation: 675

Sorting a specific range of column names in dplyr

I have a data frame and wish to sort specific columns alphabetically in dplyr. I know I can use the code below to sort all columns, but I would only like to sort columns C, B and A alphabetically. I tried using the across function as I would effectively like to select columns C:A, but this did not work.

df <- data.frame(1:16)
df$Testinfo1 <- 1
df$Band <- 1
df$Alpha <- 1
df$C <- c(10,12,14,16,10,12,14,16,10,12,14,16,10,12,14,16)
df$B <- c(10,0,0,0,12,12,12,12,0,14,NA_real_,14,16,16,16,16)
df$A <- c(1,1,1,1,1,1,1,1,1,1,1,14,NA_real_,NA_real_,NA_real_,16)
df

df %>% 
  select(sort(names(.)))

     A Alpha  B Band  C Testinfo1 X1.16
 1:  1     1 10    1 10         1     1
 2:  1     1  0    1 12         1     2
 3:  1     1  0    1 14         1     3
 4:  1     1  0    1 16         1     4
 5:  1     1 12    1 10         1     5
 6:  1     1 12    1 12         1     6
 7:  1     1 12    1 14         1     7
 8:  1     1 12    1 16         1     8
 9:  1     1  0    1 10         1     9
10:  1     1 14    1 12         1    10
11:  1     1 NA    1 14         1    11
12: 14     1 14    1 16         1    12
13: NA     1 16    1 10         1    13
14: NA     1 16    1 12         1    14
15: NA     1 16    1 14         1    15
16: 16     1 16    1 16         1    16

My desired output is below:

    X1.16 Testinfo1 Band Alpha  A  B  C
 1:     1         1    1     1  1 10 10
 2:     2         1    1     1  1  0 12
 3:     3         1    1     1  1  0 14
 4:     4         1    1     1  1  0 16
 5:     5         1    1     1  1 12 10
 6:     6         1    1     1  1 12 12
 7:     7         1    1     1  1 12 14
 8:     8         1    1     1  1 12 16
 9:     9         1    1     1  1  0 10
10:    10         1    1     1  1 14 12
11:    11         1    1     1  1 NA 14
12:    12         1    1     1 14 14 16
13:    13         1    1     1 NA 16 10
14:    14         1    1     1 NA 16 12
15:    15         1    1     1 NA 16 14
16:    16         1    1     1 16 16 16

Upvotes: 2

Views: 1980

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 389235

A base R option for a case which may or may not exist. If the columns that you want to sort are not at the end of the dataframe.

We add a new column D which you don't want to change the position of.

df$D <- 1:16
cols_to_sort <- c('A', 'B', 'C')
inds <- match(cols_to_sort, names(df))
cols <- seq_along(df)
cols[cols %in% inds] <- inds
df[cols]

#   X1.16 Testinfo1 Band Alpha  A  B  C  D
#1      1         1    1     1  1 10 10  1
#2      2         1    1     1  1  0 12  2
#3      3         1    1     1  1  0 14  3
#4      4         1    1     1  1  0 16  4
#5      5         1    1     1  1 12 10  5
#6      6         1    1     1  1 12 12  6
#7      7         1    1     1  1 12 14  7
#8      8         1    1     1  1 12 16  8
#9      9         1    1     1  1  0 10  9
#10    10         1    1     1  1 14 12 10
#11    11         1    1     1  1 NA 14 11
#12    12         1    1     1 14 14 16 12
#13    13         1    1     1 NA 16 10 13
#14    14         1    1     1 NA 16 12 14
#15    15         1    1     1 NA 16 14 15
#16    16         1    1     1 16 16 16 16

Upvotes: 2

lroha
lroha

Reputation: 34621

You can use relocate() (from dplyr 1.0.0 onwards):

library(dplyr)

vars <- c("C", "B", "A")

df %>% 
  relocate(all_of(sort(vars)), .after = last_col())

If you are passing a character vector of names you should wrap it in all_of() (which will error if any variables are missing) or any_of() which won't.

Upvotes: 8

MrFlick
MrFlick

Reputation: 206546

You can do

sortcols <- c("A","B","C")
library(dplyr)
df %>% 
  select(-sortcols, sort(sortcols))

The -sortcols part selects everything but the columns you want to sort and then you put the columns you want after those.

Upvotes: 3

Related Questions