Как найти несортированные фрагменты фрейма данных - PullRequest
0 голосов
/ 28 декабря 2018

Давайте предположим, что у меня есть data.frame, который должен быть отсортирован по выбранным столбцам, и я хочу убедиться, что это действительно так.Я мог бы попробовать что-то вроде:

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

, но если identical вернет FALSE, это только даст мне знать, что набор данных находится в неправильном порядке.

  1. Что если яхотели бы проверить только те строки, которые на самом деле находятся в неправильном порядке?Как я могу отфильтровать их из всего набора данных?(В лучшем случае мне нужно избегать зацикливания, поскольку набор данных, с которым я работаю, довольно большой)
  2. Если остальные переменные (не используемые для упорядочения) различаются для одного и того же значения manufacturer, modelyear, как dplyr::arrange решает, какое наблюдение наступит раньше?Сохраняет ли он порядок из исходного набора данных (mpg здесь)?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Не думаю, что это то, что мне было нужно раньше.Обычно лучше не полагаться на порядок столов.Лишь в тех случаях, когда я полагаюсь на это, порядок будет содержаться внутри функции, т. Е. Функция 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]
0 голосов
/ 28 декабря 2018

Что касается второго вопроса , я считаю, что dplyr::arrange является стабильным , он сохраняет порядок строк при наличии связей в столбцах сортировки.
Этоможно увидеть, сравнив с результатом из base::order.На странице справки, раздел Details (мой акцент):

В случае связей в первом векторе значения во втором *
используются для разрыва связей.Если значения все еще связаны, значения в более поздних аргументах
используются для разрыва связи (см. Первый пример).
Используемая сортировка стабильна (за исключением метода = "quick"), поэтомувсе неразрешенные связи
будут оставлены в их первоначальном порядке.

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], ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...