2012-12-09 29 views
5

Tôi có chuỗi thời gian bán hàng theo ID tài khoản. Để tính toán mức tăng trưởng trung bình, tôi cần trích xuất tháng đầu tiên với doanh số khác 0 cho mỗi ID. Vì tài khoản có thể đã được thiết lập vào các thời điểm khác nhau, tôi cần phải xác định động khi bán hàng> 0 lần đầu tiên trong tài khoản.Tìm lần xuất hiện đầu tiên khác 0 trong khung dữ liệu

Chỉ mục cho hàng sẽ đủ để tôi chuyển đến một hàm tính toán tăng trưởng. Vì vậy, tôi mong đợi các kết quả sau đây bằng ID tài khoản:

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

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

Mọi con trỏ? Ngoài ra, có cách nào dễ dàng hơn để tính CAGR với tập dữ liệu này không?

Cảm ơn trước!

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

Bạn có nói rằng bạn muốn chỉ mục cho hàng đó trong số một tập con của các mục nhập cho một ID mà doanh số bán hàng khác không? Bởi vì 4 cho 87 là chỉ khi bạn đặt bảng này, nếu không nó sẽ là 9 (đếm từ đầu). –

+0

Vâng, đó là chính xác. Tôi chưa hoàn toàn tìm ra cách nhưng với plyr và ggplot, tôi có tầm nhìn về làm việc trên các tập con ID, để tính toán hiệu quả và hiển thị số liệu thống kê tăng trưởng trung bình. – user1100825

Trả lời

6

có giúp đỡ này:

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

nơi df là khung dữ liệu của bạn ở trên không?

Nếu bạn muốn toàn bộ hàng & không chỉ là chỉ số, điều này có thể giúp:

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

Tôi đã chỉnh sửa và thay thế các chỉ mục được mã hóa cứng của bạn (2, 3) bằng các tên cột (ID, Bán hàng). Việc sử dụng các chỉ số ít mạnh mẽ hơn. (Hãy tưởng tượng dữ liệu đến từ một tệp và ai đó quyết định chèn một cột). – flodel

+0

Bây giờ điều này là khá gần với câu trả lời của @ digEmAll. Điểm khác biệt duy nhất là bằng cách sử dụng 'head', bạn sẽ kết thúc với một danh sách trong trường hợp một ID không có giá trị khác không, trong khi anh ta vẫn sẽ nhận được một vector nhưng với' NA'. – flodel

+0

Cảm ơn một tonne @flodel. Tôi nghĩ rằng chúng tôi đã trả lời gần như đồng thời ... :-) Cảm ơn một tấn cho các chỉnh sửa. Tôi nên cẩn thận hơn khi sao chép từ các bản dùng thử của tôi tại bảng điều khiển R. –

3

Dưới đây là một giải pháp khả thi:

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

> res1 
54 87 95 
1 4 2 

đâu res là một vector số với:

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

Nếu bạn muốn để có được các chỉ số của các dòng trong bản gốc data.frame và không trong các tập con, bạn có thể làm:

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

> res2 
54 87 95 
1 9 15 

Sau đó, bạn chỉ có thể sử dụng các chỉ số trong res2, để tập hợp con các 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

Cảm ơn. Điều này có vẻ đầy hứa hẹn! Tôi sẽ cung cấp cho nó một spin. – user1100825

1

Xây dựng trên digEmAll câu trả lời, một giải pháp sử dụng functional lập trình (có thể là một chút bụi):

> res3 <- tapply(
    1:nrow(df) 
    , df$ID 
    , function(Idx) Idx[Position(function(x) df[x, "Sales"] > 0, Idx)] 
) 
> identical(res3, res2) 
[1] TRUE 
Các vấn đề liên quan