R – Sort Data Frame by Column

In R, you can sort a data frame by one or more columns using the base R order() function. This tutorial shows how to sort a data frame by column in ascending order, descending order, and by multiple columns, with examples that use row indexing and with().

A data frame stores data in rows and columns, where each column has the same number of values. Sorting a data frame means changing the row order based on the values in one or more columns.

Let us take a data frame as shown in the following.

</>
Copy
df <- data.frame(names = c("Andrew", "Mathew", "Dany", "Philip", "John", "Bing", "Monica"),
		age = c(28, 23, 49, 29, 38, 23, 29),
		income = c(25.2, 10.5, 11, 21.9, 44, 11.5, 45))

The data frame has three columns: names, age, and income.

We will sort these columns in ascending or descending order in the following examples.

Sort an R Data Frame by One Column in Ascending Order

The syntax to sort a data frame by column in ascending order is:

</>
Copy
dataframe_name[with(dataframe_name, order(column_name)), ]

The expression order(column_name) returns the row positions in sorted order. The data frame is then indexed with those row positions, while the comma keeps all columns.

Example 1 – Sort R Data Frame by Column in Ascending Order

In this example, we will sort our data frame in ascending order.

r_dataframe_sort_asc.R

</>
Copy
# R program to sort data frame by column in ascending order

df <- data.frame(names = c("Andrew", "Mathew", "Dany", "Philip", "John", "Bing", "Monica"),
		age = c(28, 23, 49, 29, 38, 23, 29),
		income = c(25.2, 10.5, 11, 21.9, 44, 11.5, 45))


cat("\n\n Sort data frame by names in ascending order\n")
# to sort data frame by names in ascending order
df_sorted_names_asc <- df[with(df, order(names)), ]

print(df_sorted_names_asc)


cat("\n\n Sort data frame by age in ascending order\n")
# to sort data frame by age in ascending order
df_sorted_age_asc <- df[with(df, order(age)), ]

print(df_sorted_age_asc)


cat("\n\n Sort data frame by income in ascending order\n")
# to sort data frame by income in ascending order
df_sorted_asc <- df[with(df, order(income)), ]

print(df_sorted_asc)

Output

$ Rscript r_dataframe_sort_asc.R 


 Sort data frame by names in ascending order
   names age income
1 Andrew  28   25.2
6   Bing  23   11.5
3   Dany  49   11.0
5   John  38   44.0
2 Mathew  23   10.5
7 Monica  29   45.0
4 Philip  29   21.9


 Sort data frame by age in ascending order
   names age income
2 Mathew  23   10.5
6   Bing  23   11.5
1 Andrew  28   25.2
4 Philip  29   21.9
7 Monica  29   45.0
5   John  38   44.0
3   Dany  49   11.0


 Sort data frame by income in ascending order
   names age income
2 Mathew  23   10.5
3   Dany  49   11.0
6   Bing  23   11.5
4 Philip  29   21.9
1 Andrew  28   25.2
5   John  38   44.0
7 Monica  29   45.0

In the first sorted data frame, rows are arranged alphabetically by names. In the second sorted data frame, rows are arranged from the smallest age to the largest age. In the third sorted data frame, rows are arranged from the smallest income to the largest income.

Sort an R Data Frame by Numeric Column in Descending Order

The syntax to sort a data frame in descending order is

</>
Copy
dataframe_name[with(dataframe_name, order(-column_name)), ]

Please observe the ‘-‘ negative sign before the column_name to sort in descending order

Example 2 – Sort R Data Frame by Numeric Column in Descending Order

In this example, we will sort our Data Frame in descending order.

r_dataframe_sort_desc.R

</>
Copy
# R program to sort dataframe by column in descending order

df <- data.frame(names = c("Andrew", "Mathew", "Dany", "Philip", "John", "Bing", "Monica"),
		age = c(28, 23, 49, 29, 38, 23, 29),
		income = c(25.2, 10.5, 11, 21.9, 44, 11.5, 45))


cat("\n\n Sort data frame by names in descending order\n")
# to sort data frame by names in descending order
df_sorted_names_desc <- df[with(df, order(-names)), ]

print(df_sorted_names_desc)


cat("\n\n Sort data frame by age in descending order\n")
# to sort data frame by age in descending order
df_sorted_age_desc <- df[with(df, order(-age)), ]

print(df_sorted_age_desc)


cat("\n\n Sort data frame by income in descending order\n")
# to sort data frame by income in descending order
df_sorted_desc <- df[with(df, order(-income)), ]

print(df_sorted_desc)

Output

$ Rscript r_dataframe_sort_desc.R 


 Sort data frame by names in descending order
Warning message:
In Ops.factor(names) : ‘-’ not meaningful for factors
   names age income
1 Andrew  28   25.2
2 Mathew  23   10.5
3   Dany  49   11.0
4 Philip  29   21.9
5   John  38   44.0
6   Bing  23   11.5
7 Monica  29   45.0


 Sort data frame by age in descending order
   names age income
3   Dany  49   11.0
5   John  38   44.0
4 Philip  29   21.9
7 Monica  29   45.0
1 Andrew  28   25.2
2 Mathew  23   10.5
6   Bing  23   11.5


 Sort data frame by income in descending order
   names age income
