我在order
周围写了这个小小的包装,但我担心我的实现是蹩脚的。我蜷缩在角落里,等待R命令的神灵或算法效率来击打我的人体工程学键盘: - (
set.seed(1001)
height <- rnorm(6, mean = 1, sd = 0.2)
weight <- rnorm(6, mean = 100, sd = 15)
id <- 1:6
dd <- data.frame(id, height, weight)
# Here's the function I came up with
ReorderDataByColumn <- function(x, column) {
ordered.indices <- order(x[ ,paste(column)])
return(x[ordered.indices, ])
}
#And here are its results
> ReorderDataByColumn(dd, column = "height")
id height weight
4 4 0.4986928 76.09430
5 5 0.8885377 104.53967
3 3 0.9629449 86.38809
2 2 0.9644905 90.65584
6 6 0.9712881 124.51589
1 1 1.4377296 116.37253
> ReorderDataByColumn(dd, column = "weight")
id height weight
4 4 0.4986928 76.09430
3 3 0.9629449 86.38809
2 2 0.9644905 90.65584
5 5 0.8885377 104.53967
1 1 1.4377296 116.37253
6 6 0.9712881 124.51589
答案 0 :(得分:4)
我不会因为格式正确的问题而进入这个业务。我认为代码是可读和明智的。如果你想稍微收紧一下,你可以通过使用“[[”并在“[”:
中创建索引来放弃paste()操作ReorderDataByColumn2 <- function(x, column) {
return(x[ order( x[[column]]), ])
}
编辑:添加Hadley的建议(除了我认为你还需要do.call):
ReorderDataByColumn2 <- function(x, column, desc=FALSE) {
return(
x[ do.call( order, x[ , column, drop=FALSE ] ), ]
) }
如果您愿意,可以添加一些错误检查:
ReorderDataByColumn2 <- function(x, column) {
if(column %in% names(x)){return(x[ order( x[[column]]), ])
}else{ cat("Column ", column, "not in dataframe ", deparse(substitute(x))) }
}
答案 1 :(得分:2)
参见plyr中的安排功能:
library(plyr)
arrange(mtcars, cyl)
arrange(mtcars, desc(cyl))
arrange(mtcars, vs, am)
该功能的定义非常简单:
arrange <- function (df, ...) {
ord <- eval(substitute(order(...)), df, parent.frame())
unrowname(df[ord, ])
}
它适用于与基础R中的subset
非常相似的过程。