在混合方向上按多个变量排序data.frame

时间:2018-05-01 12:23:51

标签: r

对于此示例data.frame,

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)

未排序

  var1 var2 var3 var4
1    b    l    t    5
2    a    l    t    3
3    b    k    x    3
4    a    k    t    5
5    a    l    x    5
6    b    k    x    3

我想同时按顺序对三列'var2','var3'和'var4'进行排序。一列上升,另一列下降。要排序的列名存储在变量中。

sort_asc <- "var2"
sort_desc <- c("var3","var4")

基础R 中执行此操作的最佳方式是什么?

更新了详情

这是输出,如果先按'var2'排序(步骤1),然后按'var3'和'var4'降序(作为步骤2)。

var1   var2 var3 var4
a      l    x    5
b      k    x    3
b      k    x    3
a      k    t    5
b      l    t    5
a      l    t    3

但我正在寻找的是同时进行所有三种排序来获得这个:

var1 var2 var3 var4
b    k    x    3
b    k    x    3
a    k    t    5
a    l    x    5
b    l    t    5
a    l    t    3

'var2'是升序(k,l),在k内,在l内,'var3'正在下降,同样'var4'正在下降

澄清一下,这个问题与其他data.frame订购问题有什么不同......

  • 订购多列
  • 要订购的列名存储在变量
  • 不同的订购方向(asc,desc)
  • 排序不是逐步的(一种接一种),而是同步的(同时所有选定的列)
  • 使用基础R,而不是dplyr

1 个答案:

答案 0 :(得分:3)

逐步排序(先升序排序然后降序排列)。

dplyr解决方案:

library(dplyr)
df %>% 
   arrange_at(sort_asc) %>%
   arrange_at(sort_desc, desc)

  var1 var2 var3 var4
1    a    l    x    5
2    b    k    x    3
3    b    k    x    3
4    a    k    t    5
5    b    l    t    5
6    a    l    t    3

基础R溶液:

使用base R,如果有多列(一般情况下),请在order中使用do.call。在这里,我们首先为升序创建索引,然后使用第二组列对其进行排序(&#39; sort_desc&#39;)

i1 <- do.call(order, df[sort_asc]) 
df1 <- df[i1,]
i2 <-  do.call(order, c(df1[sort_desc], list(decreasing = TRUE)))
df1[i2,]

  var1 var2 var3 var4
5    a    l    x    5
3    b    k    x    3
6    b    k    x    3
4    a    k    t    5
1    b    l    t    5
2    a    l    t    3

同时/顺序排序(所有排序变量在一个排序步骤中使用):

dplyr解决方案:

df %>% 
   arrange_(.dots  = c(sort_asc, paste0("desc(", sort_desc, ")")))

#   var1 var2 var3 var4
#1    b    k    x    3
#2    b    k    x    3
#3    a    k    t    5
#4    a    l    x    5
#5    b    l    t    5
#6    a    l    t    3

基础R溶液:

使用base R,如果我们需要与arrange_

类似的输出
df[do.call(order, c(as.list(df[sort_asc]), lapply(df[sort_desc], 
               function(x) -xtfrm(x)))),]

#  var1 var2 var3 var4
#3    b    k    x    3
#6    b    k    x    3
#4    a    k    t    5
#5    a    l    x    5
#1    b    l    t    5
#2    a    l    t    3