2012-03-10 29 views
10

Tôi là một người mới sử dụng R và tôi đang gặp nhiều rắc rối khi làm một việc gì đó có lẽ rất đơn giản. Tôi có một tập dữ liệu lớn được chia thành các nhóm theo mã quốc gia và tôi muốn lấy trung bình 3 tháng của chỉ số giá, theo quốc gia và sau đó đặt nó vào một cột mới phù hợp với tháng thích hợp. Tôi đã cố gắng sử dụng rollmean như thế này mà không thành công (mã và thông báo lỗi bên dưới):áp dụng phương tiện lăn theo nhóm trong R

> leader$last3<-tapply(leader, leader$ccode, 
    function(x) rollmean(leader$GI_delta, 3, na.pad=T)) 
Error in tapply(leader, leader$ccode, function(x) rollmean(leader$GI_delta, : 
    arguments must have same length 

> leader$last3<-ddply(leader, .(ccode), 
    rollmean(GI_delta, 3, na.pad=T)) 

Error in llply(.data = .data, .fun = .fun, ..., .progress = .progress, : 
    .fun is not a function. 

Bất kỳ trợ giúp nào cũng được đánh giá cao!

Trả lời

5

Trong lần thử đầu tiên, chức năng của bạn không sử dụng đối số x, và luôn trả về cùng một thứ (một véc tơ có kích thước sai). Ngoài ra, đối số đầu tiên, phải là một vectơ. Cuối cùng, tapply trả về danh sách các vectơ: bạn không thể đặt kết quả trực tiếp vào data.frame.

library(zoo) 
n <- 10 
leader <- data.frame(
    ccode = rep(LETTERS[1:3],each=n), 
    GI_delta = rnorm(3*n) 
) 
tapply(
    leader$GI_delta, 
    leader$ccode, 
    function(x) rollmean(x, 3, na.pad=TRUE) 
) 

Trong ví dụ thứ hai của bạn, đối số thứ ba của plyr phải là một chức năng, không phải là một biểu hiện. Nếu bạn muốn sử dụng một biểu thức, bạn có thể sử dụng summarize hoặc transform như một chức năng (summarize trả về một data.frame 1 hàng cho mỗi giá trị của ccode, trong khi transform giữ số hàng không thay đổi), và đặt các biểu thức như các đối số khác.

library(plyr) 
ddply(
    leader, "ccode", 
    transform, 
    last3 = rollmean(GI_delta, 3, align="right", na.pad=TRUE) 
) 
+0

Cảm ơn sự giúp đỡ của bạn Vincent! –

13

Nếu bạn muốn tạo cột mới, hãy thử sử dụng ave. Nó giống như tapply nhưng trả về một vectơ có độ dài bằng với đối số đầu tiên của nó. Kinh nghiệm của tôi là nó nhanh hơn rất nhiều so với ddply:

require(zoo) 
leader$last3<-ave(leader$GI_delta, leader$ccode, 
         FUN= function(x) rollmean(x, k=3, na.pad=T)) 
+0

Cảm ơn, công trình này tuyệt vời! –

Các vấn đề liên quan