thanks. What if the data is stored in a csv file and I don't know eactly how many numbers each class has.
Hi, I have a csv file like this:
order class value
1 a 5
2 a 6
3 a 4
4 b 10
5 b 7
6 b 18
now I want to order this by the each class and its values:
order class value
3 a 4
1 a 5
2 a 6
5 b 7
4 b 10
6 b 18
how to do this in R? Thanks!
3 answers
#/ Data:
df <-
data.frame(order=seq(1,6),
class=rep(c("a", "b"), each=3),
value=c(5,6,4,10,7,18))
#/ Base R ::: https://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-multiple-columns
df[with(df, order(class, value)), ]
#/ dplyr ::: https://dplyr.tidyverse.org/reference/arrange.html
library(dplyr)
df %>% arrange(class, value)
As usual the base solution is much faster compared to dplyr (tidyverse). Still, with multiple filtering conditions and with operations up- and downstream of this command the tidyverse syntax / verbs can be more convenient to write and easier to read, so exactly what the tidyverse has been developed for (it has not been developed for speed, this is a common misconception from what I understand).
library(microbenchmark)
base=function(x) df[with(df, order(class, value)),]
tidy=function(x) df %>% arrange(class, value)
microbenchmark(base=base(), tidy=tidy())
Unit: microseconds
expr min lq mean median uq max neval
base 59.125 71.5165 96.27901 79.3505 88.886 1680.796 100
tidy 1611.210 1782.8240 1941.95609 1887.5755 1937.872 7368.565 100
I don't know eactly how many numbers each class has.
What does that mean?
I'm on the the data.table camp which is usually faster and, in my opinion, more readable than base R or dplyr. In this case:
df[order(class, value), ]
dplyr (which I haven't really used) seems to have too many dedicated functions and idioms for common tasks, like arrange, filter and I feel I need to re-learn what I already know. I don;t get that with data.table like in this example.
> library(sqldf)
> df
order class value
1 1 a 5
2 2 a 6
3 3 a 4
4 4 b 10
5 5 b 7
6 6 b 18
> sqldf("select * from df order by class, value")
order class value
1 3 a 4
2 1 a 5
3 2 a 6
4 5 b 7
5 4 b 10
6 6 b 18
> sqldf("select * from df order by class asc, value asc")
that really helps! do you know how to do the reverse order, from the biggest value to the smallest value
If you want to sort only values in descending order:
sqldf("select * from df order by class, value desc")
If you want to sort both class and value by desc
sqldf("select * from df order by class desc, value desc")
if you want class to be desc, but value to be in ascening order:
sqldf("select * from df order by class desc, value")
thanks! what if I want value in descending order, but class in a given order, like "b b b a a a c c c " but not "aaa bbb ccc"
Log in to answer this question.