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' 排序。
非常感谢
我们可以使用 arrange
从 dplyr
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)))
我有一个订单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' 排序。
非常感谢
我们可以使用 arrange
从 dplyr
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)))