我需要按几列对数据框进行排序,并且我在变量中有列的名称。 我的问题与this one有关,但在我的情况下,用于排序的列存储在变量中,例如this other question。
我从第一个问题借用数据框:
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
dd
b x y z
1 Hi A 8 1
2 Med D 3 1
3 Hi A 9 1
4 Low C 9 2
我需要做的是按dd
减少排序z
,然后按b
增加排序。
排序答案是:
dd[with(dd, order(-z, b)), ]
我拥有的是:
sort_list <- c("z","b")
从第二个问题我知道我可以做到:
dd[do.call(order, dd[, sort_list]),]
但这只会让我增加两个变量的顺序。我无法弄清楚的是如何通过递减顺序来做到这一点。我试过这个:
dd[do.call(order, list(dd[, sort_list]), decreasing = c(TRUE,FALSE)),]
产生错误,因为它假设decreasing
参数只是另一个订购项。
答案 0 :(得分:2)
使用data.table
订单功能,您可以执行以下操作:
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
library(data.table)
sort_list <- c("z","b")
sort_order <- c(-1, 1)
setDT(dd)
setorderv(dd, sort_list, sort_order)
dd
#> b x y z
#> 1: Low C 9 2
#> 2: Med D 3 1
#> 3: Hi A 8 1
#> 4: Hi A 9 1
答案 1 :(得分:1)
这有效:
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
sort_list <- c("z","b")
dd[order(-dd[,sort_list[1]], dd[,sort_list[2]]), ]
# or
dd[order(-dd[,sort_list["z"]], dd[,sort_list["b"]]), ]
如果输入令人讨厌,或者变量名称发生变化,或者其他什么,你可以将它粘贴在一个函数中(按照正确的顺序):
downup <- function(dat, sort_list){
dat[order(-dat[,sort_list[1]], dat[,sort_list[2]]), ]
}
downup(dd)
那有帮助吗?
答案 2 :(得分:0)
dplyr
示例
library(dplyr)
sort_list <- c("z","b")
sort_order=c(TRUE,FALSE)
dd %>% arrange_(.dots=ifelse(sort_order,paste0("desc(",sort_list,")"),sort_list))