是否有更快的方式来改变百分比?

the*_*ist 1 r dataframe

我有一个包含大约25000条记录和10列的数据框.我正在使用代码来确定相同列(NewVal)中基于另一列(y)的前一个值的更改,其中已经有一个百分比更改.

x=c(1:25000)
y=rpois(25000,2)
z=data.frame(x,y)
z[1,'NewVal']=z[1,'x']
Run Code Online (Sandbox Code Playgroud)

所以我跑了这个:

for(i in 2:nrow(z)){z$NewVal[i]=z$NewVal[i-1]+(z$NewVal[i-1]*(z$y[i]/100))}
Run Code Online (Sandbox Code Playgroud)

这比我预期的要长得多.当然,我可能是一个不耐烦的人 - 正如我曾经说过的一封严厉的信件 - 但我试图逃避Excel的世界(在我阅读http://www.burns-stat.com/pages/Tutor/spreadsheet_addiction之后). html,由于我开始不信任数据,这导致了更多问题 - 这封信也提到了我的信任问题).

我想做到这一点不使用任何功能,从包,因为我想知道是什么创造价值的公式是 - 或者,如果你愿意,我根据这个友好的公文是一个苛刻的控制狂.

我也想知道如何像caTools中的rollmean一样获得移动平均线.要么是这样,要么我怎么弄清楚他们的公式是什么?我尝试进入rollmean,我认为它指的是另一个功能(我是R的新手).这应该是另一个问题 - 但正如那封信所说,我一生中都没有做出正确的决定.

And*_*rie 7

R中的秘密是矢量化.在您的示例中,您可以使用cumprod繁重的工作:

z$NewVal2 <- x[1] * cumprod(with(z, 1 +(c(0, y[-1]/100))))

all.equal(z$NewVal, z$NewVal2)
[1] TRUE

head(z, 10)
    x y   NewVal  NewVal2
1  25 4 25.00000 25.00000
2  24 3 25.75000 25.75000
3  23 0 25.75000 25.75000
4  22 1 26.00750 26.00750
5  21 3 26.78773 26.78773
6  20 2 27.32348 27.32348
7  19 2 27.86995 27.86995
8  18 3 28.70605 28.70605
9  17 4 29.85429 29.85429
10 16 2 30.45138 30.45138
Run Code Online (Sandbox Code Playgroud)

在我的机器上,循环运行只需不到3分钟,而cumprod声明几乎是瞬间完成的.


42-*_*42- 6

我得到了大约800倍的改进Reduce:

    system.time(z[, "NewVal"] <-Reduce("*",  c(1, 1+z$y[-1]/100), accumulate=T) )
   user  system elapsed 
  0.139   0.008   0.148 

> head(z)
    x y NewVal
1   1 1  1.000
2   2 1  1.010
3   3 1  1.020
4   4 5  1.071
5   5 1  1.082
6   6 2  1.103
7   7 2  1.126
8   8 3  1.159
9   9 0  1.159
10 10 1  1.171
> system.time(for(i in 2:nrow(z)){z$NewVal[i]=z$NewVal[i-1]+
                                              (z$NewVal[i-1]*(z$y[i]/100))})
   user  system elapsed 
  37.29  106.38  143.16 
Run Code Online (Sandbox Code Playgroud)

  • +1很好.所以`Reduce`有效地取代了`cumprod` - 这在累积功能不可用的情况下非常有用. (2认同)