studio repetidos identificar filas eliminar duplicados duplicadas datos contar columnas r duplicates duplicate-removal

repetidos - eliminar filas duplicadas en r



Eliminar duplicados manteniendo la entrada con el mayor valor absoluto (7)

Digamos que tengo cuatro muestras: id = 1, 2, 3 y 4, con una o más mediciones en cada una de esas muestras:

> a <- data.frame(id=c(1,1,2,2,3,4), value=c(1,2,3,-4,-5,6)) > a id value 1 1 1 2 1 2 3 2 3 4 2 -4 5 3 -5 6 4 6

Quiero eliminar los duplicados, manteniendo solo una entrada por ID, la que tenga el mayor valor absoluto de la columna "valor". Es decir, esto es lo que quiero:

> a[c(2,4,5,6), ] id value 2 1 2 4 2 -4 5 3 -5 6 4 6

¿Cómo podría hacer esto en R?


Aquí hay un enfoque dplyr

library(dplyr) a %>% group_by(id) %>% top_n(1, abs(value)) # A tibble: 4 x 2 # Groups: id [4] # id value # <dbl> <dbl> #1 1 2 #2 2 -4 #3 3 -5 #4 4 6


Echa un vistazo a ?aggregate :

aggregate(value~id,a,function(x) x[which.max(abs(x))])

Me gusta la respuesta de @DWin, pero me gustaría mostrar cómo esto también podría funcionar con los metadatos:

aa<-merge(aggregate(value~id,a,function(x) x[which.max(abs(x))]),a) # Fails if the max value is duplicated for a single id without next line. aa[!duplicated(aa),]

No pude evitarlo y creé una última respuesta:

do.call(rbind,lapply(split(a,a$id),function(x) x[which.max(abs(x$value)),]))


Otro enfoque (aunque el código puede parecer un poco engorroso) es usar ave() :

a[which(abs(a$value) == ave(a$value, a$id, FUN=function(x) max(abs(x)))), ] # id value # 2 1 2 # 4 2 -4 # 5 3 -5 # 6 4 6


Puedes hacer esto con dplyr de la siguiente manera:

library(dplyr) a %>% group_by(name) %>% filter(n == max(n)) %>% ungroup()


Un enfoque de data.table podría estar en orden si su conjunto de datos es muy grande:

library(data.table) aDT <- as.data.table(a) setkey(aDT,"id") aDT[J(unique(id)), list(value = value[which.max(abs(value))])]


O una alternativa no tan rápida, pero a la vez rápida:

library(data.table) as.data.table(a)[, .SD[which.max(abs(value))], by=id]

Esta versión devuelve todas las columnas de a , en caso de que haya más en el conjunto de datos real.


aa <- a[order(a$id, -abs(a$value) ), ] #sort by id and reverse of abs(value) aa[ !duplicated(aa$id), ] # take the first row within each id id value 2 1 2 4 2 -4 5 3 -5 6 4 6


library(plyr) ddply(a, .(id), function(x) return(x[which(abs(x$value)==max(abs(x$value))),]))