答案 0 :(得分:3)
这里的选项稍有不同
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
循环,它从返回向量的第二个索引处开始。 或使用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)
答案 1 :(得分:2)
这是经典的for循环方法。由于您需要访问之前迭代的结果,因此这可能是合适的方法。
library(dplyr)
t <- tibble(k = 1:10, a = NA)
for (i in 1:nrow(t)){
if (i == 1){
t[i, "a"] <- 1
} else {
t[i, "a"] <- 5 * t[i - 1, "a"] + 3 ^ t[i - 1, "k"]
}
}
t
# A tibble: 10 x 2
# k a
# <int> <dbl>
# 1 1 1
# 2 2 8
# 3 3 49
# 4 4 272
# 5 5 1441
# 6 6 7448
# 7 7 37969
# 8 8 192032
# 9 9 966721
# 10 10 4853288
答案 2 :(得分:2)
您也可以为此使用vapply
# Init
len <- 10L + 1L
init = 1L
x <- numeric(len); x[[1]] <- init
# Create sequence
vapply(2:len, function (k) x[[k]] <<- 5*x[[k-1L]] + 3^(k-1L), numeric(1))
# Result
x
# [1] 1 8 49 272 1441 7448 37969 192032 966721 4853288 24325489
答案 3 :(得分:2)
Tidyverse解决方案:比“ for_loop”和“ vapply”方法慢
library(tidyverse)
# f31 is slightly faster (using function) instead of formula (on f32)
f31 <- function(a1 = 1, n = 10) {
x <- c(a1,rep(0,n-1))
map_dbl(2:n, function (k) x[k] <<- 5*x[k-1] + 3^(k-1))
return(x)
} #func
f31(n=10)
# [1] 1 8 49 272 1441 7448 37969 192032 966721
# [10] 4853288
f32 <- function(a1 = 1, n = 10) {
x <- c(a1,rep(0,n-1))
map_dbl(2:n, ~ {x[.] <<- 5*x[.-1] + 3^(.-1)})
return(x)
} # func
f32(n=10)
# [1] 1 8 49 272 1441 7448 37969 192032 966721
# [10] 4853288