按升序排列一列数据,其他所有数据按逆序排列(根据列的顺序)

4

我有一个有序表格,类似于以下内容:

df <- read.table(text = 
"A   B   C   Size
1   0   0   1
0   1   1   2
0   0   1   1
1   1   0   2
0   1   0   1",
header = TRUE)

实际上,这个表格会有更多的列,但对于解决方案来说,这已经足够了。

我希望首先按 SIZE(升序)对该表格进行排序,然后按优先顺序对其他每个列进行排序(降序)- 即首先按 A 列排序,然后是 B、C 等等。

问题在于我事先不知道列名,因此无法命名它们,但需要“除 SIZE 外的所有列”。

最终结果应为:

A B C Size
1 0 0 1
0 1 0 1
0 0 1 1
1 1 0 2
0 1 1 2

我看过按两个列排序的例子,但是我找不到正确的语法来按“所有其他列顺序”排序。

非常感谢


所有这些列都是数字或整数吗? - talat
2个回答

12

使用如下的名称顺序order,不需要使用任何包。

o <- with(df, order(Size, -A, -B, -C))
df[o, ]

这将会得到:

  A B C Size
1 1 0 0    1
5 0 1 0    1
3 0 0 1    1
4 1 1 0    2
2 0 1 1    2

或者不使用名称,只使用列号:

o <- order(df[[4]], -df[[1]], -df[[2]], -df[[3]])
或者
k <- 4
o <- do.call("order", data.frame(df[[k]], -df[-k]))
如果Size始终是最后一列,请改用k <- ncol(df),如果不一定是最后一列但总是叫 Size,请改用k <- match("Size", names(df))
注意:虽然在问题示例中不需要,但如果列不是数字,则不能否定它们,因此更一般的解决方案是将上面的第一行替换为以下内容,其中xtfrm是一个R函数,用于将对象转换为数字,使结果按预期顺序排序。
o <- with(df, order(Size, -xtfrm(A), -xtfrm(B), -xtfrm(C)))

列是数字的,但我不想明确地命名它们,因为它们在每次执行中可能会有所不同。 - Jon
请在注释前查看末尾的附加内容。 - G. Grothendieck

5
我们可以使用来自dplyr的arrange。
library(dplyr)
arrange(df, Size, desc(A), desc(B), desc(C))

如果需要更多列,可以使用arrange_

cols <-  paste0("desc(", names(df)[1:3], ")")
arrange_(df, .dots = c("Size", cols))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接