Reputation: 1775
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
Reputation: 41
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
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
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