2012-12-09 11 views
5

Mam szereg czasowy sprzedaży według identyfikatora konta. Aby obliczyć średni wzrost, muszę wyodrębnić pierwszy miesiąc z niezerową sprzedażą dla każdego identyfikatora. Ponieważ konto mogło zostać utworzone w różnym czasie, muszę dynamicznie identyfikować, kiedy sprzedaż> 0 po raz pierwszy na koncie.Znajdź pierwsze niezerowe wystąpienie w ramce danych

Indeks do rzędu wystarczyłby, aby przejść do funkcji obliczającej wzrost. Spodziewam się następujących wyników według identyfikatora konta:

54 - [1] 
87 - [4] 
95 - [2] 

I tried `apply(df$Sales,2,match,x>0)` but this doesn't work. 

Jakieś wskazówki? Czy istnieje również łatwiejszy sposób obliczenia CAGR na tym zestawie danych?

Z góry dziękuję!

CalendarMonth ID Sales 
8/1/2008 54 6692.60274 
9/1/2008 54 6476.712329 
10/1/2008 54 6692.60274 
11/1/2008 54 6476.712329 
12/1/2008 54 11098.60822 
7/1/2008 87 0 
8/1/2008 87 0 
9/1/2008 87 0 
10/1/2008 87 18617.94155 
11/1/2008 87 18017.36279 
12/1/2008 87 18617.94155 
1/1/2009 87 18617.94155 
2/1/2009 87 16816.20527 
7/1/2008 95 0 
8/1/2008 95 8015.956284 
9/1/2008 95 0 
10/1/2008 95 8015.956284 
11/1/2008 95 6309.447514 
12/1/2008 95 6519.762431 
1/1/2009 95 6519.762431 
+1

Czy mówisz, że chcesz indeks do tego wiersza wśród podzestawu wpisów dla identyfikatora, gdzie sprzedaż jest niezerowa? Ponieważ 4 dla 87 jest tylko wtedy, gdy podzbiór tej tabeli, inaczej byłoby 9 (licząc od góry). –

+0

Tak, to prawda. Jeszcze nie do końca zrozumiałem, jak, ale z plyr i ggplot, mam wizje pracy nad podzbiorami ID, aby skutecznie obliczyć i pokazać średnie statystyki wzrostu. – user1100825

Odpowiedz

6

pomogłoby to:

tapply(df$Sales, df$ID, function(a)head(which(a>0),1)) 

gdzie df jest powyżej ramka danych?

Jeśli chcesz cały wiersz & nie tylko indeks, to może pomóc:

lapply(unique(df$ID),function(a) head(subset(df,ID==a & Sales>0),1)) 
+0

Edytowałem i zastępowałem twoje indeksy zakodowane na stałe (2, 3) nazwami kolumn (ID, Sprzedaż). Korzystanie z indeksów jest mniej niezawodne. (Wyobraź sobie, że dane pochodzą z pliku i ktoś decyduje się wstawić kolumnę). – flodel

+0

Teraz jest to bardzo blisko odpowiedzi @ digEmAll. Jedyną różnicą jest to, że używając 'head', otrzymasz listę w przypadku, gdy ID nie ma niezerowej sprzedaży, podczas gdy on nadal dostanie wektor, ale z' NA'. – flodel

+0

Dzięki za tonę @flodel. Myślę, że odpowiedzieliśmy niemal jednocześnie ... :-) Dziękuję za zmiany. Powinienem być bardziej ostrożny podczas kopiowania z moich prób na konsoli R. –

3

Oto możliwe rozwiązanie:

res1 <- tapply(df$Sales,INDEX=df$ID,FUN=function(x) which(x > 0)[1]) 

> res1 
54 87 95 
1 4 2 

Gdzie res jest wektorem numerycznej:

> names(res) 
[1] "54" "87" "95" 

Jeśli chcesz uzyskać indeksy rzędu w oryginalnym data.frame i nie w podzbiorze możesz:

res2 <- tapply(1:nrow(df), 
       INDEX=df$ID,FUN=function(idxs) idxs[df[idxs,'Sales'] > 0][1]) 

> res2 
54 87 95 
1 9 15 

Następnie można po prostu użyć indeksów w res2, do podzbioru data.frame:

df2 <- df[res2,] 

> df2 
CalendarMonth ID  Sales 
    8/1/2008  54  6692.603 
10/1/2008  87 18617.942 
    8/1/2008  95  8015.956 
+0

Dzięki. To wygląda obiecująco! Dam mu spin. – user1100825

1

Opierając się na digEmAll odpowiedź, rozwiązanie przy użyciu programowania functional (może nieco czystsze):

> res3 <- tapply(
    1:nrow(df) 
    , df$ID 
    , function(Idx) Idx[Position(function(x) df[x, "Sales"] > 0, Idx)] 
) 
> identical(res3, res2) 
[1] TRUE 
Powiązane problemy