2011-08-28 17 views
5

Este problema parece trivial, pero estoy en mi ingenio después de horas de lectura.Crear un vector que enumera la longitud de ejecución del vector original con la misma longitud que el vector original

Necesito generar un vector de la misma longitud que el vector de entrada que enumera para cada valor del vector de entrada el recuento total de ese valor. Así, a modo de ejemplo, me gustaría que para generar la última columna de esta trama de datos:

> df 
    customer.id transaction.count total.transactions 
1   1     1     4 
2   1     2     4 
3   1     3     4 
4   1     4     4 
5   2     1     2 
6   2     2     2 
7   3     1     3 
8   3     2     3 
9   3     3     3 
10   4     1     1 

Soy consciente de que esto podría hacerse de dos maneras, ya sea mediante el uso de las tiradas de la primera columna, o la agrupación de la segunda columna usando el primero y aplicando un máximo.

He intentado tanto tapply:

> tapply(df$transaction.count, df$customer.id, max) 

Y RLE:

> rle(df$customer.id) 

Pero ambos devuelven un vector de longitud más corta que la original:

[1] 4 2 3 1 

Cualquier ayuda agradecido ¡aceptado!

+0

Muchas gracias por las respuestas excelentes! Todas las respuestas funcionaron maravillosamente. –

Respuesta

6

Puede hacerlo sin crear contador de transacciones con:

df$total.transactions <- with(df, 
        ave(transaction.count , customer.id , FUN=length)) 
+0

He estado usando variaciones en esto constantemente en las últimas semanas con diferentes funciones en lugar de longitud y ha sido realmente muy útil, también muy rápido en comparación con algunas otras implementaciones. ¡Ojalá tuviera suficientes representantes para votar! ¡Gracias! –

0

Probablemente esté buscando el enfoque dividir-aplicar-combinar; echar un vistazo a ddply en el paquete plyr o la función split en R. base de

1

Usted puede utilizar rle con rep para conseguir lo que quiere:

x <- rep(1:4, 4:1) 
> x 
[1] 1 1 1 1 2 2 2 3 3 4 

rep(rle(x)$lengths, rle(x)$lengths) 
> rep(rle(x)$lengths, rle(x)$lengths) 
[1] 4 4 4 4 3 3 3 2 2 1 

Por motivos de rendimiento, se puede almacenar el objeto rle por separado, por lo que solo se llama una vez.

O, como sugirió Karsten con ddply de plyr:

require(plyr) 

#Expects data.frame 
dat <- data.frame(x = rep(1:4, 4:1)) 
ddply(dat, "x", transform, total = length(x)) 
Cuestiones relacionadas