Eliminar filas duplicadas

152

He leído un CSVarchivo en un R data.frame. Algunas de las filas tienen el mismo elemento en una de las columnas. Me gustaría eliminar filas que son duplicados en esa columna. Por ejemplo:

platform_external_dbus          202           16                     google        1
platform_external_dbus          202           16         space-ghost.verbum        1
platform_external_dbus          202           16                  localhost        1
platform_external_dbus          202           16          users.sourceforge        8
platform_external_dbus          202           16                    hughsie        1

Solo me gustaría una de estas filas ya que las otras tienen los mismos datos en la primera columna.

usuario1897691
fuente
3
¿Cuál quieres? solo el primero? en otras palabras: ¿desea mantener googleo localhosto hughsie?
Anthony Damico
No importa para esta parte de mi análisis estadístico. Solo estoy tratando de relacionar el título del proyecto (primera columna), el número de errores (segunda columna) y el número de organizaciones en el proyecto (tercera columna).
user1897691
3
frio. tirar columnas innecesarias y usar? único
Anthony Damico

Respuestas:

186

simplemente aísle su marco de datos a las columnas que necesita, luego use la función única: D

# in the above example, you only need the first three columns
deduped.data <- unique( yourdata[ , 1:3 ] )
# the fourth column no longer 'distinguishes' them, 
# so they're duplicates and thrown out.
Anthony Damico
fuente
1
Parece que funcionará perfectamente. ¿Puede explicarme qué está pasando con la [,1:3]parte de ese código? Soy nuevo en R, por lo que pregunto lo que solo puedo asumir que es una pregunta obvia.
user1897691
66
@ user1897691 márquelo como correcto entonces;) mire esto y, si le gusta, revise twotorials.com
Anthony Damico
3
Tenga en cuenta que esto eliminará todas las columnas, excepto las tres primeras.
GuillaumeL
186

Para las personas que han venido aquí a buscar una respuesta general para la eliminación de filas duplicadas, use !duplicated():

a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)

duplicated(df)
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE

> df[duplicated(df), ]
  a b
2 A 1
6 B 1
8 C 2

> df[!duplicated(df), ]
  a b
1 A 1
3 A 2
4 B 4
5 B 1
7 C 2

Respuesta de: Eliminando filas duplicadas del marco de datos R

Mehdi Nellen
fuente
Quiero crear una nueva variable que marque si hay un duplicado en una determinada variable casi como df $ duplicates <- ifelse (este valor de filas en la columna a == valor de fila anterior en la columna a, 1, 0)
jacob
@jacob vea esta pregunta stackoverflow.com/questions/12495345/…
dpel
2
Esto mantiene el primer valor aparecido y elimina el resto de los duplicados, ¿verdad? ¿O elimina valores al azar?
News_is_Selection_Bias
@alphabetagamma sí, mantiene el primer valor aparecido
Mehdi Nellen
2
Si solo está interesado en duplicados en ciertas columnas, digamos cols 1 y 2, podemos usardf[!duplicated(df[, 1:2])]
qwr
82

La función distinct()en el dplyrpaquete realiza una eliminación duplicada arbitraria, ya sea de columnas / variables específicas (como en esta pregunta) o considerando todas las columnas / variables. dplyres parte de la tidyverse.

Datos y paquete

library(dplyr)
dat <- data.frame(a = rep(c(1,2),4), b = rep(LETTERS[1:4],2))

Eliminar filas duplicadas en una columna específica (por ejemplo, columna a)

Tenga en cuenta que .keep_all = TRUEconserva todas las columnas, de lo contrario solo ase conservaría la columna .

distinct(dat, a, .keep_all = TRUE)

  a b
1 1 A
2 2 B

Eliminar filas que son duplicados completos de otras filas:

distinct(dat)

  a b
1 1 A
2 2 B
3 1 C
4 2 D
Sam Firke
fuente
Gran respuesta, por cierto, .keep_alles para ya sea para mantener todas las columnas, a no ser mezclado con keepen pandas.
Jason Goal
28

El data.tablepaquete también tiene uniquey duplicatedmétodos propios con algunas características adicionales.

Tanto el unique.data.tabley los duplicated.data.tablemétodos tienen un adicional de byargumento que le permite pasar una charactero integervector de nombres de columna o de sus lugares, respectivamente

library(data.table)
DT <- data.table(id = c(1,1,1,2,2,2),
                 val = c(10,20,30,10,20,30))

unique(DT, by = "id")
#    id val
# 1:  1  10
# 2:  2  10

duplicated(DT, by = "id")
# [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE

Otra característica importante de estos métodos es una gran ganancia de rendimiento para conjuntos de datos más grandes.

library(microbenchmark)
library(data.table)
set.seed(123)
DF <- as.data.frame(matrix(sample(1e8, 1e5, replace = TRUE), ncol = 10))
DT <- copy(DF)
setDT(DT)

microbenchmark(unique(DF), unique(DT))
# Unit: microseconds
#       expr       min         lq      mean    median        uq       max neval cld
# unique(DF) 44708.230 48981.8445 53062.536 51573.276 52844.591 107032.18   100   b
# unique(DT)   746.855   776.6145  2201.657   864.932   919.489  55986.88   100  a 


