Как упорядочить фрейм данных по одному убыванию и одному возрастанию столбца?
У меня есть кадр данных, который выглядит так:
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
для всех векторов заказов сразу. Как я могу сделать правильный выбор?
Ответы
Ответ 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"), 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
Ответ 2
Я использую 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
Ответ 3
Я боюсь, что ответ Роман Луштрик неверен. Он работает на этом входе случайно.
Рассмотрим, например, его вывод на очень похожем входе (с дополнительной строкой, аналогичной исходной строке 3 с "c" в столбце I2):
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
Ответ 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
приоритет отдается А.
Случай 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.
Ответ 5
Сортировка по умолчанию стабильна, поэтому мы сортируем дважды: сначала второстепенным ключом, затем основным ключом
rum1 <- rum[order(rum$I2, decreasing = FALSE),]
rum2 <- rum1[order(rum1$I1, decreasing = TRUE),]
Ответ 6
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)
Ответ 7
Простой без ранга:
rum[order(rum$I1, -rum$I2, decreasing = TRUE), ]
Ответ 8
rum[order(rum$T1, -rum$T2 ), ]
Ответ 9
Правильный способ:
rum[order(rum$T1, rum$T2, decreasing=c(T,F)), ]
Ответ 10
В примере @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.