7 Monica  29   45.0
5   John  38   44.0
1 Andrew  28   25.2
4 Philip  29   21.9
6   Bing  23   11.5
3   Dany  49   11.0
2 Mathew  23   10.5

Note : Descending order is not applicable for Character Datatypes. Observe lines (5,6) with a warning message.

Correct Way to Sort Character Columns in Descending Order in R

For character or factor columns, do not use the unary minus sign. Use decreasing = TRUE inside order(). This works for both numeric and character columns.

</>
Copy
df_sorted_names_desc <- df[with(df, order(names, decreasing = TRUE)), ]
print(df_sorted_names_desc)

Output

   names age income
4 Philip  29   21.9
7 Monica  29   45.0
2 Mathew  23   10.5
5   John  38   44.0
3   Dany  49   11.0
6   Bing  23   11.5
1 Andrew  28   25.2

For numeric columns, both order(-age) and order(age, decreasing = TRUE) can arrange rows in descending order. For character columns, prefer order(names, decreasing = TRUE).

Sort an R Data Frame by Multiple Columns

You can pass more than one column to order() when rows should be sorted by a primary column and then by a secondary column. For example, if two people have the same age, you can sort those rows by income.

</>
Copy
df_sorted_age_income <- df[with(df, order(age, income)), ]
print(df_sorted_age_income)

Output

   names age income
2 Mathew  23   10.5
6   Bing  23   11.5
1 Andrew  28   25.2
4 Philip  29   21.9
7 Monica  29   45.0
5   John  38   44.0
3   Dany  49   11.0

Here, age is the first sorting column. Where age values are equal, income is used as the next sorting column.

Sort One R Data Frame Column Ascending and Another Column Descending

To sort by mixed directions in base R, use decreasing with a vector of logical values. The following example sorts age in ascending order and income in descending order within the same age group.

</>
Copy
df_sorted_mixed <- df[with(df, order(age, income, decreasing = c(FALSE, TRUE))), ]
print(df_sorted_mixed)

Output

   names age income
6   Bing  23   11.5
2 Mathew  23   10.5
1 Andrew  28   25.2
7 Monica  29   45.0
4 Philip  29   21.9
5   John  38   44.0
3   Dany  49   11.0

Sort an R Data Frame with dplyr arrange()

If your project already uses the tidyverse, you can sort a data frame using arrange() from dplyr. In dplyr, ascending order is the default, and desc() is used for descending order.

</>
Copy
library(dplyr)

# Sort by age in ascending order
df_sorted_age <- arrange(df, age)

# Sort by income in descending order
df_sorted_income_desc <- arrange(df, desc(income))

# Sort by age ascending, then income descending
df_sorted_age_income <- arrange(df, age, desc(income))

Use base R order() when you want a solution that does not require additional packages. Use dplyr::arrange() when you are already working with tidyverse-style data transformation code.

Common Mistakes While Sorting a Data Frame by Column in R

  • Using minus on a character column: Use decreasing = TRUE instead of -names.
  • Forgetting the comma in row indexing: Use df[order(df$age), ]. Without the comma, R treats the expression as column indexing.
  • Expecting the original data frame to change automatically: Sorting returns a new row order. Assign it back to the same object if you want to replace the original data frame.
  • Sorting numbers stored as text: Convert numeric-looking character values to numeric before sorting, otherwise sorting may happen alphabetically.

FAQ on Sorting Data Frames by Column in R

How do I sort a data frame by a column in R?

Use df[order(df$column_name), ] or df[with(df, order(column_name)), ]. This arranges the rows based on the selected column and keeps all columns in the result.

How do I sort an R data frame in descending order?

For numeric columns, you can use df[order(-df$age), ]. For a safer approach that also works with character columns, use df[order(df$age, decreasing = TRUE), ].

How do I sort a data frame by multiple columns in R?

Pass multiple columns to order(), such as df[with(df, order(age, income)), ]. R sorts by the first column, then uses the next column to break ties.

How do I sort one column ascending and another descending in R?

Use order() with a logical vector for decreasing, such as order(age, income, decreasing = c(FALSE, TRUE)). This sorts age ascending and income descending.

Does sorting a data frame by column change the original data frame?

No. The sorted result is returned as a new object unless you assign it back. For example, df <- df[order(df$age), ] replaces df with the sorted version.

Editorial QA Checklist for This R Data Frame Sorting Tutorial

  • Verify that base R examples use row indexing in the form data_frame[row_order, ].
  • Confirm that descending examples explain the difference between numeric columns and character columns.
  • Check that multiple-column sorting examples clearly identify the primary and secondary sort columns.
  • Ensure new output blocks use the output class and new R code blocks use language-r.
  • Confirm that the tutorial keeps the distinction between base R order() and dplyr::arrange() clear.

Conclusion

In this R Tutorial, we have learnt to sort a data frame by column in ascending and descending order. For base R, use order() with row indexing. For character columns in descending order, use decreasing = TRUE. For tidyverse workflows, dplyr::arrange() provides a readable alternative.