【问题标题】:Gettting cumulative sum of previous values except for the first value获取除第一个值之外的先前值的累积总和
【发布时间】:2024-04-29 16:20:02
【问题描述】:

我在 R 中运行代码,其示例如下,带有一个小数据集 -

library(plyr)
Ex<-structure(list(X1 = c(-36.8598, -37.1726, -36.4343, -36.8644, 
                      -37.0599, -34.8818, -31.9907, -37.8304, 
                      -34.3367, -31.2984, -33.5731), 
               X2 = c(64.26, 63.085, 66.36, 61.08, 61.57, 65.04, 72.69, 63.83, 
                      67.555, 76.06, 68.61), 
               Y1 = c(493.81544, 493.81544, 494.54173, 
                      494.61364, 494.61381, 494.38717, 494.64122, 493.73265,             494.04246, 
                      494.92989, 494.98384), 
               Y2 = c(489.704166, 489.704166, 490.710962, 
                      490.653212, 490.710612, 489.822928, 
                      488.160904, 489.747776, 490.600579, 
                      488.946738, 490.398958), 
               Y3 = c(19L, 19L, 19L, 23L, 30L,43L,43L,2L, 58L, 47L, 61L),
               date = c("2013-06-01","2013-06-02","2013-06-03","2013-06-04",
                        "2013-06-05","2013-06-06","2013-06-07","2013-06-08",
                        "2013-06-09","2013-06-10","2013-06-11")), 
          .Names = c("X1", "X2", "Y1", "Y2", "Y3", "date"), 
          row.names = c(NA, 11L), class = "data.frame")

Ex <- arrange(Ex, Y3)

Ex$Dup <- as.numeric(duplicated(Y3))
Ex$Dup_rev <- as.numeric(duplicated(Y3,fromLast=TRUE))

##Testing If Else
attach(Ex)
Ex$X5 <- 0
for(i in 1:length(Y3))
{
  if (Ex$Dup[i]==0 & Ex$Dup_rev[i]==0)
  {
    Ex$X5[i]=Y2[i]
  } else if(Ex$Dup[i]==0)
  {
    Ex$X5[i]=Y2[i]
  }else 
    {Ex$X5[i]=Y2[i] + X5[i-1]}
}

这样做的目的是,除非 Y3 列的值是第一次出现在数据集中,否则对于 Y3 的每一行,我们都需要创建一个 X5 列,它是之前 Y2 的累积和。 由于我的数据量很大(大约 110k 行数据),因此这段代码需要花费大量时间来执行。有没有更简单的方法来执行相同的代码?

X1  X2  Y1  Y2  Y3  date    Dup Dup_rev X5
 1  -37.8304    63.830  493.7326    489.7478    2   2013-06-08  0   0   489.7478
 2  -36.8598    64.260  493.8154    489.7042    19  2013-06-01  0   1   489.7042
 3  -37.1726    63.085  493.8154    489.7042    19  2013-06-02  1   1   1469.1125
 4  -36.4343    66.360  494.5417    490.7110    19  2013-06-03  1   0   1470.1193
 5  -36.8644    61.080  494.6136    490.6532    23  2013-06-04  0   0   490.6532

【问题讨论】:

  • 你能发布你想要的输出吗?我从运行你的代码得到的输出与你正在寻找的内容的描述不匹配
  • 我的错误,例如a = c(1, 2, 3, 4, 5),我想创建b这样b[i] = a[i] + b[i-1 ]。其中 b[1] = 0。
  • 您可以使用示例中的变量名吗?因此,在您刚刚发布的输出中,第三行中X5 的值是1469.1125。根据您的解释,它听起来应该等于Y2[3] + X5[2],即489.7042 + 489.7042 = 979.4084。抱歉,如果我遗漏了一些非常明显的东西,但我不知道 1469.1125 来自哪里

标签: r if-statement sum cumsum


【解决方案1】:

这是一个使用 data.table 的解决方案,如果您按“因子”(在本例中为 Y3)进行拆分,这种分析的速度非常快:

library(data.table)
DT <- data.table(Ex)[, X5:=cumsum(Y2), by=Y3]
DT
#           X1     X2       Y1       Y2 Y3       date        X5
#  1: -37.8304 63.830 493.7326 489.7478  2 2013-06-08  489.7478
#  2: -36.8598 64.260 493.8154 489.7042 19 2013-06-01  489.7042
#  3: -37.1726 63.085 493.8154 489.7042 19 2013-06-02  979.4083
#  4: -36.4343 66.360 494.5417 490.7110 19 2013-06-03 1470.1193
#  5: -36.8644 61.080 494.6136 490.6532 23 2013-06-04  490.6532
#  6: -37.0599 61.570 494.6138 490.7106 30 2013-06-05  490.7106
#  7: -34.8818 65.040 494.3872 489.8229 43 2013-06-06  489.8229
#  8: -31.9907 72.690 494.6412 488.1609 43 2013-06-07  977.9838
#  9: -31.2984 76.060 494.9299 488.9467 47 2013-06-10  488.9467
# 10: -34.3367 67.555 494.0425 490.6006 58 2013-06-09  490.6006
# 11: -33.5731 68.610 494.9838 490.3990 61 2013-06-11  490.3990    

请注意,尽管像 Jake 一样,我不明白您如何在第三行获得 1469 而不是 979.4083。另外,我刚刚运行了您的代码并得到了与我相同的答案,所以我猜您的示例结果中存在拼写错误,或者数据可能已更改?

【讨论】:

  • 非常感谢!这正是我想要的:)
  • @RHelp,如果这回答了您的问题,请考虑将其标记为已回答。
【解决方案2】:

这是一个使用 dplyr 的解决方案。 dplyr 是 plyr 的下一次迭代,速度非常快。

library(dplyr)
Ex %.% group_by(Y3) %.% mutate(X5 = cumsum(Y2))
#> Source: local data frame [11 x 7]
#> Groups: Y3
#> 
#>          X1     X2       Y1       Y2 Y3       date        X5
#> 1  -36.8598 64.260 493.8154 489.7042 19 2013-06-01  489.7042
#> 2  -37.1726 63.085 493.8154 489.7042 19 2013-06-02  979.4083
#> 3  -36.4343 66.360 494.5417 490.7110 19 2013-06-03 1470.1193
#> 4  -36.8644 61.080 494.6136 490.6532 23 2013-06-04  490.6532
#> 5  -37.0599 61.570 494.6138 490.7106 30 2013-06-05  490.7106
#> 6  -34.8818 65.040 494.3872 489.8229 43 2013-06-06  489.8229
#> 7  -31.9907 72.690 494.6412 488.1609 43 2013-06-07  977.9838
#> 8  -37.8304 63.830 493.7326 489.7478  2 2013-06-08  489.7478
#> 9  -34.3367 67.555 494.0425 490.6006 58 2013-06-09  490.6006
#> 10 -31.2984 76.060 494.9299 488.9467 47 2013-06-10  488.9467
#> 11 -33.5731 68.610 494.9838 490.3990 61 2013-06-11  490.3990

【讨论】:

    最近更新 更多