I have a dataset something like this, and it shows the price for each product:
df <- tribble(
~product_id, ~price,
'123', 35,
'445', 98,
'654', 194,
'135', 2000,
'156', 10,
)
I now would like to make a discount based on the following conditions on the product price with this formula: price * (100 - discount rate) / 100
If price X, make Y% discount on the price
- Less than 10$: 3%
- 10-20$: 5%
- 20-30$: 7%
- 30-90$: 10%
- 90-190$: 20%
- 190-2000$: 30%
- Higher than 2000$: 50%
Thus, the desired output will be like this:
df <- tribble(
~product_id, ~price, ~discount_rate, ~final_price,
'123', 35, 10, 31.5,
'445', 98, 20, 78.4,
'654', 194, 30, 135.8,
'135', 2000, 50, 1000,
'156', 10, 5, 9.5,
)
How can I do this?
CodePudding user response:
Just create a column of 'discount_rate' with cut
and then subtract the 'price' from the discounted price
library(dplyr)
df <- df %>%
mutate(discount_rate = as.integer(as.character(cut(price,
breaks = c(-Inf, 10, 20, 30, 90, 190, 2000, Inf),
labels = c(3, 5, 7, 10, 20, 30, 50), right = FALSE))),
final_price = price - (price * discount_rate/100))
-output
# A tibble: 5 × 4
product_id price discount_rate final_price
<chr> <dbl> <int> <dbl>
1 123 35 10 31.5
2 445 98 20 78.4
3 654 194 30 136.
4 135 2000 50 1000
5 156 10 5 9.5
CodePudding user response:
You may create a discount table.
library(fuzzyjoin)
library(dplyr)
discount_table <- data.frame(start = c(0, 10, 20, 30, 90, 190, 2000),
end = c(10, 20, 30, 90, 190, 2000, Inf),
discount = c(0.03, 0.05, 0.07, 0.1, 0.2, 0.3, 0.5))
discount_table
# start end discount
#1 0 10 0.03
#2 10 20 0.05
#3 20 30 0.07
#4 30 90 0.10
#5 90 190 0.20
#6 190 2000 0.30
#7 2000 Inf 0.50
Join it with df
using fuzzyjoin
and calculate the new price.
fuzzy_left_join(df, discount_table, by = c('price' = 'start', 'price' = 'end'),
match_fun = c(`>=`, `<`)) %>%
mutate(final_price = price - (price * discount),
discount = discount * 100)
# product_id price start end discount final_price
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 123 35 30 90 10 31.5
#2 445 98 90 190 20 78.4
#3 654 194 190 2000 30 136.
#4 135 2000 2000 Inf 50 1000
#5 156 10 10 20 5 9.5