>我有一个看起来像的数据集
C_ID I_ID Loan R1 Prot_id Collateral R2 maxRank
1 A c 341 1 p1 506 1 3
2 A c 341 1 p2 366 2 3
3 A c 341 1 p3 263 3 3
4 A a 689 2 p1 506 1 3
5 A a 689 2 p2 366 2 3
6 A a 689 2 p3 263 3 3
7 A d 720 3 p1 506 1 3
8 A d 720 3 p2 366 2 3
9 A d 720 3 p3 263 3 3
10 A b 334 4 p1 506 1 3
11 A b 334 4 p2 366 2 3
12 A b 334 4 p3 263 3 3
13 A e 752 5 p1 506 1 3
14 A e 752 5 p2 366 2 3
15 A e 752 5 p3 263 3 3
16 B h 193 1 p5 529 1 2
17 B h 193 1 p4 414 2 2
18 B g 494 2 p5 529 1 2
19 B g 494 2 p4 414 2 2
20 B f 227 3 p5 529 1 2
21 B f 227 3 p4 414 2 2
22 B j 785 4 p5 529 1 2
23 B j 785 4 p4 414 2 2
24 B i 371 5 p5 529 1 2
25 B i 371 5 p4 414 2 2
26 B k 395 6 p5 529 1 2
27 B k 395 6 p4 414 2 2
其中R1
是每个contract_id组的贷款排名,R2
是cotnract_id下每个抵押品的排名。需要的是
C_ID I_ID Loan R1 Prot_id Prot_value R2 maxRank PreAllocation Allocation PostAllocation Residual
1 A c 341 1 p1 506 1 3 341 341 0 165
2 A c 341 1 p2 366 2 3 0 0 0 366
3 A c 341 1 p3 263 3 3 0 0 0 263
4 A a 689 2 p1 506 1 3 689 165 524 0
5 A a 689 2 p2 366 2 3 524 366 158 0
6 A a 689 2 p3 263 3 3 158 158 0 105
7 A d 720 3 p1 506 1 3 720 0 720 0
8 A d 720 3 p2 366 2 3 720 0 720 0
9 A d 720 3 p3 263 3 3 720 105 615 0
10 A b 334 4 p1 506 1 3 334 0 334 0
11 A b 334 4 p2 366 2 3 334 0 334 0
12 A b 334 4 p3 263 3 3 334 0 334 0
13 A e 752 5 p1 506 1 3 752 0 752 0
14 A e 752 5 p2 366 2 3 752 0 752 0
15 A e 752 5 p3 263 3 3 752 0 752 0
16 B h 193 1 p5 529 1 2 193 193 0 336
17 B h 193 1 p4 414 2 2 0 0 0 414
18 B g 494 2 p5 529 1 2 494 336 158 0
19 B g 494 2 p4 414 2 2 158 158 0 256
20 B f 227 3 p5 529 1 2 227 0 227 0
21 B f 227 3 p4 414 2 2 227 227 0 29
22 B j 785 4 p5 529 1 2 785 0 785 0
23 B j 785 4 p4 414 2 2 785 29 756 0
24 B i 371 5 p5 529 1 2 371 0 371 0
25 B i 371 5 p4 414 2 2 371 0 371 0
26 B k 395 6 p5 529 1 2 395 0 395 0
27 B k 395 6 p4 414 2 2 395 0 395 0
只有Allocation
列很重要,另一列只是为了到达Allocation
列。我能够使用如下所示的循环来达到这一点
df3 <- as.data.frame(df3)
df3$PreAllocation <- 0
df3$Allocation <- 0
df3$PostAllocation <- 0
df3$Residual <- 0
for (i in 1:nrow(df3)){
df3$PreAllocation[i] <- ifelse(df3$R2[i]==1,df3$Loan[i],df3$PostAllocation[i-1])
df3$Allocation[i]<- ifelse(df3$R1[i] >1, min(df3$Residual[i -
df3$maxRank[i]],df3$PreAllocation[i]),min(df3$PreAllocation[i],df3$Prot_value[i]))
df3$PostAllocation[i]<- df3$PreAllocation[i] - df3$Allocation[i]
df3$Residual[i] <- ifelse(df3$R1[i]==1, (df3$Prot_value[i] - df3$Allocation[i]), (df3$Residual[i-
df3$maxRank[i]] - df3$Allocation[i]))
}
但是,当数据集很大时,会出现性能问题。我一直在尝试使用应用函数达到相同的目的;行+转换等,但无法到达。为 1. 列是相互依赖的。 2.需要在计算后面的行等时使用生成的列的动态(基于maxRank(滞后。
任何建议。谢谢。
看起来使用了循环,因此您可以查看上一行中的值。 下面是一个使用 dplyr 的解决方案,它有一个函数 lag()
(和 lead()
(,可让您查看以前(或连续(的行。它还使用 pmin()
(还有一个pmax()
(,它获取一组向量中相应元素之间的最小值/最大值。
# `mutate()` takes data and one or more LHS=RHS statements about the data.
# Each column in the LHS is created (or overwritten) with the logic on the
# RHS. Conveniently, we don't have to prepend each with `df$3`.
# Uses dplyr's if_else()` instead of base R.
# `lag(x, n=1)` looks at previous row's value for x.
# Run `pmin(1:5, 5:1)` for a simple example
# of how it works.
df3 <- mutate(df3,
PreAllocation = if_else(R2 == 1, Loan, lag(PostAllocation, n = 1)),
Allocation = if_else(R3 > 1, pmin(lag(Residual, n = maxRank), PreAllocation),
pmin(PreAllocation, Prot_value)),
PostAllocation = PreAllocation - Allocation,
Residual = if_else(R1 == 1, Prot_value - Allocation, lag(Residual, n = maxRank - Allocation))
)
我鼓励您查看dplyr CRAN页面和"dplyr简介"小插图以获取更多信息。
如果你想要一个更接近基 R 的语法来用于子集和赋值,你也可以考虑 data.table 包。
这些是非常流行的数据操作和聚合框架。