r - R数据框使用上一行中当前行中的值
问题描述
我在 R 中有一个数据框,定义如下:
df <- data.frame('ID'=c(1,1,1,1),
'Month' =c('M1','M2','M3','M4'),
"Initial.Balance" =c(100,100,100,0),
"Value" = c(0.1,0.2,0.2,0.2),
"Threshold"=c(0.05,0.18,0.25,0.25),
"Intermediate.Balance"=c(0,0,100,0),
"Final.Balance"=c(100,100,0,0))
此任务使用上一行的 Final.Balance 中的 Initial.Balance(在当前行中)。
- 当 Value >= Threshold 时,Intermediate.Balance=0 且 Final.Balance = Initial.Balance-Intermediate.Balance
- 当 Value < Threshold 时,Intermediate.Balance = Initial.Balance 和 Final.Balance = Initial.Balance-Intermediate.Balance
我曾尝试使用 for 循环来完成此任务,但在大型数据集上需要大量时间(对于许多 ID)
这是我的解决方案:
for (i in 1:nrow(df)){
df$Intermediate.Balance[i] <- ifelse(df$Value[i]>df$Threshold[i],0,df$Initial.balance[i])
df$Final.Balance[i] <- df$Initial.balance[i]-df$Intermediate.Balance[i]
if(i+1<=nrow(df)){
df$Initial.balance[i+1] <- df$Final.Balance[i] }
}
我们可以使用数据表寻找类似的解决方案吗?由于数据表操作比数据帧上的 for 循环更快,我相信这将帮助我节省计算时间。
谢谢,
解决方案
我认为在这种特殊情况下,一旦有一行 Value 小于 Threshold 并且后续余额都变为 0,最终余额就会变为 0。所以你可以使用这个:
ib <- 100
df[, InitBal := ib * 0^shift(cumsum(Value<=Threshold), fill=0L)]
df[, ItmdBal := replace(rep(0, .N), which(Value<=Threshold)[1L], ib)]
df[, FinlBal := InitBal - ItmdBal]
或其中之一[]
:
df[, c("InitBal", "ItmdBal", "FinlBal") := {
v <- Value<=Threshold
InitBal <- ib * 0^shift(cumsum(v), fill=0L)
ItmdBal <- replace(rep(0, .N), which(v)[1L], ib)
.(InitBal, ItmdBal, InitBal - ItmdBal)
}]
或者当中间余额不等于初始余额时使用 Rcpp 的更一般的方法:
library(Rcpp)
cppFunction('List calc(NumericVector Value, NumericVector Threshold, double init) {
int n = Value.size();
NumericVector InitialBalance(n), IntermediateBalance(n), FinalBalance(n);
InitialBalance[0] = init;
for (int i=0; i<n; i++) {
if (Value[i] <= Threshold[i]) {
IntermediateBalance[i] = InitialBalance[i];
}
FinalBalance[i] = InitialBalance[i] - IntermediateBalance[i];
if (i < n-1) {
InitialBalance[i+1] = FinalBalance[i];
}
}
return List::create(Named("InitialBalance") = InitialBalance,
Named("IntermediateBalance") = IntermediateBalance,
Named("FinalBalance") = FinalBalance);
}')
setDT(df)[, calc(Value, Threshold, Initial.Balance[1L])]
推荐阅读
- c# - WPF - 无法访问在运行时创建的对象的模板元素
- testing - 使用 NUnit-Console runner 以特定顺序运行 TestFixtures
- android - 以编程方式在 Android 上下载文件的最佳方法?
- netsuite - Suitelet 的 NetSuite 客户端脚本
- typescript - 如何将事件分配给打字稿中的变量
- gsuite-addons - 测试未发布的插件失败
- mongodb - 无法从同一网络中的另一台 PC 访问 mongodb 图表
- android - 如何提取 ISO 文件,然后将其重新打包成可用的 ISO 文件?
- c++ - 如何检查变量是否是 C++ 中的映射?
- javascript - 如何使用javascript获取url的最后一个参数?