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)