2014-10-22 15 views
5

Tôi khá quen thuộc với R vì tôi đã sử dụng nó trong một vài năm nay. Thật không may, tôi không phải là rất thạo trong việc tạo ra các chức năng liên quan đến lặp hoặc lặp lại của một phương trình. Sự cố xảy ra như sau:Lặp lại hoặc lặp lại một đối số

Tôi có vectơ chứa hơn 1000 giá trị. Tôi muốn tính toán sự khác biệt tuyệt đối giữa hai phương tiện juxtaposing có kích thước bằng nhau từ một tập con của vector đó.

Đây là một ví dụ.

Tôi có vector (VEC) có độ dài 8

[1] 0.12472963 1.15341289 -1.09662288 -0.73241639 0.06437658 -0.13647136 -1.52592048 1.46450084 

Tôi muốn tính toán giá trị trung bình của 2 giá trị đầu tiên (0,12472963, 1,15341289) và có được sự khác biệt tuyệt đối với giá trị trung bình của 2 giá trị sau (-1.09662288 -0.73241639), sau đó, làm việc theo cách của tôi xuống vector.

Trong trường hợp này, tôi có thể dễ dàng sử dụng các phương trình sau:

abs(mean(vec[1:2])-mean(vec[3:4])) 

và từng bước tăng mỗi số 1 để làm việc theo cách của tôi xuống bằng tay cho đến cuối của vector. Tôi sẽ có được véc tơ sau.

[1] 1.553591 0.3624149 0.8784722 0.497176 0.005337574 

Điều tôi muốn, có thói quen tự động cho phép tôi thực hiện điều đó qua các vectơ dài và thay đổi số giá trị để tính phương tiện.

Dường như với tôi rằng nó phải tương đối đơn giản, nhưng tôi không biết bắt đầu từ đâu.

+1

Bạn có thể nhìn vào 'rollapply() 'từ' gói zoo'. –

Trả lời

7

Sử dụng filter:.

c(abs(filter(vec, c(0.5, 0.5, -0.5, -0.5), sides=1)[-(1:3)])) 
#[1] 1.55359090 0.36241491 0.87847224 0.49717601 0.00533757 
+0

Xuất hiện để được gửi nhanh nhất cho đến nay. –

2

Sử dụng rollapply từ zoo

library(zoo) 
n <- 2 
n1 <- length(vec) 

abs(rollapply(vec[1:(n1-n)], 2, mean)-rollapply(vec[(n+1):n1], 2,mean)) 
#[1] 1.55359090 0.36241491 0.87847224 0.49717601 0.00533757 

Ngoài ra, các biến thể khác của các mã trên (từ bình luận bằng @G Grothendieck- một trong những tác giả của zoo gói)

abs(rollmean(vec[1:(n1-n)], 2) - rollmean(vec[(n+1):n1], 2)) #using 
    #`rollmean` instead of `rollapply` 

hoặc

rollapply(vec, 4, function(x) abs(mean(x[1:2]) - mean(x[3:4]))) 

hoặc

abs(rollapply(vec, 4, "%*%", c(1, 1, -1, -1)/2)) 
+1

Những biến thể này cũng hoạt động: 'abs (rollmean (vec [1: (n1-n)], 2) - rollmean (vec [(n + 1): n1], 2))' và 'rollapply (vec, 4, hàm (x) abs (trung bình (x [1: 2]) - trung bình (x [3: 4]))) 'và' abs (rollapply (vec, 4, "% *%", c (1, 1, -1, -1)/2)) '. –

+0

@G. Grothendieck Cảm ơn nhận xét và cung cấp các biến thể. – akrun

1

Như mọi khi, tôi kêu vang trong với:

vec<-rep(c( 0.12472963 , 1.15341289, -1.09662288, -0.73241639 , 0.06437658, -0.13647136 ,-1.52592048 , 1.46450084 ),100) 

microbenchmark(roland(vec),akrun(vec),times=3) 

Unit: microseconds 
     expr  min   lq  mean median  uq  max 
    roland(vec) 564.128 565.2275 647.3353 566.327 688.939 811.551 
    akrun(vec) 3717.410 3982.1535 4218.3057 4246.897 4468.753 4690.610 
neval 
    3 
    3 
+1

Tôi đã cập nhật câu trả lời của mình với một thay đổi nhỏ nên cải thiện hiệu suất và đảm bảo xử lý đúng các giá trị 'NA'. – Roland

+0

@RichardScriven awwwwww .... :-) –

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