Encuentra valores duplicados en R

Tengo una tabla con 21638 filas * únicas:

vocabulary <- read.table("http://socserv.socsci.mcmaster.ca/jfox/Books/Applied-Regression-2E/datasets/Vocabulary.txt", header=T) 

Esta tabla tiene cinco columnas, la primera de las cuales contiene los números de identificación del encuestado. Quiero verificar si los encuestados aparecen dos veces o si todos los encuestados son únicos.

Para contar identificaciones únicas que puedo usar

 length(unique(vocabulary$id)) 

y para verificar si hay algún duplicado que pueda hacer

 length(unique(vocabulary$id)) == nrow(vocabulary) 

que devuelve TRUE , si no hay duplicados (que no lo son).

Mi pregunta:

¿Hay una forma directa de devolver los valores o los números de línea de los duplicados?

Alguna otra explicación:

Hay un problema de interpretación con el uso de la función duplicated() , porque solo devuelve los duplicados en el sentido estricto, excluyendo los “originales”. Por ejemplo, sum(duplicated(vocabulary$id)) o dim(vocabulary[duplicated(vocabulary$id),])[1] podría devolver “5” como el número de filas duplicadas. El problema es que si solo conoce el número de duplicados, no sabrá cuántas filas duplican. ¿Significa “5” que hay cinco filas con un duplicado cada una, o que hay una fila con cinco duplicados? Y como no tendrá las ID ni los números de línea de los duplicados, no tendrá ningún medio para encontrar los “originales”.


* Sé que no hay ID duplicados en esta encuesta, pero es un buen ejemplo, porque al usar cualquiera de las respuestas dadas en otra parte a esta pregunta, como duplicated(vocabulary$id) o table(vocabulary$id) generará un pajar a su pantalla en la que no podrá encontrar ninguna posible aguja duplicada.

Podría usar la table , es decir,

 n_occur < - data.frame(table(vocabulary$id)) 

le da un dataframe con una lista de id y el número de veces que ocurrieron.

 n_occur[n_occur$Freq > 1,] 

te dice qué id ocurrieron más de una vez.

 vocabulary[vocabulary$id %in% n_occur$Var1[n_occur$Freq > 1],] 

devuelve los registros con más de una ocurrencia.

Esto le dará filas duplicadas:

 vocabulary[duplicated(vocabulary$id),] 

Esto le dará la cantidad de duplicados:

 dim(vocabulary[duplicated(vocabulary$id),])[1] 

Ejemplo:

 vocabulary2 < -rbind(vocabulary,vocabulary[1,]) #creates a duplicate at the end vocabulary2[duplicated(vocabulary2$id),] # id year sex education vocabulary #21639 20040001 2004 Female 9 3 dim(vocabulary2[duplicated(vocabulary2$id),])[1] #[1] 1 #=1 duplicate 

EDITAR

De acuerdo, con la información adicional, esto es lo que debe hacer: duplicated tiene una opción fromLast que le permite obtener duplicados desde el final. Si combina esto con el duplicated normal, obtendrá todos los duplicados. El siguiente ejemplo agrega duplicados al objeto de vocabulario original (la línea 1 se duplica dos veces y la línea 5 se duplica una vez). Luego uso la table para obtener el número total de duplicados por ID.

 #Create vocabulary object with duplicates voc.dups < -rbind(vocabulary,vocabulary[1,],vocabulary[1,],vocabulary[5,]) #List duplicates dups <-voc.dups[duplicated(voc.dups$id)|duplicated(voc.dups$id, fromLast=TRUE),] dups # id year sex education vocabulary #1 20040001 2004 Female 9 3 #5 20040008 2004 Male 14 1 #21639 20040001 2004 Female 9 3 #21640 20040001 2004 Female 9 3 #51000 20040008 2004 Male 14 1 #Count duplicates by id table(dups$id) #20040001 20040008 # 3 2 

Aquí, resumo algunas formas que pueden arrojar resultados diferentes a su pregunta, así que tenga cuidado:

 # First assign your "id"s to an R object. # Here's a hypothetical example: id < - c("a","b","b","c","c","c","d","d","d","d") #To return ALL MINUS ONE duplicated values: id[duplicated(id)] ## [1] "b" "c" "c" "d" "d" "d" #To return ALL duplicated values by specifying fromLast argument: id[duplicated(id) | duplicated(id, fromLast=TRUE)] ## [1] "b" "b" "c" "c" "c" "d" "d" "d" "d" #Yet another way to return ALL duplicated values, using %in% operator: id[id %in% unique(id[duplicated(id)])] ## [1] "b" "b" "c" "c" "c" "d" "d" "d" "d" 

Espero que esto ayude Buena suerte.

Aquí hay una solución de datos que mostrará los duplicados junto con el número de duplicaciones (será 1 si hay 2 copias, y así sucesivamente; puede ajustar eso para satisfacer sus necesidades):

 library(data.table) dt = data.table(vocabulary) dt[duplicated(id), cbind(.SD[1], number = .N), by = id] 

Una manera más terser, ya sea con rev :

 x[!(!duplicated(x) & rev(!duplicated(rev(x))))] 

… en lugar de desde fromLast :

 x[!(!duplicated(x) & !duplicated(x, fromLast = TRUE))] 

… y como función auxiliar para proporcionar un vector lógico o elementos del vector original:

 duplicates < - function(x, as.bool = FALSE) { is.dup <- !(!duplicated(x) & rev(!duplicated(rev(x)))) if (as.bool) { is.dup } else { x[is.dup] } } 

El tratamiento de vectores como marcos de datos para pasar a la table es útil, pero puede ser difícil de leer, y la solución data.table está bien, pero prefiero las soluciones de base R para tratar con vectores simples como los ID.