我有一个数据框,看起来像这样:
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
参数,然后对所有排序向量一次TRUE
或FALSE
。如何让我的排序正确?
答案 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)