R 对一列升序排序,所有其他列降序排序(基于列顺序)

R Sort one column ascending, all others descending (based on column order)

我有一个订单table,类似如下:

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(升序)对 table 进行排序,然后按优先级顺序(降序)彼此 列进行排序 - 即首先按 A 列,然后是 B,然后是 C,等等

问题是我事先不知道列名所以不能命名,但实际上需要 "all columns except 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

我看过按两列排序的示例,但我找不到正确的语法来按 'all other columns sequentially' 排序。

非常感谢

我们可以使用 arrangedplyr

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))

名称使用 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)))