Lorenzo Rigamonti
Lorenzo Rigamonti

Reputation: 1775

Sorting a data.frame in R maintaining row names

I have a data.frame with daily percentage returns of several Managers, I want to sort the data.frame so that to have, for example the best 5 performers and the worst 5 performers.

I found the function sort(x) or rev(sort(x)) but they do not maintain rownames and I need them in order to check the names of Managers.

Any tips?

Upvotes: 2

Views: 7720

Answers (3)

I found this in some other website and it worked for me:

If you select a single column, then the default is to drop the data.frame property.To suppress this behavior you can set drop = FALSE:

df.sort <- df[order(df[,"x"]), , drop = FALSE]

Upvotes: 4

chepyle
chepyle

Reputation: 996

I had the same problem, but none of the Q&A I've seen on SO have dealt with single column data frames. @eddi 's answer doesnt work when you only have one column:

df.2col <- data.frame(a = c(4:1), b = c(1:4), row.names = paste0('blah', c(1:4)))

print(df.2col[order(df$a),])

results in a nice sorted data frame:

      a b
blah4 1 4
blah3 2 3
blah2 3 2
blah1 4 1

BUT, with a single column,

df.1col <- data.frame(a = c(4:1), row.names = paste0('blah', c(1:4)))

print(df.1col[order(df$a),])

the row names are trashed:

[1] 1 2 3 4

the kludgy solution I've had to resort to was sorting both data and rows:

df.sorted<-data.frame(a=df.1col$a[order(df.1col$a)],row.names=row.names(df.1col)[order(df.1col$a)])

print(df.sorted)

The desired result:

      a
blah4 1
blah3 2
blah2 3
blah1 4

If there is a better way to do this, I would appreciate any guidance

Upvotes: 3

eddi
eddi

Reputation: 49448

You want order:

df = data.frame(a = c(4:1), b = c(1:4), row.names = paste0('blah', c(1:4)))
df
#      a b
#blah1 4 1
#blah2 3 2
#blah3 2 3
#blah4 1 4

df[order(df$a),]
#      a b
#blah4 1 4
#blah3 2 3
#blah2 3 2
#blah1 4 1

Upvotes: 2

Related Questions