Encontre índices de linhas duplicadas

Função duplicada em R executa pesquisa de linha duplicada. Se quisermos remover as duplicatas, precisamos apenas escrever df[!duplicated(df),] e as duplicatas serão removidas do quadro de dados.

Mas como encontrar os índices de dados duplicados? Se duplicated retornar TRUE em alguma linha, significa que esta é a segunda ocorrência de tal linha no quadro de dados e seu índice pode ser facilmente obtido. Como obter o índice da primeira ocorrência desta linha? Ou, em outras palavras, um índice com o qual a linha duplicada é idêntica?

Eu poderia fazer um loop no data.frame, mas acho que há uma resposta mais elegante sobre essa questão.

Isso retorna um vetor de índice lógico:

 duplicated(df) | duplicated(df[nrow(df):1, ])[nrow(df):1] 

Aqui está um exemplo:

 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 

Atualizar (com base no comentário):
A complexidade do comando pode ser reduzida se fromLast = TRUE for usado como argumento de function. Isso é mais fácil do que criar dois vetores invertidos.

 duplicated(df) | duplicated(df, fromLast = TRUE) duplicated(df) | duplicated(df, fromLast = TRUE) #[1] TRUE TRUE FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE 

Como funciona?

A function duplicated é aplicada ao quadro de dados original e ao quadro de dados com ordem inversa de linhas. A saída deste último é revertida novamente. Observe que as primeiras ocorrências de valores duplicados nos dados originais são as últimas ocorrências na versão reversa. Depois, ambos os vetores são combinados usando | desde que um TRUE em pelo menos um deles indica um valor duplicado.

Se você estiver usando um data.table com chave, poderá usar a seguinte syntax elegante

 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] 

Desempacotar

  • DT[duplicated(DT)] subconjeta as linhas que são duplicatas.

  • unique(...) retorna apenas as combinações exclusivas das linhas duplicadas. Isso lida com todos os casos com mais de 1 duplicado (duplicatas duplicadas, por exemplo, triplicatas, etc.)

  • DT[..., which = T] mescla as linhas duplicadas com o original, com o which=T retornando o número da linha (sem o which = T retornaria apenas os dados).

Você também pode usar

  DT[,count := .N,by = list(A,B,C)][count>1, which=T]