如何查找未排序的数据帧片段

时间:2018-12-28 11:51:01

标签: r sorting dplyr

让我们假设我有一个data.frame,应该对所选列进行排序,并且我想确保确实如此。我可以尝试类似的东西:

library(dplyr)
mpg2 <- mpg %>% 
  arrange(manufacturer, model, year)
identical(mpg, mpg2)
[1] FALSE

但是如果identical返回FALSE,这仅让我知道数据集的顺序不正确。

  1. 如果我只想检查实际上顺序不正确的行怎么办?如何从整个数据集中过滤掉这些数据? (我最好避免在这里循环,因为我使用的数据集非常大)
  2. 如果对于相同的manufacturermodelyear值,其余变量(未用于排序)不同,那么dplyr::arrange如何决定先观察哪个?是否保留原始数据集的顺序(此处为mpg)?

2 个答案:

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