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

时间:2017-11-17 20:01:57

标签: r sorting dataframe matrix gradient

我是R的新手,也许不知道解决此任务的最佳方法,但我尝试了一些不同的建议,但没有一个允许我对data.frame中的多个列进行排序。< / p>

基本上是:

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       

我希望将所有列彼此独立排序,以便我可以对所有列进行排序&#34;降序&#34;,使一半列排序&#34;升序&#34;一半&#34;下降&#34;等。

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

这样做的目的是创建用于heatmap.2的逐列渐变,同时还能够控制列的均值,方差等。例如,我的data.frame很可能符合以下几行:

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

但是,当我尝试使用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

我尝试使用 for loops ,但没有成功。我无法独立排序或订购列(我没有合理的循环来表明有人可以复制,如果这是解决这个问题的途径,那么回答的人将比我知道更多的知识在适当的表示法。)

有没有人对如何最好地解决这个问题有什么建议?通过单独创建列,对它们进行排序然后将它们绑定在一起,我已经能够获得所需的结果。但是,由于我需要对此进行许多不同的迭代(不同的方差,均值,列数等),否则该过程效率太低,除非。

2 个答案:

答案 0 :(得分:2)

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

我们只是遍历所有列并在每个列上应用一个函数,检查它们是向量as(升序)还是向量de(降序)的一部分。如果列中没有列,则我们只是按原样返回。

答案 1 :(得分:1)

您也可以使用mutate_at + sort

执行此操作
library(dplyr)

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

<强>结果:

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

您还可以将其变为便利功能:

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)  
}

结果&amp;用法:

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。)与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。)前两个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.)前两个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.使用默认值按升序排列所有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