1

I'd like to sort each row of a data frame without losing the column names in R.
I know that this accepted answer works, but this method doesn't keep the names, as shown below:

data_5x3.csv

A,B,C,D,E
5,1,3,2,8
4,3,9,1,6
7,5,2,9,4

My code:

df <- read.csv("data_5x3.csv")

df
#   A B C D E
# 1 5 1 3 2 8
# 2 4 3 9 1 6
# 3 7 5 2 9 4

names(df)
# [1] "A" "B" "C" "D" "E"

sorted_df <- t(apply(df, 1, sort))

sorted_df
#       [,1] [,2] [,3] [,4] [,5]
# [1,]    1    2    3    5    8
# [2,]    1    3    4    6    9
# [3,]    2    4    5    7    9

names(sorted_df)
# NULL

Now the names are gone.
How can we prevent from losing the names?

IanHacker
  • 507
  • 8
  • 25

3 Answers3

3

Store the names and apply them:

nm = names(df)
sorted_df <- as.data.frame(t(apply(df, 1, sort)))
names(sorted_df) = nm

You could compress this down to a single line if you prefer:

sorted_df = setNames(as.data.frame(t(apply(df, 1, sort))), names(df))
Gregor Thomas
  • 119,032
  • 17
  • 152
  • 277
1

Another possible solution:

library(dplyr)

df %>% apply(1, sort) %>% t %>% `colnames<-`(colnames(df))

#>      A B C D E
#> [1,] 1 2 3 5 8
#> [2,] 1 3 4 6 9
#> [3,] 2 4 5 7 9
PaulS
  • 10,636
  • 1
  • 7
  • 20
0

You can try order + row like below

m <- t(df)
df[] <- t(`dim<-`(m[order(col(m), m)], dim(m)))

and you wil obtain

> df
  A B C D E
1 1 2 3 5 8
2 1 3 4 6 9
3 2 4 5 7 9
ThomasIsCoding
  • 80,151
  • 7
  • 17
  • 65