简体   繁体   English

如何对data.frame中的多个升序/降序列进行排序:R

[英]How to sort multiple ascending/descending columns in a data.frame: R

I am fairly new to R and perhaps don't know the best way to tackle this task but I have attempted a few various suggestions and none of them have allowed me to sort multiple columns in a data.frame. 我是R的新手,也许不知道解决这个任务的最佳方法,但我尝试了一些不同的建议,但没有一个允许我对data.frame中的多个列进行排序。

Essentially for: 基本上用于:

df = data.frame(matrix(c(-1,3,6,1,3,-5,2,4,9,-3,-1,-6,1,4,5), ncol=3)

       X1 X2 X3
   [1] -1 -5 -1
   [2]  3  2 -6
   [3]  6  4  1
   [4]  1  9  4
   [5]  3 -3  5       

I want to sort all of the columns independently from one another such that I could make all columns sort "descending", make half of the columns sort "ascending" and half "descending" etc. 我想要将所有列彼此独立排序,以便我可以使所有列按“降序”排序,使一半列按“升序”排序,一半列“降序”等。

       X1 X2 X3
   [1] -1 -5  5
   [2]  1 -3  4
   [3]  3  2  1
   [4]  3  4 -1
   [5]  6  9 -6       

The purpose of this is create column-wise gradients for use in heatmap.2 while also being able to control the mean, variance etc. of the columns. 这样做的目的是创建用于heatmap.2的逐列渐变,同时还能够控制列的均值,方差等。 For example my data.frame would most likely be along the lines of: 例如,我的data.frame很可能是这样的:

df <- data.frame(matrix(runif(5200,0,1), ncol=10))

However, when I attempt to use the sort or order command, I fail to be able to sort the columns independently of one another. 但是,当我尝试使用sort或order命令时,我无法彼此独立地对列进行排序。

dfi <- df[order(df[[1]], decreasing =FALSE),]

        X1 X2 X3
    [1] -1 -5 -1
    [4]  1  9  4
    [2]  3  2 -6
    [5]  3 -3  5
    [3]  6  4  1


dfi <- df[order(df[[1]], df[[2]], decreasing =FALSE),]
        X1 X2 X3
    [1] -1 -5 -1
    [4]  1  9  4
    [2]  3  2 -6
    [5]  3 -3  5
    [3]  6  4  1

I have attempted using for loops but to no success. 我试图使用for循环,但没有成功。 I faced an inability to sort or order the columns independently (I don't have a reasonable for loop to show that someone could reproduce, and if this is the route to solve this problem, whoever answers will be much more knowledgable than I at the appropriate notation.) 我面临着无法对列进行独立排序或排序的问题(我没有合理的循环来表明有人可以重现,如果这是解决这个问题的途径,谁回答的问题比我在适当的表示法。)

Does anyone have any advice as to how to best go about this? 有没有人对如何最好地解决这个问题有任何建议? I have been able to get the desired result by individually creating the columns, sorting them and then binding them together. 通过单独创建列,对它们进行排序然后将它们绑定在一起,我已经能够获得所需的结果。 However, since I need to make many many varying iterations of this (different variances, means, numbers of columns etc), that process is way too inefficient unless. 但是,由于我需要对此进行许多不同的迭代(不同的方差,均值,列数等),否则该过程效率太低,除非。

How about sapply : sapply怎么sapply

n   <- ncol(df)
as  <- 3 # columns to be sorted ascending
de  <- 2 # columns to be sorted descending
out <- sapply(1:n, function(x) {
  if(x %in% as) {
    return(sort(df[,x], decreasing = F))
  } else if (x %in% de) {
    return(sort(df[,x], decreasing = T))
  }
  return(df[,x])
})
out


    [,1] [,2] [,3]
[1,]   -1   -5   -1
[2,]    3   -3   -6
[3,]    6    2    1
[4,]    1    4    4
[5,]    3    9    5

We simply loop over all columns and apply a function on each of them checking if they are either part of the vector as (ascending) or the vector de (descending). 我们只是对所有列循环及他们是否是向量的任一部分他们每个人的检查应用功能as (升序)或载体de (降序)。 If a column is part in neither of them we just return it as it is. 如果列中没有列,则我们只是按原样返回。

You can also do this with mutate_at + sort : 您也可以使用mutate_at + sort执行此mutate_at

library(dplyr)

df %>%
  mutate_at(1:2, funs(sort(.))) %>%
  mutate_at(3, funs(sort(., decreasing = TRUE)))

Result: 结果:

  X1 X2 X3
1 -1 -5  5
2  1 -3  4
3  3  2  1
4  3  4 -1
5  6  9 -6

You can also make it into a convenience function: 您还可以将其变为便利功能:

library(rlang)

arrange_indep = function(DF, asc = 1:ncol(DF), dsc=0){
  asc_quo = enquo(asc)
  dsc_quo = enquo(dsc)

  temp = DF %>%
    mutate_at(vars(!!asc_quo), funs(sort(.))) 

  if(dsc_quo != quo(0)){
    temp = temp %>%
      mutate_at(vars(!!dsc_quo), funs(sort(., decreasing = TRUE)))
  }
  return(temp)  
}

Results & Usage: 结果与用法:

1.) First two cols ascending, third col descending: 1.)前两个cols升序,第三个col降序:

df %>%
  arrange_indep(1:2, 3)

  X1 X2 X3
1 -1 -5  5
2  1 -3  4
3  3  2  1
4  3  4 -1
5  6  9 -6

2.) Same as 1.), but with non-standard evaluation: 2.)与1.)相同,但有非标准评估:

df %>%
  arrange_indep(X1:X2, X3)

  X1 X2 X3
1 -1 -5  5
2  1 -3  4
3  3  2  1
4  3  4 -1
5  6  9 -6

3.) First two cols ascending, keeping third col unsorted: 3.)前两个cols升序,保持第三个col未分类:

df %>%
  arrange_indep(1:2)

  X1 X2 X3
1 -1 -5 -1
2  1 -3 -6
3  3  2  1
4  3  4  4
5  6  9  5

4.) First two cols descending, third col defaults to ascending: 4.)前两个cols降序,第三个col默认为升序:

df %>%
  arrange_indep(dsc=1:2)

  X1 X2 X3
1  6  9 -6
2  3  4 -1
3  3  2  1
4  1 -3  4
5 -1 -5  5

5.) Using the default of arranging all cols by ascending order: 5.)使用默认值按升序排列所有cols:

df %>%
  arrange_indep()

  X1 X2 X3
1 -1 -5 -6
2  1 -3 -1
3  3  2  1
4  3  4  4
5  6  9  5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM