Sorting

Problem

You want to sort a vector, matrix, or data frame.

Solution

Vectors

  1. # Make up a randomly ordered vector
  2. v <- sample(101:110)
  3. # Sort the vector
  4. sort(v)
  5. #> [1] 101 102 103 104 105 106 107 108 109 110
  6. # Reverse sort
  7. sort(v, decreasing=TRUE)
  8. #> [1] 110 109 108 107 106 105 104 103 102 101

Data frames

To sort a data frame on one or more columns, you can use the arrange function from plyr package, or use R’s built-in functions. The arrange function is much easier to use, but does require the external package to be installed.

  1. # Make a data frame
  2. df <- data.frame (id=1:4,
  3. weight=c(20,27,24,22),
  4. size=c("small", "large", "medium", "large"))
  5. df
  6. library(plyr)
  7. # Sort by weight column. These have the same result.
  8. arrange(df, weight) # Use arrange from plyr package
  9. df[ order(df$weight), ] # Use built-in R functions
  10. #> id weight size
  11. #> 1 1 20 small
  12. #> 2 4 22 large
  13. #> 3 3 24 medium
  14. #> 4 2 27 large
  15. # Sort by size, then by weight
  16. arrange(df, size, weight) # Use arrange from plyr package
  17. df[ order(df$size, df$weight), ] # Use built-in R functions
  18. #> id weight size
  19. #> 4 4 22 large
  20. #> 2 2 27 large
  21. #> 3 3 24 medium
  22. #> 1 1 20 small
  23. # Sort by all columns in the data frame, from left to right
  24. df[ do.call(order, as.list(df)), ]
  25. # In this particular example, the order will be unchanged

Note that the size column is a factor and is sorted by the order of the factor levels. In this case, the levels were automatically assigned alphabetically (when creating the data frame), so large is first and small is last.

Reverse sort

The overall order of the sort can be reversed with the argument decreasing=TRUE.

To reverse the direction of a particular column, the method depends on the data type:

  • Numbers: put a - in front of the variable name, e.g. df[ order(-df$weight), ].
  • Factors: convert to integer and put a - in front of the variable name, e.g. df[ order(-xtfrm(df$size)), ].
  • Characters: there isn’t a simple way to do this. One method is to convert to a factor first and then sort as above.
  1. # Reverse sort by weight column. These all have the same effect:
  2. arrange(df, -weight) # Use arrange from plyr package
  3. df[ order(df$weight, decreasing=TRUE), ] # Use built-in R functions
  4. df[ order(-df$weight), ] # Use built-in R functions
  5. #> id weight size
  6. #> 2 2 27 large
  7. #> 3 3 24 medium
  8. #> 4 4 22 large
  9. #> 1 1 20 small
  10. # Sort by size (increasing), then by weight (decreasing)
  11. arrange(df, size, -weight) # Use arrange from plyr package
  12. df[ order(df$size, -df$weight), ] # Use built-in R functions
  13. #> id weight size
  14. #> 2 2 27 large
  15. #> 4 4 22 large
  16. #> 3 3 24 medium
  17. #> 1 1 20 small
  18. # Sort by size (decreasing), then by weight (increasing)
  19. # The call to xtfrm() is needed for factors
  20. arrange(df, -xtfrm(size), weight) # Use arrange from plyr package
  21. df[ order(-xtfrm(df$size), df$weight), ] # Use built-in R functions
  22. #> id weight size
  23. #> 1 1 20 small
  24. #> 3 3 24 medium
  25. #> 4 4 22 large
  26. #> 2 2 27 large