2011-08-28 18 views
5

Ten problem wydaje się banalny, ale jestem na końcu rozumu po godzinach czytania.Utwórz wektor zawierający początkową długość oryginalnego wektora o tej samej długości co oryginalny wektor

Potrzebuję wygenerować wektor o tej samej długości, co wektor wejściowy, który wyszczególnia dla każdej wartości wektora wejściowego całkowitą liczbę dla tej wartości. Tak więc, tytułem przykładu, chciałbym wygenerować ostatniej kolumnie tej 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 

ja zrealizować można to zrobić na dwa sposoby, albo za pomocą długości ściegu pierwszej kolumny lub grupowanie drugą kolumnę używając pierwszego i stosując maksimum.

Próbowałem zarówno Tapply:

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

And RLE:

> rle(df$customer.id) 

Ale zarówno zwróci wektor krótsze niż oryginalny:

[1] 4 2 3 1 

Każda pomoc z wdzięcznością przyjęty!

+0

Dzięki bardzo za doskonałe odpowiedzi! Wszystkie odpowiedzi działały pięknie. –

Odpowiedz

6

Można to zrobić bez tworzenia licznika transakcji z:

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

Używam wariacji na ten temat w ciągu ostatnich kilku tygodni z różnymi funkcjami zamiast ich długości i jest to naprawdę bardzo przydatne - również bardzo szybkie w porównaniu z niektórymi innymi implementacjami. Żałuję tylko, że nie mam dość przedstawicieli, aby przegłosować! Dzięki! –

0

Prawdopodobnie szukasz podejścia typu split-apply-combine; spojrzeć na ddply w pakiecie plyr lub funkcji w bazie R. split

1

Można użyć rle z rep aby uzyskać to, co chcesz:

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 

Dla celów wydajności, można przechowywać obiekt RLE osobno, więc jest wywoływana tylko raz.

Albo jak Karsten zasugerował z ddply z plyr:

require(plyr) 

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