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

时间:2017-03-16 12:43:01

标签: r sorting multiple-columns

我有一个有序的表,类似如下:

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等。< / p>

问题是我不会提前知道列名,所以不能命名它们,但需要生效#34;除了SIZE&#34;之外的所有列。

最终结果应为:

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

我已经看过按两列排序的示例,但我无法找到正确的语法按顺序排列所有其他列&#39;。

非常感谢

2 个答案:

答案 0 :(得分:6)

名称使用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),或者如果它不一定是最后一列但始终称为大小,则使用k <- match("Size", names(df))代替。

注意:虽然问题中显示的示例中不需要列是否为数字,但是人们无法否定它们,因此更通用的解决方案是用以下内容替换上面的第一行其中xtfrm是一个R函数,它将对象转换为数字,以便结果按预期的顺序排序。

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

答案 1 :(得分:3)

我们可以使用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))