microbenchmark(duplicated(DF), duplicated(DT))
# Unit: microseconds
#           expr       min         lq       mean     median        uq        max neval cld
# duplicated(DF) 43786.662 44418.8005 46684.0602 44925.0230 46802.398 109550.170   100   b
# duplicated(DT)   551.982   558.2215   851.0246   639.9795   663.658   5805.243   100  a 
David Arenburg
fuente
7

¡También puedes usar dplyrla distinct()función! Tiende a ser más eficiente que las opciones alternativas, especialmente si tiene muchas observaciones.

distinct_data <- dplyr::distinct(yourdata)
Samantha Karlaina Rhoads
fuente
1
Esta es la misma respuesta que la respuesta de Sam Firke, pero con menos detalles.
qwr
6

La respuesta general puede ser, por ejemplo:

df <-  data.frame(rbind(c(2,9,6),c(4,6,7),c(4,6,7),c(4,6,7),c(2,9,6))))



new_df <- df[-which(duplicated(df)), ]

salida:

      X1 X2 X3
    1  2  9  6
    2  4  6  7
Amit Gupta
fuente
1
Tenga cuidado al usarlo -which, esto conducirá a un error si no hay duplicados, el uso df[!(duplicated(df)), ]puede ser más seguro.
Jason Goal
5

Con sqldf:

# Example by Mehdi Nellen
a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)

Solución:

 library(sqldf)
    sqldf('SELECT DISTINCT * FROM df')

Salida:

  a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2
mpalanco
fuente
Esto tiene la sobrecarga de configurar una base de datos SQL completa. cran.r-project.org/web/packages/sqldf/index.html
qwr
¿Qué quiere decir con configurar una base de datos SQL completa? Esa es una de las principales ventajas: 'con sqldf, el usuario se libera de tener que hacer lo siguiente, todo lo cual se realiza automáticamente: configuración de la base de datos, escribir la declaración de creación de tabla que define cada tabla, importar y exportar desde y hacia la base de datos '. No es una solución óptima, pero útil para quienes están familiarizados con SQL.
mpalanco
3

O podría anidar los datos en los cols 4 y 5 en una sola fila con tidyr:

library(tidyr)
df %>% nest(V4:V5)

# A tibble: 1 × 4
#                      V1    V2    V3             data
#                  <fctr> <int> <int>           <list>
#1 platform_external_dbus   202    16 <tibble [5 × 2]>

Los duplicados de col 2 y 3 ahora se eliminan para el análisis estadístico, pero ha mantenido los datos de col 4 y 5 en un tibble y puede volver al marco de datos original en cualquier momento unnest().

Joe
fuente
1

Eliminar filas duplicadas de un marco de datos

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe
distinct(mydata)

En este conjunto de datos, no hay una sola fila duplicada, por lo que devolvió el mismo número de filas que en mydata.



Eliminar filas duplicadas basadas en una variable

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe using carb variable
distinct(mydata,carb, .keep_all= TRUE)

La función .keep_all se usa para retener todas las demás variables en el marco de datos de salida.



Eliminar filas duplicadas basadas en múltiples variables

library(dplyr)
mydata <- mtcars

# Remove duplicate rows of the dataframe using cyl and vs variables
distinct(mydata, cyl,vs, .keep_all= TRUE)

La función .keep_all se usa para retener todas las demás variables en el marco de datos de salida.

(de: http://www.datasciencemadesimple.com/remove-duplicate-rows-r-using-dplyr-distinct-function/ )

vasili111
fuente
0

Este problema también se puede resolver seleccionando la primera fila de cada grupo donde el grupo son las columnas en función de las cuales queremos seleccionar valores únicos (en el ejemplo compartido, es solo la primera columna).

Usando la base R:

subset(df, ave(V2, V1, FUN = seq_along) == 1)

#                      V1  V2 V3     V4 V5
#1 platform_external_dbus 202 16 google  1

En dplyr

library(dplyr)
df %>% group_by(V1) %>% slice(1L)

O usando data.table

library(data.table)
setDT(df)[, .SD[1L], by = V1]

Si necesitamos encontrar filas únicas basadas en múltiples columnas, simplemente agregue esos nombres de columna en la parte de agrupación para cada una de las respuestas anteriores.

datos

df <- structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L), 
.Label = "platform_external_dbus", class = "factor"), 
V2 = c(202L, 202L, 202L, 202L, 202L), V3 = c(16L, 16L, 16L, 
16L, 16L), V4 = structure(c(1L, 4L, 3L, 5L, 2L), .Label = c("google", 
"hughsie", "localhost", "space-ghost.verbum", "users.sourceforge"
), class = "factor"), V5 = c(1L, 1L, 1L, 8L, 1L)), class = "data.frame", 
row.names = c(NA, -5L))
Ronak Shah
fuente
0

Aquí hay una muy simple, rápida dplyr/ tidysolución:

Eliminar filas que son completamente iguales:

library(dplyr)
iris %>% 
  distinct(.keep_all = TRUE)

Eliminar filas que son iguales solo en ciertas columnas:

iris %>% 
  distinct(Sepal.Length, Sepal.Width, .keep_all = TRUE)
stevec
fuente