Найти индексы дублированных строк

Функция, дублируемая в R, выполняет поиск дубликатов строк. Если мы хотим удалить дубликаты, нам нужно просто написать df[!duplicated(df),] и дубликаты будут удалены из фрейма данных.

Но как найти индексы дублированных данных? Если duplicated возвращает TRUE в некоторой строке, это означает, что это второе появление такой строки в кадре данных, и его индекс может быть легко получен. Как получить индекс первого появления этой строки? Или, другими словами, индекс, с которым дублированная строка идентична?

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

Это возвращает вектор логического индекса:

 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 применяется как к исходному кадру данных, так и к кадру данных с обратным порядком строк. Выход последнего снова отменяется. Обратите внимание, что первые вхождения дублированных значений в исходные данные являются последними вхождениями в обратную версию. Затем оба вектора объединяются с использованием | поскольку TRUE по меньшей мере в одном из них указывает дублирующее значение.

Если вы используете ключевую таблицу 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(...) возвращает только уникальные комбинации дублированных строк. Это касается любых случаев с более чем 1 дубликатом (дубликаты дубликатов, например, три раза и т. Д.),

  • DT[..., which = T] объединяет повторяющиеся строки с оригиналом, с which=T возвращает номер строки (без which = T он просто вернет данные).

Вы также можете использовать

  DT[,count := .N,by = list(A,B,C)][count>1, which=T] 
Давайте будем гением компьютера.