I have a random vector vec
and want make a new vector L
without using a loop. New element of L
depends on old elements of L
and vec
.
set.seed(0)
vec <- rnorm(20,0)
i = 2;
N <- length(vec) -1
L <- numeric(N-1)
constant <- 0.6
while (i < N){
L[i] = vec[i + 1] - vec[i] - constant * L[i - 1]
i <- i + 1
}
L
# [1] 0.0000000 1.6560326 -1.0509895 -0.2271942 -1.8182750 1.7023480 -0.3875622 0.5214906 2.0975262 -2.8995756 0.1771427
# [12] -0.4549334 1.1311555 -0.6884468 0.3007724 0.4832709 -1.4341071 2.1880687
You want
Let
dv <- diff(vec)
, the 2nd line becomesan AR1 process with lag-1 auto-correlation
-constant
and innovationdv[-1]
. AR1 process can be efficiently generated byfilter
with "recursive" method.I guess you mean
while (i <= N)
in your question. If you do wanti < N
, then you have to get rid of the last element above. Which can be done byhours later...
I was brought to attention by Rui Barradas's benchmark. For short
vec
, any method is fast enough. For longvec
,filter
is definitely faster, but practically suffers from coercion asfilter
expects and returns a "ts" (time series) object. It is better to call its workhorse C routine straightaway:I am not interested in comparing
AR1_FILTER
with R-level loop. I will just compare it withfilter
.When you have to compute values based on previous values the general purpose answer is no, there is no way around a loop.
In your case I would use a
for
loop. It's simpler.Note the use of
seq_len
, not2:(N - 1)
.Edit.
I have timed the solutions by myself and by user 李哲源. The results are clearly favorable to my solution.
On my PC the ratio of the medians gives my code 11 times faster.
I was thinking about using Rcpp for this, but one of the answer mentioned
rfilter
built internally in R, so I had a check:This function is already pretty look and I don't think I could write an Rcpp one to beat it with great improvement. I did a benchmark with this
rfilter
and thef1
function in the accepted answer:For short vectors with length 100, I got
For large vectors with length 10000, I got
Yeah, there is no way that R is going to beat a compiled language.