We will use the sample data rfm_data and segment customers using RFM analysis. As a first step, let us use rfm_table() to generate the RFM scores.
analysis_date <- lubridate::as_date('2006-12-31', tz = 'UTC')
rfm_result <- rfm_table(rfm_data, customer_id, order_date, revenue, analysis_date)
rfm_result | customer_id | date_most_recent | recency_days | transaction_count | amount | recency_score | frequency_score | monetary_score | rfm_score |
|---|---|---|---|---|---|---|---|---|
| Abbey O’Reilly DVM | 2006-06-09 | 205 | 6 | 472 | 3 | 4 | 3 | 343 |
| Add Senger | 2006-08-13 | 140 | 3 | 340 | 4 | 1 | 2 | 412 |
| Aden Lesch Sr. | 2006-06-20 | 194 | 4 | 405 | 3 | 2 | 3 | 323 |
| Admiral Senger | 2006-08-21 | 132 | 5 | 448 | 4 | 3 | 3 | 433 |
| Agness O’Keefe | 2006-10-02 | 90 | 9 | 843 | 5 | 5 | 5 | 555 |
| Aileen Barton | 2006-10-08 | 84 | 9 | 763 | 5 | 5 | 5 | 555 |
| Ailene Hermann | 2006-03-25 | 281 | 8 | 699 | 3 | 5 | 5 | 355 |
| Aiyanna Bruen PhD | 2006-04-29 | 246 | 4 | 157 | 3 | 2 | 1 | 321 |
| Ala Schmidt DDS | 2006-01-16 | 349 | 3 | 363 | 2 | 1 | 2 | 212 |
| Alannah Borer | 2005-04-21 | 619 | 4 | 196 | 1 | 2 | 1 | 121 |
| Segment | Description | R | F | M |
|---|---|---|---|---|
| Champions | Bought recently, buy often and spend the most | 4 - 5 | 4 - 5 | 4 - 5 |
| Loyal Customers | Spend good money. Responsive to promotions | 2 - 5 | 3 - 5 | 3 - 5 |
| Potential Loyalist | Recent customers, spent good amount, bought more than once | 3 - 5 | 1 - 3 | 1 - 3 |
| New Customers | Bought more recently, but not often | 4 - 5 | <= 1 | <= 1 |
| Promising | Recent shoppers, but haven’t spent much | 3 - 4 | <= 1 | <= 1 |
| Need Attention | Above average recency, frequency & monetary values | 2 - 3 | 2 - 3 | 2 - 3 |
| About To Sleep | Below average recency, frequency & monetary values | 2 - 3 | <= 2 | <= 2 |
| At Risk | Spent big money, purchased often but long time ago | <= 2 | 2 - 5 | 2 - 5 |
| Can’t Lose Them | Made big purchases and often, but long time ago | <= 1 | 4 - 5 | 4 - 5 |
| Hibernating | Low spenders, low frequency, purchased long time ago | 1 - 2 | 1 - 2 | 1 - 2 |
| Lost | Lowest recency, frequency & monetary scores | <= 2 | <= 2 | <= 2 |
rfm_segments %>%
count(segment) %>%
arrange(desc(n)) %>%
rename(Segment = segment, Count = n)
#> # A tibble: 8 x 2
#> Segment Count
#> <chr> <int>
#> 1 Loyal Customers 278
#> 2 Potential Loyalist 229
#> 3 Champions 158
#> 4 Hibernating 111
#> 5 At Risk 86
#> 6 About To Sleep 50
#> 7 Others 48
#> 8 Needs Attention 35rfm_segments %>%
group_by(segment) %>%
select(segment, recency_days) %>%
summarize(mean(recency_days)) %>%
rename(segment = segment, avg_recency = `mean(recency_days)`) %>%
ggplot(aes(segment, avg_recency)) +
geom_bar(stat = 'identity', fill = brewer.pal(n = 8, name = "Set1")) +
xlab('Segment') + ylab('Average Recency') +
ggtitle('Average Recency by Segment') +
coord_flip() +
theme(
plot.title = element_text(hjust = 0.5)
)