【问题标题】:R Cumulative calculation based on prior values in the same columnR 基于同一列中的先前值的累积计算
【发布时间】:2016-11-08 00:18:23
【问题描述】:

这就是我的数据框的样子。 V3 是我想要的专栏。 V3 我无法使用。

library(data.table)
dt <- fread('

Level  V1  V2  
  0    10  2     
  1     0  3     
  1     0  2    
  1     0  2 ')

我正在尝试根据 V3 的先前值计算 V3。 V3公式为:

New Value of V3 =((Prior Value of V3+ Prior Value of V3*V2)*Level)+V1
1st Row V3 = (NA+NA*3)*1 + 10 = 10
2nd Row V3 = (10+10*3)*1 + 0 =40
3rd Row V3 = (40+40*2)*1 + 0 =120
4th Row V3  = (120+120*2)*1 + 0 = 360

输出应该是这样的。

Level  V1  V2  V3
  0    10  2   10  
  1     0  3   40  
  1     0  2   120 
  1     0  2   360

我在尝试:

dt[,V3:= (cumsum(V3+V3*V2)*Level)+V1]

【问题讨论】:

  • 问题的特殊功能在这里可能会有很长的路要走。例如,如果您知道 V1 在开始时始终为非零,此后始终为零,如本例所示,您有 V1[1] * cumprod((Level*(1 + V2))[-1])
  • 我猜你想只使用 Level、V1、V2 来获得 V3,但如果是这样还不够清楚(如下面的答案所示,它们使用 V3 构建 V3)。
  • @Frank 我的意图是使用V1,V2从前一行生成的V1,V2和V3来构建新的V3。
  • 好的,但这只需要使用 V3[1],第一个元素,对吗?如果我正确阅读了其他答案,那么他们也正在使用向量的其他元素。无论如何,我可能误会了。
  • @Frank 不,你是对的。我正在使用 V3[1] 让球滚动。我没有可用的 V3 列来生成新的 V3。我正在尝试使用dt[,V3:= V1[1] * cumprod((Level*(1 + V2))[-1])],但它显示错误。

标签: r data.table dplyr cumsum


【解决方案1】:

我在 cmets 中重做了你的努力以获得预期的结果:

 dt[,V3:=cumprod( c(V1[1] ,(Level*(1 + V2))[-1]) ) ]
 dt

   Level V1 V2  V3
1:     0 10  2  10
2:     1  0  3  40
3:     1  0  2 120
4:     1  0  2 360

我实际上并没有收到 dt[,V3:= V1[1] * cumprod((Level*(1 + V2))[-1])] 的错误(只有警告)。使用 [-1] 缩短了没有扩展的 cumprod,并导致回收。

【讨论】:

  • 非常感谢您的回答! cumprod 的想法最初来自@Frank
  • 我发现自己想知道是否可以使用这种方法来模拟涉及噪声序列相乘的差分方程。
  • 这里是相关问题stackoverflow.com/questions/40495918/…。我曾尝试在此使用 cumprod 无济于事。
【解决方案2】:

data.table

dt[,{ lag.V3=c(0, V3[-.N]) ; V3 = (lag.V3 + lag.V3 * V2 )* Level + V1 }]

输出

[1]  10  40 120 360

【讨论】:

  • 仅供参考,data.table 引入了移位运算符,因此您可以执行shift(V3, type = "lead", fill = 0) 之类的操作。另外,我猜没有理由不将(lag.V3 + lag.V3 * V2) 简化为(1+V2)*lag.V3
  • @Frank Hi Frank,您介意发布您的“轮班”解决方案作为答案吗?
  • @gibbz00 抱歉,这并不是一个完整的答案。我只是指出如何交替编写c(0, V3[-.N])
  • @MFR 问题是我只能使用 V1、V2 和 Level 来生成 V3。我没有 V3 来生成新的 V3。我在文章开头提到 V3 是我想要的专栏。
【解决方案3】:

这是dplyr的一种方法

dt %>% 
  mutate(V4=lag(V3) + lag(V3)*V2 + V1,
         V4=ifelse(is.na(V4), 0, V4))

  Level V1 V2  V3  V4
1     0 10  2  10   0
2     1  0  3  40  40
3     1  0  2 120 120
4     1  0  2 360 360

【讨论】:

  • 如果您想删除 ifelse 部分,您可以使用 lag 函数中的 default 参数将 NA 设置为任意数字。
  • @JasonWang 我编辑了这篇文章。我只能使用 V1、V2 和 Level 来生成 V3。我没有 V3 来生成新的 V3。我在文章开头提到 V3 是我想要的专栏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-04
相关资源
最近更新 更多