如何按列给出数据框,将列名作为变量

时间:2016-10-28 09:07:53

标签: r sorting dataframe

我需要按几列对数据框进行排序,并且我在变量中有列的名称。 我的问题与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参数只是另一个订购项。

3 个答案:

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