【问题标题】:Run for loop without overwriting existing elements in a vector in R运行for循环而不覆盖R中向量中的现有元素
【发布时间】:2017-03-26 11:43:17
【问题描述】:

我是 R 新手,目前正在为 for 循环苦苦挣扎。

我的代码将模拟 8 个股票价格,从股票价格为 100 的时间 0 到时间 8。我想这样做 10 次,并将所有值存储在一个向量 price 中。我的向量最终将包含 80 个价格。但是,存储在向量中的唯一值是最后一次模拟。我不知道如何在不覆盖现有元素的情况下存储所有值。有没有人知道如何做到这一点?

这是我的代码:

S = c(100)
delta = 0.25
sigma = 0.2
rf = 0.01

prices = c()

Ber.reg <- function(S, delta, sigma, rf) {
    for(i in 1:10) {
      for(j in 1:8) {
        S[j+1] <- S[j]*exp((rf - 0.5*sigma^2)*delta + sigma*sqrt(delta)*rnorm(1))
      }
    prices <- S
    }
return(prices)
}

【问题讨论】:

  • prices &lt;- c(prices, S)
  • 谢谢,成功了

标签: r vector


【解决方案1】:

几个问题:

1) 依赖于在运行之前正确初始化全局变量的函数是脆弱函数。拥有prices 全局是糟糕的设计。它应该是函数本地的。

2) 他们唯一与S 相关的是值100。初始价格应该是参数,将其包装在 c() 中是不必要的模糊(尽管无害,因为 100 c(100))。从概念上讲,100 是一个标量

3) 您的代码是 10 次模拟运行,其中每个模拟有 8 个转换步骤。为什么不 a) 将这些数字作为参数而不是硬连接它们? b) 返回一个 matrix ,其中每一行都是一次运行?从逻辑上讲,矩阵比平面向量更多。

4) 不断增长的向量(例如price &lt;- c(price,S))效率低下,因为它反复分配更多空间并将旧值复制到新空间中。由于您提前知道输出的大小,因此一劳永逸地分配空间。

5) 使您的代码更加矢量化。从重复试验次数的初始值向量开始,在每个阶段,在一行代码中更新整个向量,不需要内部循环:

Ber.reg <- function(initial, delta, sigma, rf,runs,steps){
  n <- runs*(steps+1)
  prices <- vector("numeric",n)
  price <- rep(initial,runs)
  prices[1:runs] <- price
  for(i in seq_len(steps)){
    price <- price*exp((rf - 0.5*sigma^2)*delta + sigma*sqrt(delta)*rnorm(runs))
    prices[(1+ i*runs):((i+1)*runs)] <- price
  }
  dim(prices) <- c(runs,steps+1)
  prices
}

例如,使用delta, sigma, rf 的值:

> Ber.reg(100,delta,sigma,rf,3,4)
     [,1]      [,2]      [,3]      [,4]      [,5]
[1,]  100  94.72913  94.35394  92.47475  90.03819
[2,]  100  91.91992  85.05428  83.87200  65.26291
[3,]  100 120.12281 121.45070 131.76266 124.25140

您的代码将(几乎)等同于

prices <- Ber.reg(100,delta,sigma,rf,10,8)

如果您真的想要一个平面向量,请对输出执行此操作:

prices <- as.vector(t(prices))

【讨论】:

  • 非常感谢。在模拟 100,000 条路径时,您的方法肯定更有效,这是我应该做的
  • @KristianLomheim 最近出版的一本让我大开眼界的书(我现在已经完成了一半)是 Gillespie 和 Lovelace 的“Efficient R Programming”。他们的提示之一(也可以在其他来源中找到)是“永远不要增长对象”,而是尽可能预先分配。你可能会喜欢这本书,尽管我会抛出一个警告,即我没有足够的经验来真正判断它的质量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多