Как сгенерировать первые n членов в серии: - PullRequest
0 голосов
/ 24 февраля 2019

Тидиверс?(скажем, n = 10)

enter image description here

Я думал, что lag было бы полезно, но я не мог получить правильные результаты.

Ответы [ 4 ]

0 голосов
/ 25 февраля 2019

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
0 голосов
/ 24 февраля 2019

Здесь немного другой вариант

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, который начинается со второго индекса вектора возврата.

Или решение 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)

enter image description here

0 голосов
/ 24 февраля 2019

Вы также можете использовать 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
0 голосов
/ 24 февраля 2019

Вот классический подход для цикла.Поскольку вам необходимо получить доступ к результатам итерации ранее, это может быть правильным способом.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...