values times many how data column cases appears r count unique aggregate

times - distinct en r



Cómo agregar el recuento de valores únicos por grupo a R data.frame (3)

Deseo contar el número de valores únicos agrupando una segunda variable y luego agregar el conteo al data.frame existente como una nueva columna. Por ejemplo, si el marco de datos existente tiene este aspecto:

color type 1 black chair 2 black chair 3 black sofa 4 green sofa 5 green sofa 6 red sofa 7 red plate 8 blue sofa 9 blue plate 10 blue chair

Quiero agregar para cada color , el recuento de types únicos que están presentes en los datos:

color type unique_types 1 black chair 2 2 black chair 2 3 black sofa 2 4 green sofa 1 5 green sofa 1 6 red sofa 2 7 red plate 2 8 blue sofa 3 9 blue plate 3 10 blue chair 3

Esperaba usar ave , pero parece que no puedo encontrar un método sencillo que no requiera muchas líneas. Tengo> 100,000 filas, así que tampoco estoy seguro de cuán importante es la eficiencia.

Es algo similar a este problema: cuente el número de observaciones / filas por grupo y agregue el resultado al marco de datos


Aquí hay una solución con el paquete dplyr : tiene n_distinct() como un contenedor de length(unique()) .

df %>% group_by(color) %>% mutate(unique_types = n_distinct(type))


Esto también se puede lograr en un vectorizado sin operaciones grupales combinando unique table unique o tabulate

Si df$color es factor , entonces

Ya sea

table(unique(df)$color)[as.character(df$color)] # black black black green green red red blue blue blue # 2 2 2 1 1 2 2 3 3 3

O

tabulate(unique(df)$color)[as.integer(df$color)] # [1] 2 2 2 1 1 2 2 3 3 3

Si df$color es un character , solo

table(unique(df)$color)[df$color]

Si df$color es un integer entonces solo

tabulate(unique(df)$color)[df$color]


Usando ave (ya que lo pides específicamente):

within(df, { count <- ave(type, color, FUN=function(x) length(unique(x)))})

Asegúrese de que el type sea ​​vector de caracteres y no factor.

Como también dice que sus datos son enormes y que la velocidad / el rendimiento pueden ser un factor, sugiero también una solución de datos.

require(data.table) setDT(df)[, count := uniqueN(type), by = color] # v1.9.6+ # if you don''t want df to be modified by reference ans = as.data.table(df)[, count := uniqueN(type), by = color]

uniqueN se implementó en v1.9.6 y es un equivalente más rápido de length(unique(.)) . Además, también funciona con data.frames / data.tables.

Otras soluciones

Usando plyr:

require(plyr) ddply(df, .(color), mutate, count = length(unique(type)))

Usando aggregate :

agg <- aggregate(data=df, type ~ color, function(x) length(unique(x))) merge(df, agg, by="color", all=TRUE)