在维度为 76x108 的数据帧 dt 中,我想通过从最后一行开始最小化列中的非零元素,将每列 13 到 108 中的值总和减少存储在数组 c 中的数量。
例如,如果 dt[76,13] > 0,则会发生以下情况:
dt[76,13] <- max((dt[76,13]-c),0)
如果在此操作之后 dt[76,13] == 0,c - dt[76,13] 的残差应该从第 13 列中的下一个非零元素中减去。这一直持续到列中所有行的总和13 减少了相当于 c 的量。
这需要对 dt[,13:108] 中的 96 列进行。
编辑:在下面添加了一个带有较小数据框的示例。
dt <- data.frame(Plant = sample(LETTERS,10,replace=T),
Type = rep("Base",10),
Ownership = rep("Pub",10))
caps = matrix(round(runif(10*5,0,500),0),nrow=10,ncol=5)
dt <- as.data.frame(cbind(dt,caps)) #this what the data frame looks like
for(i in 1:5){
colnames(dt)[i+3] <- (paste0("TB",i))
}
dt
Plant Type Ownership TB1 TB2 TB3 TB4 TB5
1 T Base Pub 454 32 162 271 478
2 S Base Pub 275 75 385 491 60
3 Y Base Pub 314 44 252 221 363
4 T Base Pub 170 122 490 332 123
5 J Base Pub 241 178 173 472 468
6 B Base Pub 243 316 152 411 434
7 T Base Pub 127 167 356 451 400
8 U Base Pub 20 102 54 182 57
9 O Base Pub 368 333 236 103 27
10 J Base Pub 343 189 0 494 184
c <- c(500,200,217,50,300)
#required output
Plant Type Ownership TB1 TB2 TB3 TB4 TB5
1 T Base Pub 454 32 162 271 478
2 S Base Pub 275 75 385 491 60
3 Y Base Pub 314 44 252 221 363
4 T Base Pub 170 122 490 332 123
5 J Base Pub 241 178 173 472 468
6 B Base Pub 243 316 152 411 434
7 T Base Pub 127 167 356 451 368
8 U Base Pub 20 102 54 182 0
9 O Base Pub 211 322 19 103 0
10 J Base Pub 0 0 0 444 0
#dt[10,4] is now max((343-500),0), while dt[9,4] is 368-(500-343).
#dt[10,5] is now max((189-200),0), while dt[9,4] is 333-(200-189).
#and so on.
到目前为止我尝试过的看起来像这样:
for(i in 4:8){
j <- nrow(dt) #start from the last row
if(dt[j,i]>0){
res1 <- c[i] - dt[j,i] #residual value of the difference
dt[j,i] <- max((dt[j,i] - c[i]),0)
while(res1>0){ #the process should continue until an amount equivalent to c[i] is not subtracted from dt[j,i]
j <- j-1
p <- dt[j,i]
dt[j,i] <- max((dt[j,i] - res1),0)
res1 <- res1 - p
}
}
else if(dt[j,i]==0){ #if the last element of the column is already 0, process should start w/ the first non-zero element
j <- j-1
res1 <- c[i] - dt[j,i]
dt[j,i] <- max((dt[j,i] - c[i]),0)
while(res1>0){
j <- j-1
p <- dt[j,i]
dt[j,i] <- max((dt[j,i] - res1),0)
res1 <- res1 - p
}
}
}
这将达到你的目的。(我重命名了您的向量c
,cc
以便它不会与函数交互c
)
df <- read.table(text = ' Plant Type Ownership TB1 TB2 TB3 TB4 TB5
1 T Base Pub 454 32 162 271 478
2 S Base Pub 275 75 385 491 60
3 Y Base Pub 314 44 252 221 363
4 T Base Pub 170 122 490 332 123
5 J Base Pub 241 178 173 472 468
6 B Base Pub 243 316 152 411 434
7 T Base Pub 127 167 356 451 400
8 U Base Pub 20 102 54 182 57
9 O Base Pub 368 333 236 103 27
10 J Base Pub 343 189 0 494 184', header =T)
cc <- c(500,200,217,50,300)
library(tidyverse)
df %>% arrange(rev(row_number())) %>%
mutate(across(starts_with('TB'), ~ . - c(first(pmin(cc[as.integer(str_remove(cur_column(), 'TB'))],
cumsum(pmin(., cc[as.integer(str_remove(cur_column(), 'TB'))])))),
diff(pmin(cc[as.integer(str_remove(cur_column(), 'TB'))],
cumsum(pmin(., cc[as.integer(str_remove(cur_column(), 'TB'))])))))
)) %>%
arrange(rev(row_number()))
#> Plant Type Ownership TB1 TB2 TB3 TB4 TB5
#> 1 T Base Pub 454 32 162 271 478
#> 2 S Base Pub 275 75 385 491 60
#> 3 Y Base Pub 314 44 252 221 363
#> 4 T Base Pub 170 122 490 332 123
#> 5 J Base Pub 241 178 173 472 468
#> 6 B Base Pub 243 316 152 411 434
#> 7 T Base Pub 127 167 356 451 368
#> 8 U Base Pub 20 102 54 182 0
#> 9 O Base Pub 211 322 19 103 0
#> 10 J Base Pub 0 0 0 444 0
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句