R语言:基于多变量混合方向排序data.frame的技术问询
Alright, let's work through this sorting task with your data frame. Below are two reliable methods to get the exact sort order you need—one using base R, another with the popular dplyr package, both honoring your requirement to store sort column names in variables.
First, let's recap your starting data frame for reference:
df <- data.frame( var1=c("b","a","b","a","a","b"), var2=c("l","l","k","k","l","k"), var3=c("t","t","x","t","x","x"), var4=c(5,3,3,5,5,3), stringsAsFactors=F )
Using Base R
This approach leverages order() with a dynamic set of sorting keys, handling both ascending and descending orders even for mixed column types (character/numeric).
First define your sort column variables:
sort_asc <- "var2" sort_desc <- c("var3", "var4")
Then create the sorted data frame:
# Build sorting arguments: ascending for sort_asc, descending for sort_desc sort_args <- c( list(df[[sort_asc]]), lapply(sort_desc, function(col) -xtfrm(df[[col]])) ) # Get ordered row indices and reorder the data frame df_sorted_base <- df[do.call(order, sort_args), ]
What's happening here?
xtfrm()converts any vector (character or numeric) to a numeric vector suitable for sorting, making it a flexible tool for mixed column types.- The negative sign reverses the numeric output of
xtfrm(), effectively turning an ascending sort into a descending one. do.call(order, sort_args)passes all our sorting keys to theorder()function in the correct sequence.
Using dplyr (Tidyverse)
If you prefer a more readable, pipe-based workflow, dplyr makes this straightforward with arrange() and across().
First load the package and define your sort variables (same as above):
library(dplyr) sort_asc <- "var2" sort_desc <- c("var3", "var4")
Then sort the data frame:
df_sorted_dplyr <- df %>% arrange( !!sym(sort_asc), # Convert string column name to a dplyr-compatible symbol across(all_of(sort_desc), desc) # Apply descending sort to all columns in sort_desc )
What's happening here?
!!sym(sort_asc)uses tidy evaluation to convert your string variable into a column name that dplyr can recognize.across(all_of(sort_desc), desc)applies thedesc()(descending) function to every column listed insort_desc, keeping your code concise even if you add more descending columns later.
Final Sorted Result
Both methods will produce the same sorted data frame:
var1 var2 var3 var4 4 a k t 5 3 b k x 3 6 b k x 3 5 a l x 5 1 b l t 5 2 a l t 3
内容的提问来源于stack exchange,提问作者mindlessgreen

