累计sum/subtraction 取决于flag和帐号R
Cumulative sum/subtraction dependent on flag and account number R
我有一个数据集看起来
TransAmount C/D ACCOUNT BALANCE NEW_BAL
110 C 500000 130.34 -6128.74
200 D 500000 130.34 -6328.74
210 C 500000 130.34
83.07 C 500009 -1079 -6411.81
113.49 C 500026 112.63 -6525.3
39.74 C 500041 179.2 -6565.04
39.74 C 500041 179.2 -6604.78
80 D 500051 -959.93 -6684.78
New_Bal 此处计算错误。
我希望 NEW_BAL 在帐户级别进行计算。
因此,如果它是该帐户的第一个实例并且 C/D 是 C,那么 New_Bal = BALANCE-TRANSAMOUNT
如果C/D是D那么New_Bal = BALANCE+TRANSAMOUNT
对于该帐户的所有其他实例,我想使用以前的 New_Bal 而不是 BALANCE。对于每个帐户的所有其他实例,如果 C/D = C 则 New_Bal = New_Bal(来自以前的版本)-TRANSAMOUNT
如果 C/D 是 D 那么 New_Bal = New_Bal(来自以前的版本)+TRANSAMOUNT
我想要的输出是:
TransAmount C/D ACCOUNT BALANCE NEW_BAL
110 C 500000 130.34 20.34
200 D 500000 130.34 220.34
210 C 500000 130.34 10.34
83.07 C 500009 -1079 -1162.07
113.49 C 500026 112.63 -0.86
39.74 C 500041 179.2 139.46
39.74 C 500041 179.2 99.72
80 D 500051 -959.93 -879.93
请注意,2 不是交易的最大数量,最多可以有 40 个,所以我希望 NEW_BAL 是滚动余额。
我认为所需输出的第 3 行有错字。 NEW_BAL 应该是 220.34 - 210 = 10.34。
TransAmount符号翻转后C/D可以用base::Reduce
做累加:
df$TransAmount <- ifelse(df$`X.C.D.`=="C", -df$TransAmount, df$TransAmount)
do.call(rbind, by(df, df$ACCOUNT, function(x) {
x$NEW_BAL <- Reduce(`+`, x$TransAmount[-1], x$BALANCE[1]+x$TransAmount[1], accumulate=TRUE)
x
}))
或使用data.table
:
library(data.table)
setDT(DT)[X.C.D.=='C', TransAmount := -TransAmount][,
NEW_BAL := Reduce(`+`, TransAmount[-1L], BALANCE[1L]+TransAmount[1L], accumulate=TRUE), by=ACCOUNT]
DT
输出:
TransAmount X.C.D. ACCOUNT BALANCE NEW_BAL
500000.1 -110.00 C 500000 130.34 20.34
500000.2 200.00 D 500000 130.34 220.34
500000.3 -210.00 C 500000 130.34 10.34
500009 -83.07 C 500009 -1079.00 -1162.07
500026 -113.49 C 500026 112.63 -0.86
500041.6 -39.74 C 500041 179.20 139.46
500041.7 -39.74 C 500041 179.20 99.72
500051 80.00 D 500051 -959.93 -879.93
数据:
df <- read.csv(text="TransAmount,'C/D',ACCOUNT,BALANCE
110,C,500000,130.34
200,D,500000,130.34
210,C,500000,130.34
83.07,C,500009,-1079
113.49,C,500026,112.63
39.74,C,500041,179.2
39.74,C,500041,179.2
80,D,500051,-959.93", header=TRUE)
DT <- df
我有一个数据集看起来
TransAmount C/D ACCOUNT BALANCE NEW_BAL
110 C 500000 130.34 -6128.74
200 D 500000 130.34 -6328.74
210 C 500000 130.34
83.07 C 500009 -1079 -6411.81
113.49 C 500026 112.63 -6525.3
39.74 C 500041 179.2 -6565.04
39.74 C 500041 179.2 -6604.78
80 D 500051 -959.93 -6684.78
New_Bal 此处计算错误。
我希望 NEW_BAL 在帐户级别进行计算。
因此,如果它是该帐户的第一个实例并且 C/D 是 C,那么 New_Bal = BALANCE-TRANSAMOUNT
如果C/D是D那么New_Bal = BALANCE+TRANSAMOUNT
对于该帐户的所有其他实例,我想使用以前的 New_Bal 而不是 BALANCE。对于每个帐户的所有其他实例,如果 C/D = C 则 New_Bal = New_Bal(来自以前的版本)-TRANSAMOUNT
如果 C/D 是 D 那么 New_Bal = New_Bal(来自以前的版本)+TRANSAMOUNT
我想要的输出是:
TransAmount C/D ACCOUNT BALANCE NEW_BAL
110 C 500000 130.34 20.34
200 D 500000 130.34 220.34
210 C 500000 130.34 10.34
83.07 C 500009 -1079 -1162.07
113.49 C 500026 112.63 -0.86
39.74 C 500041 179.2 139.46
39.74 C 500041 179.2 99.72
80 D 500051 -959.93 -879.93
请注意,2 不是交易的最大数量,最多可以有 40 个,所以我希望 NEW_BAL 是滚动余额。
我认为所需输出的第 3 行有错字。 NEW_BAL 应该是 220.34 - 210 = 10.34。
TransAmount符号翻转后C/D可以用base::Reduce
做累加:
df$TransAmount <- ifelse(df$`X.C.D.`=="C", -df$TransAmount, df$TransAmount)
do.call(rbind, by(df, df$ACCOUNT, function(x) {
x$NEW_BAL <- Reduce(`+`, x$TransAmount[-1], x$BALANCE[1]+x$TransAmount[1], accumulate=TRUE)
x
}))
或使用data.table
:
library(data.table)
setDT(DT)[X.C.D.=='C', TransAmount := -TransAmount][,
NEW_BAL := Reduce(`+`, TransAmount[-1L], BALANCE[1L]+TransAmount[1L], accumulate=TRUE), by=ACCOUNT]
DT
输出:
TransAmount X.C.D. ACCOUNT BALANCE NEW_BAL
500000.1 -110.00 C 500000 130.34 20.34
500000.2 200.00 D 500000 130.34 220.34
500000.3 -210.00 C 500000 130.34 10.34
500009 -83.07 C 500009 -1079.00 -1162.07
500026 -113.49 C 500026 112.63 -0.86
500041.6 -39.74 C 500041 179.20 139.46
500041.7 -39.74 C 500041 179.20 99.72
500051 80.00 D 500051 -959.93 -879.93
数据:
df <- read.csv(text="TransAmount,'C/D',ACCOUNT,BALANCE
110,C,500000,130.34
200,D,500000,130.34
210,C,500000,130.34
83.07,C,500009,-1079
113.49,C,500026,112.63
39.74,C,500041,179.2
39.74,C,500041,179.2
80,D,500051,-959.93", header=TRUE)
DT <- df