Multiplication by levels

If you pre-calculate all the intervals and then only calculate the remainder in each interval for each value, I think you can do this safely in a vectorised fashion without requiring branching. This will then also be extendable to adding as many cutoffs and rates as required without having to adjust the body of the function.

propmult <- function(x, rate, coff) {
    spot <- findInterval(x, coff)
    base <- cumsum(rate * c(diff(coff), 0))[spot-1]
    base + ((x - coff[spot]) * rate[spot])
}

Comparing results with other answer:

propmult(my_data$Var_1, rate = c(0, 0.02, 0.03, 0.05), coff = c(0, 100, 1000, 2000))
##[1] 198.0  33.0   5.0  24.0  13.0  18.0  25.5  73.0
map_dbl(my_data$Var_1, foo)
##[1] 198.0  33.0   5.0  24.0  13.0  18.0  25.5  73.0

As a side benefit, it should also be quick to run on huge data if that is a concern:

datbig <- my_data[rep(1:8,1e6),]
nrow(datbig)
# 8 million rows - 8,000,000 - to test it out
system.time({ map_dbl(datbig$Var_1, foo) })
##   user  system elapsed 
##  5.049   0.092   5.140 

system.time({propmult(datbig$Var_1, rate = c(0, 0.02, 0.03, 0.05), coff = c(0, 100, 1000, 2000))})
##   user  system elapsed 
##  0.138   0.000   0.138
2 Likes