2011-08-28 17 views
5

Questo problema sembra banale ma sono alla fine del mio ingegno dopo ore di lettura.Creare un vettore con una lunghezza di esecuzione del vettore originale con la stessa lunghezza del vettore originale

Ho bisogno di generare un vettore della stessa lunghezza del vettore di input che elenca per ogni valore del vettore di input il conteggio totale per quel valore. Così, a titolo di esempio, vorrei generare l'ultima colonna di questa dataframe:

> 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 

Mi rendo conto che questo potrebbe essere fatto in due modi, o usando le tirature della prima colonna, o di raggruppamento la seconda colonna usando il primo e applicando un massimo.

Ho provato sia Tapply:

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

E rle:

> rle(df$customer.id) 

Ma entrambi restituiscono un vettore di lunghezza inferiore rispetto all'originale:

[1] 4 2 3 1 

Qualsiasi aiuto riconoscente accettato!

+0

Grazie tanto per le risposte eccellenti! Tutte le risposte hanno funzionato magnificamente. –

risposta

6

È possibile farlo senza creare contatore di posizioni con:

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

Nelle ultime settimane utilizzo costantemente delle variazioni con funzioni diverse al posto della lunghezza ed è stato davvero molto utile - anche molto veloce rispetto ad altre implementazioni. Spero solo di aver avuto abbastanza rep per upvote! Grazie! –

0

Probabilmente stai cercando un approccio split-apply-combine; dare un'occhiata al ddply nel pacchetto plyr o la funzione split in R. base di

1

È possibile utilizzare rle con rep per ottenere ciò che si vuole:

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 

Ai fini delle prestazioni, è possibile memorizzare l'oggetto rle separatamente, quindi viene chiamato solo una volta.

O come Karsten suggerito con ddply da plyr:

require(plyr) 

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