基于作为输入传入的多个列的顺序

时间:2018-03-08 00:55:32

标签: r sorting dataframe

我想编写一个函数,通过任意数量的列对给定的data.frame(我将其称为dataSet)进行排序,其名称也传递给函数(在我将引用的向量中)作为orderList)。我知道要通过单个传入的字符串进行排序,您只需使用

即可
sortDataset <- function(dataSet, sortCol) {
return(dataSet[order(dataSet[[sortCol]]),])
}

并且您可以使用

按多个传递的字符串进行排序
sortDataset <- function(dataSet, sortCol1, sortCol2) {
return(dataSet[order(dataSet[[sortCol1]], dataSet[[sortCol2]]),])
}

随着我想要的许多sortCol#输入。但是,我希望能够传入任意数量的字符串列表。我尝试了以下方法:

dataSet[order(dataSet[[orderList]]),]
dataSet[order(dataSet$orderList),]
dataSet[order(dataSet[,orderList])]

并遇到了前两个问题,因为它们不是获取多列的有效方法(我仍尝试过):)并且在第三个中,顺序似乎不接受返回的矩阵通过dataSet [,orderList]作为参数。

我想要一个函数如下:

sortDataset <- function(dataSet, sortCols)

其中sortCols的第一个元素是具有最高优先级的列,然后第二列是第一个仲裁器,第三个列是第二个仲裁器等,并且该函数返回适当排序的dataSet。如果我可以指定每个是否应该在可选输入中升序,那么第一列可以升序排序,第二列降序排序等等也是很好的。

到目前为止,我真正想到的唯一方法是假设每个列表只包含数值,然后将各个排序列乘以10 ^ n,以便将所有列合并到一列中维护优先级,然后按该列排序。我觉得应该有更好的方法来做到这一点,因为这似乎是一个非常基本的功能。

2 个答案:

答案 0 :(得分:0)

使用do.call

data[do.call("order", data[sortCols]), ]

其中data是数据框,sortCols是列名的字符向量。

另请查看doBy包中的orderBy

答案 1 :(得分:0)

我们可以使用tidyverse

执行此操作
library(dplyr)
data %>%
     arrange_at(vars(sortCols))

可以使用quos/1!!

制作一个函数
sortDataset <- function(dataSet, ...) {
   stopifnot(rlang::is_quosures(...))
   a1 <- c(...)

  dataSet %>%
      arrange(!!!  a1)
 }
sortDataset(mtcars, quos(mpg, cyl))
如果我们将变量作为字符串

传递,则使用

arrange_at

sortDataset <- function(dataSet, ...) {

 a1 <- c(...)
dataSet %>%
    arrange_at(vars(a1))
}

sortDataset(mtcars, "mpg", "cyl")

正如评论中提到的@Nettle一样,arrange_atgroup_by一起使用可能会导致一些错误(基于here