让我们假设我有一个data.frame
,应该对所选列进行排序,并且我想确保确实如此。我可以尝试类似的东西:
library(dplyr)
mpg2 <- mpg %>%
arrange(manufacturer, model, year)
identical(mpg, mpg2)
[1] FALSE
但是如果identical
返回FALSE
,这仅让我知道数据集的顺序不正确。
manufacturer
,model
,year
值,其余变量(未用于排序)不同,那么dplyr::arrange
如何决定先观察哪个?是否保留原始数据集的顺序(此处为mpg
)?答案 0 :(得分:1)
关于第二个问题,我相信dplyr::arrange
是稳定,当排序列中有联系时,它会保留行的顺序。
通过与base::order
的结果进行比较可以看出这一点。在帮助页面的Details
部分(我的重点):
在第一个向量中有平局的情况下,第二个向量中的值是
过去打破关系。如果仍然绑定值,则
中的值 后面的参数用于打破平局(请参阅第一个示例)。
所使用的排序是稳定的(方法=“快速”除外),因此任何
未解决的联系将保留其原始顺序。
mpg2 <- mpg %>%
arrange(manufacturer, model, year)
i <- with(mpg, order(manufacturer, model, year))
mpg3 <- mpg[i, ]
identical(as.data.frame(mpg2), as.data.frame(mpg3))
#[1] TRUE
除类外,值相同。因此,dplyr::arrange
确实保留了平局的顺序。
第一个问题,也许下面的代码可以回答它。它只获取下一个订单号小于上一个订单号的行。这意味着这些行的相对位置已更改。
j <- which(diff(i) < 0)
mpg[i[j], ]
答案 1 :(得分:0)
我认为这不是我以前需要的。通常,最佳实践是不依赖表顺序。只有当我依赖它时,排序才会包含在函数内,即我不会让函数B依赖于函数A中发生的排序。
我认为这可以使用data.table
软件包满足您的要求。您使用此程序包设置密钥,并且按主键,辅助键等的顺序从左到右排序。我不确定将键并置在一起是否是最好的方法,但是它很简单。
# reproducible fake data
library(data.table)
set.seed(1)
dt <- data.table(a=rep(1:5, 2), b=letters[1:10], c=sample(1:3, 10, TRUE))
# scramble
dt <- dt[sample(1:.N)]
# make the ideal structure
keys <- c("a", "b")
dt_ideal <- copy(dt)
dt_ideal <- setkeyv(dt_ideal, keys)
key(dt_ideal)
# function to find keys not the same for each row. Pasting together
findBad <- function(dt, dt_ideal){
not_ok <- which(dt_ideal[, do.call(paste, c(.SD, sep=">")), .SDcols=keys] !=
dt[, do.call(paste, c(.SD, sep=">")), .SDcols=keys])
not_ok
}
# index of bad rows - all bad in this case
not_ok <- findBad(dt, dt_ideal)
dt[not_ok]
# better eg, swap 7 & 8
dt2 <- copy(dt_ideal)
dt2 <- dt2[c(1:6, 8, 7, 9:10)]
not_ok <- findBad(dt2, dt_ideal)
dt2[not_ok]