Здесь немного другой вариант
f <- function(a1 = 1, n = 10) {
ret <- numeric(n) # Pre-allocation
ret[1] <- a1
for (i in 2:length(ret)) ret[i] <- 5 * ret[i - 1] + 3 ^ (i - 1)
ret
}
f(n = 10)
#[1] 1 8 49 272 1441 7448 37969 192032 966721
#[10] 4853288
Два небольших комментария:
- Мы инициализируем вектор с
numeric(n)
, что быстрее, чем, например, rep(0, 10)
. - Остальное - просто классический цикл
for
, который начинается со второго индекса вектора возврата.
Или решение C ++ с использованием Rcpp
library(Rcpp)
cppFunction("
IntegerVector f2(int n = 10, int a1 = 1) {
IntegerVector ret(n, a1);
for (int i = 1; i < n; i++) {
ret[i] = 5 * ret[i - 1] + pow(3, i);
}
return ret;
}")
f2(10)
# [1] 1 8 49 272 1441 7448 37969 192032 966721
#[10] 4853288
и microbenchmark
сравнение
library(microbenchmark)
res <- microbenchmark(
R_for_loop = f(n = 10),
Rcpp_for_loop = f2(n = 10)
)
#Unit: microseconds
# expr min lq mean median uq max neval cld
# R_for_loop 3.226 3.4195 3.78043 3.4945 3.5625 29.365 100 b
# Rcpp_for_loop 1.913 2.0980 2.36980 2.2560 2.3495 12.582 100 a
library(ggplot2)
autoplot(res)