Найти индексы дублированных строк
Функция, дублируемая в R, выполняет поиск дубликатов строк. Если мы хотим удалить дубликаты, нам нужно просто написать df[!duplicated(df),]
, и дубликаты будут удалены из фрейма данных.
Но как найти индексы дублированных данных? Если duplicated
возвращает TRUE в некоторой строке, это означает, что это второе появление такой строки в кадре данных, и его индекс может быть легко получен. Как получить индекс первого появления этой строки? Или, другими словами, индекс, с которым дублированная строка идентична?
Я мог бы создать цикл на data.frame, но я думаю, что есть более элегантный ответ на этот вопрос.
Ответы
Ответ 1
Возвращает вектор логического индекса:
duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1]
Вот пример:
df <- data.frame(a = c(1,2,3,4,1,5,6,4,2,1))
duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1]
#[1] TRUE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE
which(duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1])
#[1] 1 2 4 5 8 9 10
Обновить (на основе комментария):
Сложность команды может быть уменьшена, если fromLast = TRUE
используется как аргумент функции. Это проще, чем создание двух обратных векторов.
duplicated(df) | duplicated(df, fromLast = TRUE)
duplicated(df) | duplicated(df, fromLast = TRUE)
#[1] TRUE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE
Как это работает?
Функция duplicated
применяется как к исходному кадру данных, так и к кадру данных с обратным порядком строк. Выход последнего снова отменяется. Обратите внимание, что первые вхождения дублированных значений в исходные данные являются последними вхождениями в обратную версию. Затем оба вектора объединяются с использованием |
, так как a TRUE
по меньшей мере в одном из них указывает дублируемое значение.
Ответ 2
Если вы используете ключевую таблицу data.table, вы можете использовать следующий элегантный синтаксис
library(data.table)
DT <- data.table(A = rep(1:3, each=4),
B = rep(1:4, each=3),
C = rep(1:2, 6), key = "A,B,C")
DT[unique(DT[duplicated(DT)]),which=T]
Чтобы распаковать
-
DT[duplicated(DT)]
подмножества этих строк, которые являются дубликатами.
-
unique(...)
возвращает только уникальные комбинации дублированных строк. Это касается любых случаев с более чем одним дубликатом (дубликаты дубликатов, например, три раза и т.д.)
-
DT[..., which = T]
объединяет повторяющиеся строки с оригиналом, при этом which=T
возвращает номер строки (без which = T
он просто возвращает данные).
Вы также можете использовать
DT[,count := .N,by = list(A,B,C)][count>1, which=T]