2

假设我有一个向量v = c(250,1200,700)、一个起始值n和一个函数,例如

f = function(v){

g = function(v){ 
    cases(
    v <= 20 -> 0.1,
    v > 20 & v <= 100 -> 0.075,
    v > 100 -> .05
    )  
  }
  suppressWarnings(g(v))
}

f是使用包中编写casesmemisc——我对 R 还是新手,很想知道是否f可以用“更好”的方式进行编码。无论如何,我正在寻找将执行以下递归过程的代码(包括“大”长度的向量):

f(n), 
f(n)*v[1]+n, 
f(f(n)*v[1]+n)*v[2] + f(n)*v[1]+n, 
f(f(f(n)*v[1]+n)*v[2] + f(n)*v[1]+n)*v[3] + f(f(n)*v[1]+n)*v[2] + f(n)*v[1]+n 

最终我对最后一行的价值感兴趣。

为任何帮助而欢呼

4

2 回答 2

3

如果我理解正确,这就是您所说的过程:

 X1 = f(n)
 X2 = X1*v[1] + n
 X3 = F(X2)*v[2] + X2
 X4 = F(X3)*v[3] + X3 
...

如果您需要所有中间步骤,则递归函数相当无用,因为您还需要存储在结果中的中间步骤。因此,您可以使用基本的 R 轻松编写代码:

Thefun <- function(v,n){
  l <- length(v)
  res <- numeric(l+1)

  res[1] <- g(n)
  res[2] <- res[1]*v[1] + n
  for(i in seq(2,l)){
    res[i+1] <- res[i] + g(res[i])*v[i]
  }
  return(res)
}

结果的最后一个值是您需要的结果。由于您只需要最后一步的结果,因此您可以使用以下方法递归地执行此操作Recall

Recfunc <- function(v,n){
    l <- length(v)
    if(l > 0){
        res <- Recall(v[-l],n)
        return(g(res)*v[l] + res)
    } else {
      return(n)
    } 
}

在旁注上

你可以定义你的函数 g 不同,像这样(我称之为 fv):

fv <- function(v){
   0.1*(v <= 20) + 0.075*(v > 20 & v <=100) + 0.05*(v>100)
}

如果与您的功能相比,您的速度将提高 6 倍。

vec <- sample(1:150,1e5,TRUE)
benchmark(
   fv(vec),
   g(vec),
   columns=c("test","replications","elapsed","relative"),
   replications = 1000

)

     test replications elapsed relative
1 fv(vec)         1000    9.39    1.000
2  g(vec)         1000   56.30    5.996
于 2013-02-07T15:27:15.637 回答
1

我在这里假设这n是 v 的长度。我像这样重写 recursion:

y1 <- n                  ## slight change here
y2 <- f(y1)*v[1] +y1, 
y3 <- f(y2)*v[2] +y2
y4 <- f(y3)*v[3] +y3
.... I can''t see the terms > length(v) so my first assumption

因此,例如,您可以像这样实现:

filter.f <- function(func=f,coef=v){
  n <-  length(coef)
  y <- numeric(n)
  y[1] <- n
  for(i in 2:n)
    y[i] <- func(y[i-1])*coef[i-1]+y[i-1] ## here the recursion
  y[1] <- f(n)
  y
}

 filter.f()
[1]   0.1 124.0 159.0 191.5
 v=c(250, 1200, 700)
filter.f()
[1]   0.1  28.0 118.0
于 2013-02-07T14:59:44.457 回答