Here is a version with just the three columns:
Count <- c(1:10)
Give <- c(0,0,5,0,0,5,0,5,0,5)
X <- c(rep(0,10))
Y <- c(rep(0,10))
Z <- c(rep(0,10))
X_Target <- 5
Y_Target <- 10
Z_Target <- 5
df <- data.frame(Count,
Give,
Given = cumsum(Give))
df$X <- pmin(df$Given, X_Target)
df$Y <- pmin(df$Given - df$X, Y_Target)
df$Z <- pmin(df$Given - df$X - df$Y, Z_Target)
df
#> Count Give Given X Y Z
#> 1 1 0 0 0 0 0
#> 2 2 0 0 0 0 0
#> 3 3 5 5 5 0 0
#> 4 4 0 5 5 0 0
#> 5 5 0 5 5 0 0
#> 6 6 5 10 5 5 0
#> 7 7 0 10 5 5 0
#> 8 8 5 15 5 10 0
#> 9 9 0 15 5 10 0
#> 10 10 5 20 5 10 5
Created on 2020-12-08 by the reprex package (v0.3.0)
I'm not sure how to generalize to arbitrary columns. The easiest would be with a for loop, something like that (with probably quite a bit of thinking required for correct initialization etc):
Targets <- list(X=5,Y=10,Z=5)
for(i in seq_along(Targets)){
df[[names(Targets[i])]] <- pmin(df$Given - df$sum_of_previous_targets, Targets[[i]])
df$sum_of_previous_targets <- df$sum_of_previous_targets + df[[names(Targets[i])]]
}
I don't see how to easily use *apply() or map_*() since the result of each column depends on the previous columns, that means you would need to expand some big combination vector to get the equivalent of sum_of_previous_targets .