una tabla seleccionar matriz filas extraer eliminar datos contar como columnas columna r

r - tabla - Subconjunto con casos únicos, basado en múltiples columnas



seleccionar datos en r (5)

Me gustaría subconjuntar un marco de datos para incluir solo las filas que tienen combinaciones únicas de tres columnas. Mi situación es similar a la presentada en this pregunta, pero me gustaría conservar las otras columnas en mis datos también. Aquí está mi ejemplo:

> df v1 v2 v3 v4 v5 1 7 1 A 100 98 2 7 2 A 98 97 3 8 1 C NA 80 4 8 1 C 78 75 5 8 1 C 50 62 6 9 3 C 75 75

El resultado solicitado sería algo como esto, en el que estoy buscando casos únicos basados ​​en v1, v2 y v3 solamente:

> df.new v1 v2 v3 v4 v5 1 7 1 A 100 98 2 7 2 A 98 97 3 8 1 C NA 80 6 9 3 C 75 75

Si pudiera recuperar las filas no exclusivas también sería genial:

> df.dupes v1 v2 v3 v4 v5 3 8 1 C NA 80 4 8 1 C 78 75 5 8 1 C 50 62

Vi una pregunta relacionada sobre cómo hacer esto en sql ( here ), pero no puedo obtener esto en R. Estoy seguro de que es simple, pero jugar con unique () y subconjunto () no ha sido fructífero. Gracias por adelantado.


Puede usar la función duplicated() para encontrar las combinaciones únicas:

> df[!duplicated(df[1:3]),] v1 v2 v3 v4 v5 1 7 1 A 100 98 2 7 2 A 98 97 3 8 1 C NA 80 6 9 3 C 75 75

Para obtener solo los duplicados, puede verificarlo en ambas direcciones:

> df[duplicated(df[1:3]) | duplicated(df[1:3], fromLast=TRUE),] v1 v2 v3 v4 v5 3 8 1 C NA 80 4 8 1 C 78 75 5 8 1 C 50 62


Puedes usar el paquete plyr :

library(plyr) ddply(df, c("v1","v2","v3"), head, 1) # v1 v2 v3 v4 v5 # 1 7 1 A 100 98 # 2 7 2 A 98 97 # 3 8 1 C NA 80 # 4 9 3 C 75 75 ddply(df, c("v1","v2","v3"), function(x) if(nrow(x)>1) x else NULL) # v1 v2 v3 v4 v5 # 1 8 1 C NA 80 # 2 8 1 C 78 75 # 3 8 1 C 50 62


Sí, pero usar plyr y ddply es muy lento si tienes demasiados datos.

Deberías intentar algo de este tipo:

df[ cbind( which(duplicated(df[1:3])), which(duplicated(df[1:3], fromLast=TRUE))),]

o::

from = which(duplicated(df[1:3]) to = which(duplicated(df[1:3], fromLast=TRUE)) df[cbind(from,to),]

SHD ser más rápido en su mayor parte.

pruébalo y haznos saber

hay algunos errores, pero supongo que puedes arreglarlos mientras tengas la idea.

También intente único y todo eso


Una forma no elegante pero funcional es pegar las entradas de una fila dada y encontrar cuáles son filas únicas (o no únicas), algo así como:

df.vector=apply(df,1,FUN=function(x) {paste(x,collapse="")}) df.table=table(df.vector)

luego obtenga los índices de los duplicados con algo como:

which(df.vector%in%names(which(df.table>1)))


Usando dplyr puedes hacer:

library(dplyr) # distinct df %>% distinct(v1, v2, v3, .keep_all = T) # non-distinct only df %>% group_by(v1, v2, v3) %>% filter(n() > 1) # exclude any non-distinct df %>% group_by(v1, v2, v3) %>% filter(n() == 1)