我想编写一个函数,通过任意数量的列对给定的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,以便将所有列合并到一列中维护优先级,然后按该列排序。我觉得应该有更好的方法来做到这一点,因为这似乎是一个非常基本的功能。
答案 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_at
与group_by
一起使用可能会导致一些错误(基于here