如何生成序列中的前n个项:

时间:2019-02-24 07:49:39

标签: r tidyverse

整洁的方式? (例如n = 10)

enter image description here

我认为lag会有所帮助,但我无法获得正确的结果。

4 个答案:

答案 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

两条小评论:

  1. 我们用numeric(n)初始化向量,比执行例如rep(0, 10)
  2. 其余的只是一个经典的for循环,它从返回向量的第二个索引处开始。

或使用Rcpp

的C ++解决方案
    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)

this question

答案 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