【问题标题】:apply function instead of nested loop with if statements使用 if 语句应用函数而不是嵌套循环
【发布时间】:2016-08-15 14:34:46
【问题描述】:

Here is the image showing what i need to calculate。抱歉,图片中的 total_r 实际上是代码中的 test_gain,图片中的 gamma 指的是代码中的 alpha(抱歉)。同样在图像中,我在 t=3 处停止计算,但实际上我想计算它直到最后一个值为 0.6。

我对使用 apply 系列函数还很陌生。我通常使用循环,但我听说使用 apply 函数而不是嵌套的 for 循环要快得多。我尝试了几个教程,但仍然无法用 apply 函数替换我的嵌套 for 循环。任何帮助将不胜感激,下面是我要更改的代码。

基本上这就是我想要做的: 数据的第一行:从列中获取值 + alpha * 该列的下一个值(第 2 行)+ alpha ^ 2 * 列的下一个值(row3)+ alpha ^ 3 * 列的下一个值(row4),依此类推,直到最后一行。每次我都在增加 Alpha 的力量。

所有这些计算都是针对第一行的。现在对于第二行,我将忽略列中的第一个值,但将以相同的方式获取所有后续值。下面是我的代码,它运行良好,但执行时间太长。

#value of alpha
alpha <- 0.85

# test_gain is a vector containing values from a column belonging to a data frame
test_gain <- testdata$Total_rew

# initialise the variables 
s = 0
d = rep(0,nrow(testdata))

for (i in 1:nrow(testdata[1:4999,])){
  d[i] = test_gain[i]
  for (s in (i+1):nrow(testdata)){
    d[i] = d[i] + alpha^(s-i) * test_gain[s]
    if (alpha^(s-i) < (10^-5)) {next()}

  }
}

【问题讨论】:

  • 什么是 gamma,如果 gamma 小于 10^-5 为什么不打印?
  • 通常在 R 中,您会希望将代码矢量化并尽可能避免循环。 apply 系列的代码中有循环。查看有关矢量化的文章
  • 抱歉打错了。伽马实际上是阿尔法。我现在已经改变了。当 alpha 小于 10^-5 时我跳过迭代的唯一原因只是为了加快整个过程。因为当 alpha 达到 10^-5 时,之后的任何东西都会很小,我不需要将它添加到我的总和中
  • @AliJawaad:我不确定这会加快速度,因为我相信你只会去下一个s 而不是i;您应该改用break 吗?无论如何,你会想要一个更好的解决方案。
  • 干杯@aichao。我还附上了一张图片,显示了我想要做的计算。图中total_r指代码中的test_gain

标签: r apply nested-loops


【解决方案1】:

关键是生成一个大小为N 的幂级数为alpha 的上三角矩阵,其中Ntestdata 中的行数,如下所示:

1 alpha alpha^2 alpha^3 ... alpha^(N-1)
0   1   alpha   alpha^2 ... alpha^(N-2)
0   0     1     alpha   ... alpha^(N-3)
0   0     0       1     ... alpha^(N-4)
...                            ...
0   0     0       0             1

然后,计算只是与列testdata$Total_rew 的矩阵相乘。

要生成这个上三角矩阵(改编自this SO question/answer):

## This will work for both nrow(testdata) is odd and even
nr <- ceiling(nrow(testdata)/2 - 1)
mat <- outer(alpha^(-nr:nr), alpha^(-nr:nr))
## reverse the columns
mat <- mat[,rev(seq.int(ncol(mat)))]
## what we want is in the lower triangular, so set the upper triangular to zeroes
mat[upper.tri(mat)] <- 0
## take the transpose so what we want is now upper triangular
mat <- t(mat)

那么,

d <- mat %*% testdata$Total_rew

另请注意,您不需要在上面的最后一步中转置mat。如果您在上述最后一步中转置mat,这也会得到相同的结果:

d <- testdata$Total_rew %*% mat

希望这会有所帮助。

【讨论】:

  • 它确实有帮助,谢谢。我将尝试您建议的方式,看看结果是否与我之前使用嵌套循环提取的值匹配。如果这种方式有效,我可以看到它大大减少了我的计算时间
  • 我可以建议您不要在 alpha^(s-i) 小于 10^-5 时停止该系列吗?我还将编辑答案,但这不会影响结果。
  • 是的,你的权利,我将取出这行代码并让它运行一夜。谢谢
  • 我可以建议您先尝试较少数量的 testdata 行来说服自己它有效吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多