【发布时间】:2022-01-25 23:07:51
【问题描述】:
数据集
> read.delim("df.tsv")
col1 col2 group
1 3 2 aa
2 1 1 aa
3 4 1 aa
4 4 3 aa
5 5 3 ab
6 3 2 ab
7 4 1 ab
8 2 4 ab
9 4 2 ba
10 1 4 ba
11 3 1 ba
12 4 3 ba
13 4 2 bb
14 2 3 bb
15 3 1 bb
16 1 2 bb
我想排序列 col1 和 col2 在 4 个组中的每一个中,按以下方式:
- 如果组名中的第一个字符是“a”,则在中排序col1 >下降方式,如果是“b”则上升
- 如果组名中的第二个字符是“a”,则将col2排序到下降方式,如果是“b”则上升
- 重要的是,我希望这两列同时排序,即,如果该组为“aa”,该组的排序应如下所示:
col1 col2 group
1 4 3 aa
2 3 2 aa
3 4 1 aa
4 1 1 aa
...
这可以通过例如一个"one row at a time" approach,先是col1,然后是col2,每行交替进行。
当前代码和输出
library(dplyr)
read.delim("df.tsv") %>%
group_by(group) %>%
arrange(ifelse(substr(group, 1,1) == "a", desc(col1), col1), # if first character in group name is "a", sort col1 in a descending manner, and ascending if it's "b"
ifelse(substr(group, 2,2) == "a", desc(col2), col2), # if second character in group name is also "a", sort also col2 in a descending manner, and ascending if it's "b"
.by_group = TRUE)
col1 col2 group
1 4 3 aa
2 4 1 aa
3 3 2 aa
4 1 1 aa
5 5 3 ab
6 4 1 ab
7 3 2 ab
8 2 4 ab
9 1 4 ba
10 3 1 ba
11 4 3 ba
12 4 2 ba
13 1 2 bb
14 2 3 bb
15 3 1 bb
16 4 2 bb
但是,这不满足第三个标准,即“一次同时排序一行”。
期望的输出
col1 col2 group
1 4 3 aa
2 3 2 aa
3 4 1 aa
4 1 1 aa
5 5 3 ab
6 4 1 ab
7 3 2 ab
8 2 4 ab
9 1 4 ba
10 4 3 ba
11 3 1 ba
12 4 2 ba
13 1 2 bb
14 3 1 bb
15 2 3 bb
16 4 2 bb
编辑
实际上有几个答案可以完成建议的任务,所以我认为一个平局可能是该算法在要排序的列数方面是灵活的,例如3:
col1 col2 col3 group
3 2 4 aaa
1 1 2 aaa
4 1 4 aaa
4 3 1 aaa
5 3 3 aab
3 2 2 aab
4 1 1 aab
2 4 1 aab
4 2 3 aba
1 4 3 aba
3 1 2 aba
4 3 3 aba
3 2 4 abb
1 1 2 abb
4 1 4 abb
4 3 1 abb
4 2 1 baa
2 3 2 baa
3 1 2 baa
1 2 1 baa
5 3 3 bab
3 2 2 bab
4 1 1 bab
2 4 1 bab
4 2 3 bba
1 4 3 bba
3 1 2 bba
4 3 3 bba
4 2 1 bbb
2 3 2 bbb
3 1 2 bbb
1 2 1 bbb
输出应该是
col1 col2 col3 group
4 3 1 aaa
3 2 4 aaa
4 1 4 aaa
1 1 2 aaa
5 3 3 aab
2 4 1 aab
4 1 1 aab
3 2 2 aab
4 2 3 aba
3 1 2 aba
4 3 3 aba
1 4 3 aba
4 1 4 abb
1 1 2 abb
4 3 1 abb
3 2 4 abb
1 2 1 baa
2 3 2 baa
3 1 2 baa
4 2 1 baa
2 4 1 bab
5 3 3 bab
4 1 1 bab
3 2 2 bab
1 4 3 bba
3 1 2 bba
4 2 3 bba
4 3 3 bba
1 2 1 bbb
3 1 2 bbb
4 2 1 bbb
2 3 2 bbb
目前,当包含 3 列或更多列时,建议的 2 个解决方案不起作用,它们仅基于 2 列进行排序。
编辑 2
如果例如group=='aba',该组的第一行应该是col1中包含最高值的那一行;第 2 行包含 col2 中(剩余的)最低值的行;第 3 行包含 col3 中的(剩余)最高值,第 4 行是剩余的行。但是,这应该是灵活的,以允许每组超过 4 行,在这种情况下,第 4 行应该是包含 col1 中(剩余)最高值的行;第 5 行应该是包含 col2 中(剩余)最低值的行;等等
更多详情
示例:对于 'aba' 组的第 2 行,在 col2 中的最低(剩余)值的 2 行之间存在平局的情况下,例如
row-a 3 1 4 aba
row-b 2 1 4 aba
(请注意,两行中的 col2 中都有一个 1),理想情况下,选择的第二行将是 row-a,因为 col1 在该组中必须以降序方式('a')排序,并且3>2,无论如何对于 col3 4==4。
如果改为
row-a 3 1 4 aba
row-b 2 1 5 aba
让优先级转到 col3>col2>col1,因为循环转到 col1>col2>col3... 所以第二行将是 row-b,因为 5>4。
所以概括地说,如果有 5 列并且组是 'aabaa',并且在 2 行之间选择第 3 行存在平局:
row-a 3 2 1 3 3 aabaa
row-b 5 4 1 4 2 aabaa
(col3 == 1 in both),那么要选择的将是 row-a,因为 col5 3>2。如果改为
row-a--> 3 2 1 3 3
row-b--> 5 4 1 4 3
(col5==3 in both),然后选择 row-b since for col4 4>3.
【问题讨论】:
-
我不确定我是否理解为什么 col1 应该是
4 3 4而不是4 4 3? -
因为如果 col1 为 4 4 3 表示 col2 为 3 1 2,而我想要的是第一行在 col1 中具有最高值,那么 row2 在 col2 中具有剩余的最高值,那么row3 col1 中剩余的最高值
-
好的,现在更有意义了。
标签: r dataframe sorting dplyr tidyverse