我有一个像这样的数据集,它显示了每个产品的价格:
df <- tribble(
~product_id, ~price,
'123', 35,
'445', 98,
'654', 194,
'135', 2000,
'156', 10,
)
我现在想根据以下条件对产品价格进行折扣,公式为:价格*(100 -贴现率)/100
如果价格为X,则在价格上给予Y%的折扣
- <10$: 3%
- 10 - 20美元:5%
- 20 - 30美元:7%
- 30 - 90美元:10%
- 90 - 190: 20%
- 190 - 2000: 30%
- 高于2000$:50%
因此,期望的输出将是这样的:
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,
)
我该怎么做?
用cut
创建一个'discount_rate'列,然后从折扣价格中减去'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))
与产出
# 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
您可以创建一个折扣表。
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
用fuzzyjoin
与df
结合,计算新的价格
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
case_when
解决方案:
library(tidyverse)
discount <- tribble(
~product_id, ~price,
'123', 35,
'445', 98,
'654', 194,
'135', 2000,
'156', 10,
)
discount %>%
mutate(discount_rate = case_when(
price < 10 ~ 0.03,
(price >= 10 & price < 20) ~ 5,
(price >= 20 & price < 30) ~ 7,
(price >= 30 & price < 90) ~ 10,
(price >= 90 & price < 190) ~ 20,
(price >= 190 & price < 2000) ~ 30,
price >= 2000 ~ 50),
final_price = (price * (100 - discount_rate)) / 100
)
#> # A tibble: 5 × 4
#> product_id price discount_rate final_price
#> <chr> <dbl> <dbl> <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
由reprex包(v2.0.1)在2018-10-29上创建