Sort columns of a dataframe by column name
Asked Answered
H

11

120

This is possibly a simple question, but I do not know how to order columns alphabetically.

test = data.frame(C = c(0, 2, 4, 7, 8), A = c(4, 2, 4, 7, 8), B = c(1, 3, 8, 3, 2))

#   C A B
# 1 0 4 1
# 2 2 2 3
# 3 4 4 8
# 4 7 7 3
# 5 8 8 2

I like to order the columns by column names alphabetically, to achieve

#   A B C
# 1 4 1 0
# 2 2 3 2
# 3 4 8 4
# 4 7 3 7
# 5 8 2 8

For others I want my own defined order:

#   B A C
# 1 4 1 0
# 2 2 3 2
# 3 4 8 4
# 4 7 3 7
# 5 8 2 8

Please note that my datasets are huge, with 10000 variables. So the process needs to be more automated.

Honegger answered 7/9, 2011 at 13:27 Comment(0)
E
156

You can use order on the names, and use that to order the columns when subsetting:

test[ , order(names(test))]
  A B C
1 4 1 0
2 2 3 2
3 4 8 4
4 7 3 7
5 8 2 8

For your own defined order, you will need to define your own mapping of the names to the ordering. This would depend on how you would like to do this, but swapping whatever function would to this with order above should give your desired output.

You may for example have a look at Order a data frame's rows according to a target vector that specifies the desired order, i.e. you can match your data frame names against a target vector containing the desired column order.

Eclipse answered 7/9, 2011 at 13:46 Comment(7)
To elaborate, test[,c(2,3,1)] or test[,c('A','B','C')] will produce A,B,C column order. The "[" operator is very clever at figuring out what you want to do.Charlinecharlock
thank you, I figured out the second question with help provided; myorder = c("B", "A", "C"), test[,myorder]Honegger
Is there a way to sort the columns in a way I want (say C A B)?Gerdi
You can take advantage of the fact that a data.frame is a list and make it simpler:: test[ order(names(test)) ]Sabadell
What is the difference between using names() vs colnames() here?Eidetic
@Eidetic None, read the source of colnames: it ends up calling names for a data.frame.Eclipse
Is there way to make the ordering numerical? I have var names as "q" then a number 1 - 80 I need ordered and the ordering goes 1, 10, 11... so on which is wrong. I need 1,2 3...so onLepidopteran
B
49

Here's the obligatory dplyr answer in case somebody wants to do this with the pipe.

test %>% 
    select(sort(names(.)))
Brewing answered 16/8, 2018 at 20:57 Comment(1)
For me this worked well since it's easy to select the variables I want first. Sticking to the original df: test%>%select(b,sort(names(.))) will put it as "b,a,c"Neural
M
17
test = data.frame(C=c(0,2,4, 7, 8), A=c(4,2,4, 7, 8), B=c(1, 3, 8,3,2))

Using the simple following function replacement can be performed (but only if data frame does not have many columns):

test <- test[, c("A", "B", "C")]

for others:

test <- test[, c("B", "A", "C")]
Mandrake answered 1/4, 2014 at 20:4 Comment(0)
H
11

An alternative option is to use str_sort() from library stringr, with the argument numeric = TRUE. This will correctly order column that include numbers not just alphabetically:

str_sort(c("V3", "V1", "V10"), numeric = TRUE)

# [1] V1 V3 V10

Henchman answered 19/5, 2019 at 8:27 Comment(0)
P
8
  test[,sort(names(test))]

sort on names of columns can work easily.

Prenotion answered 18/11, 2017 at 18:9 Comment(0)
F
6

If you only want one or more columns in the front and don't care about the order of the rest:

require(dplyr)
test %>%
  select(B, everything())
Fatal answered 27/10, 2018 at 10:12 Comment(0)
S
4

So to have a specific column come first, then the rest alphabetically, I'd propose this solution:

test[, c("myFirstColumn", sort(setdiff(names(test), "myFirstColumn")))]
Snead answered 28/6, 2019 at 15:3 Comment(1)
and if you want more than one column to be first, then what?Downturn
L
2

Here is what I found out to achieve a similar problem with my data set.

First, do what James mentioned above, i.e.

test[ , order(names(test))]

Second, use the everything() function in dplyr to move specific columns of interest (e.g., "D", "G", "K") at the beginning of the data frame, putting the alphabetically ordered columns after those ones.

select(test, D, G, K, everything())

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Lueluebke answered 25/7, 2017 at 16:51 Comment(0)
S
1

Similar to other syntax above but for learning - can you sort by column names?

sort(colnames(test[1:ncol(test)] ))
Skinner answered 15/3, 2019 at 20:32 Comment(1)
The [1:ncol(test)] isn't doing anything here, it's just a longer way to write sort(colnames(test)).Levison
D
1

another option is..

mtcars %>% dplyr::select(order(names(mtcars)))
Deforest answered 6/5, 2022 at 0:47 Comment(0)
A
0

In data.table you can use the function setcolorder:

setcolorder reorders the columns of data.table, by reference, to the new order provided.

Here a reproducible example:

library(data.table)
test = data.table(C = c(0, 2, 4, 7, 8), A = c(4, 2, 4, 7, 8), B = c(1, 3, 8, 3, 2))
setcolorder(test, c(order(names(test))))
test
#>    A B C
#> 1: 4 1 0
#> 2: 2 3 2
#> 3: 4 8 4
#> 4: 7 3 7
#> 5: 8 2 8

Created on 2022-07-10 by the reprex package (v2.0.1)

Alva answered 10/7, 2022 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.