R - замена цикла на манипуляции по строкам, может потребоваться отставание генерируемого столбца

у меня две таблицы

C_ID Loan_ID Loan
    A   L1      341
    A   L2      689
    A   L3      720
    A   L4      334
    B   L5      193
    B   L6      494
    B   L7      227


C_ID Prot_id Prot_value
    A   p1  506
    A   p2  366
    A   p3  263
    B   p4  529
    B   p5  414

В таблице 1 приведены сведения о кредите, а в таблице 2 — сведения о залоге, и кредиты, и залог указаны на уровне контракта (C_ID); Залог распределяется по кредиту по правилу, согласно которому самый высокий залог назначается первым и первым (L1 перед L2 в том же контракте) кредит получает распределение первым.

Итак, наконец, я должен получить

C_ID Loan_ID Loan Coll_ID Collateral Allocation
    A   L1    341        p1  506          341
    A   L1    341        p2  366          0
    A   L1    341        p3  263          0
    A   L2    689        p1  506          165
    A   L2    689        p2  366          366
    A   L2    689        p3  263          158
    A   L3    720        p1  506          0
    A   L3    720        p2  366          0
    A   L3    720        p3  263          105
    A   L4    334        p1  506          0
    A   L4    334        p2  366          0
    A   L4    334        p3  263          0
    B   L5    193        p4  529          193
    B   L5    193        p5  414          0
    B   L6    494        p4  529          336
    B   L6    494        p5  414          158
    B   L7    227        p4  529          0
    B   L7    227        p5  414          227

Я смог получить их, используя слияние и цикл; но цикл (с поддерживающими столбцами) требует много времени для большого набора данных.

  df3<-merge(x=df1,y=df2,by="C_ID")
  df3 <- mutate(df3,PreAllocation = 0,Allocation = 0, PostAllocation = 0,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]))    
 }

Кто-нибудь, пожалуйста, помогите мне с альтернативным способом перехода к столбцу «Распределение», который может сэкономить время.

Спасибо.


person Shambhu Shankar    schedule 27.11.2019    source источник
comment
ifelse векторизован, поэтому вам не нужно зацикливаться на каждой строке. также в вашем коде, что такое «R1», «R2» и т. д. (не показано в данных)   -  person akrun    schedule 27.11.2019
comment
Привет @akrun, если вы предлагаете приведенный ниже код в качестве решения, похоже, он не работает 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 - Распределение))   -  person Shambhu Shankar    schedule 27.11.2019
comment
Поскольку R1 или R2 не показаны в данных, это неясно.   -  person akrun    schedule 27.11.2019
comment
@akrun, R1 — рейтинг кредита, R2 — рейтинг залога, а maxR — максимальный R2 по каждому контракту.   -  person Shambhu Shankar    schedule 27.11.2019


Ответы (1)


@akrun после слияния и ранжирования может выглядеть так

C_ID    Loan_ID Loan    R1  Coll_ID Collateral  R2  maxRank
A       c       341     1       p1  506         1   3
A       c       341     1       p2  366         2   3
A       c       341     1       p3  263         3   3
A       a       689     2       p1  506         1   3
A       a       689     2       p2  366         2   3
A       a       689     2       p3  263         3   3
A       d       720     3       p1  506         1   3
A       d       720     3       p2  366         2   3
A       d       720     3       p3  263         3   3
A       b       334     4       p1  506         1   3
A       b       334     4       p2  366         2   3
A       b       334     4       p3  263         3   3
A       e       752     5       p1  506         1   3
A       e       752     5       p2  366         2   3
A       e       752     5       p3  263         3   3
B       h       193     1       p5  529         1   2
B       h       193     1       p4  414         2   2
B       g       494     2       p5  529         1   2
B       g       494     2       p4  414         2   2
B       f       227     3       p5  529         1   2
B       f       227     3       p4  414         2   2
B       j       785     4       p5  529         1   2
B       j       785     4       p4  414         2   2
B       i       371     5       p5  529         1   2
B       i       371     5       p4  414         2   2
B       k       395     6       p5  529         1   2
B       k       395     6       p4  414         2   2
person Shambhu Shankar    schedule 27.11.2019