如何通过一个降序列和一个升序列来订购数据框?

时间:2011-10-17 11:48:17

标签: r sorting dataframe

我有一个数据框,看起来像这样:

    P1  P2  P3  T1  T2  T3  I1  I2
1   2   3   5   52  43  61  6   "b"
2   6   4   3   72  NA  59  1   "a"
3   1   5   6   55  48  60  6   "f"
4   2   4   4   65  64  58  2   "b"

我希望按I1按降序对其进行排序,将I1中具有相同值的行按I2按升序排序,以1 3 4 2的顺序获取行。但是order函数似乎只接受一个decreasing参数,然后对所有排序向量一次TRUEFALSE。如何让我的排序正确?

11 个答案:

答案 0 :(得分:41)

我使用此代码生成所需的输出。这就是你追求的目标吗?

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b"), header = TRUE)
rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a

答案 1 :(得分:28)

我使用rank

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

> rum[order(rum$I1, -rank(rum$I2), decreasing = TRUE), ]
  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a

答案 2 :(得分:23)

我担心RomanLuštrik的回答是错误的。它偶然适用于此输入。 例如,考虑它在非常相似的输入上的输出(在I2列中有一条类似于原始行3的“c”的附加行):

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
3  1  5  6 55 48 60  6  f
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a

这不是理想的结果:I2的前三个值是f b c而不是b c f,这是预期的,因为次要排序是I2,按升序排列。

要获得I2的相反顺序,您希望较大的值较小,反之亦然。对于数字值乘以-1会做到这一点,但对于字符来说它有点棘手。字符/字符串的一般解决方案是通过因子,反转级别(使大值小值和小值变大)并将因子更改回字符:

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

f=factor(rum$I2)
levels(f) = rev(levels(f))
rum[order(rum$I1, as.character(f), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a

答案 3 :(得分:4)

设df为具有2个字段A和B的数据帧 案例1:如果您的字段A和B是数字

    df[order(df[,1],df[,2]),] - sorts fields A and B in ascending order
    df[order(df[,1],-df[,2]),] - sorts fields A in ascending and B in descending order
    优先考虑A.     

案例2:如果字段A或B是非数字说明因素或字符

    在我们的例子中,如果B是字符,我们想按相反的顺序排序
    df[order(df[,1],-as.numeric(as.factor(df[,2]))),] -> this sorts field A(numerical) in ascending and field B(character) in descending.要优先考虑A.

The idea is that you can apply -sign in order function ony on numericals. So for sorting character strings in descending order you have to coerce them to numericals.

答案 4 :(得分:3)

默认排序是稳定的,因此我们排序两次:首先是次要密钥,然后是主键

rum1 <- rum[order(rum$I2, decreasing = FALSE),]
rum2 <- rum1[order(rum1$I1, decreasing = TRUE),]

答案 5 :(得分:2)

    library(dplyr)
    library(tidyr)
    #supposing you want to arrange column 'c' in descending order and 'd' in ascending order. name of data frame is df
    ## first doing descending
    df<-arrange(df,desc(c))
    ## then the ascending order of col 'd;
    df <-arrange(df,d)

答案 6 :(得分:2)

没有等级的简单:

rum[order(rum$I1, -rum$I2, decreasing = TRUE), ]

答案 7 :(得分:1)

rum[order(rum$T1, -rum$T2 ), ]

答案 8 :(得分:0)

正确的方法是:

rum[order(rum$T1, rum$T2, decreasing=c(T,F)), ]

答案 9 :(得分:0)

在@dudusan的例子中,你也可以颠倒I1的顺序,然后按升序排序:

> rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
+   2   3   5   52  43  61  6   b
+   6   4   3   72  NA  59  1   a
+   1   5   6   55  48  60  6   f
+   2   4   4   65  64  58  2   b
+   1   5   6   55  48  60  6   c"), header = TRUE)
> f=factor(rum$I1)   
> levels(f) <- sort(levels(f), decreasing = TRUE)
> rum[order(as.character(f), rum$I2), ]
  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a
> 

这似乎有点短,你不要两次颠倒I2的顺序。

答案 10 :(得分:0)

你可以使用惊人的包 dplyr 有一个函数叫排列。 考虑到您选择的层次结构,您只需设置数据框和要排序的列。默认是升序。但如果你想按降序排列,你可以使用命令 desc。

rum <- read.table(textConnection("P1 P2 P3 T1 T2 T3 I1 I2 2 3 5 52 43 61 6 乙 6 4 3 72 不适用 59 1 a 1 5 6 55 48 60 6 f 2 4 4 65 64 58 2 b"), 标题 = TRUE)

图书馆(dplyr)
安排(朗姆酒,desc(I1),I2)