if (!"pacman" %in% installed.packages()[, "Package"]) {
install.packages("pacman", dependencies = TRUE)
library("pacman", character.only = TRUE)
}
pacman::p_load("here")
knitr::opts_knit$set(root.dir = here::here())
pacman::p_load("readr")
clv_data <- read_csv("./data/clv_data.csv")
## Rows: 500 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (2): purchase_frequency, customer_lifetime_value
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(clv_data)
## # A tibble: 6 × 2
## purchase_frequency customer_lifetime_value
## <dbl> <dbl>
## 1 3 110.
## 2 7 190.
## 3 6 160.
## 4 2 94.4
## 5 4 133.
## 6 8 223.
dim(clv_data)
## [1] 500 2
sapply(clv_data, class)
## purchase_frequency customer_lifetime_value
## "numeric" "numeric"
str(clv_data)
## spc_tbl_ [500 × 2] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ purchase_frequency : num [1:500] 3 7 6 2 4 8 0 4 8 3 ...
## $ customer_lifetime_value: num [1:500] 110.3 190.2 160 94.4 133.2 ...
## - attr(*, "spec")=
## .. cols(
## .. purchase_frequency = col_double(),
## .. customer_lifetime_value = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
summary(clv_data)
## purchase_frequency customer_lifetime_value
## Min. :-1.000 Min. : 26.13
## 1st Qu.: 4.000 1st Qu.:122.04
## Median : 5.000 Median :148.21
## Mean : 4.914 Mean :148.25
## 3rd Qu.: 6.000 3rd Qu.:175.88
## Max. :11.000 Max. :262.04
sapply(clv_data[,], var)
## purchase_frequency customer_lifetime_value
## 4.146898 1642.315996
sapply(clv_data[,], sd)
## purchase_frequency customer_lifetime_value
## 2.036393 40.525498
pacman::p_load("e1071")
sapply(clv_data[,], kurtosis, type = 2)
## purchase_frequency customer_lifetime_value
## -0.1220038 -0.1484811
sapply(clv_data[,], skewness, type = 2)
## purchase_frequency customer_lifetime_value
## -0.04021915 -0.01608242
cov(clv_data, method = "spearman")
## purchase_frequency customer_lifetime_value
## purchase_frequency 20409.91 20235.73
## customer_lifetime_value 20235.73 20874.99
cor.test(clv_data$customer_lifetime_value, clv_data$purchase_frequency, method = "spearman")
##
## Spearman's rank correlation rho
##
## data: clv_data$customer_lifetime_value and clv_data$purchase_frequency
## S = 409190, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.9803588
cor(clv_data, method = "spearman")
## purchase_frequency customer_lifetime_value
## purchase_frequency 1.0000000 0.9803588
## customer_lifetime_value 0.9803588 1.0000000
# `par(mfrow = c(1, 2))` This is used to divide the area used to plot the visualization into a 1 row by 2 columns grid
# `for (i in 1:2)` This is used to identify the variable (column) that is being processed
# `clv_data[[i]]` This is used to extract the i-th column as a vector
# `hist()` This is the function used to plot the histogram
par(mfrow = c(1, 2))
for (i in 1:2) {
if (is.numeric(clv_data[[i]])) {
hist(clv_data[[i]],
main = names(clv_data)[i],
xlab = names(clv_data)[i])
} else {
message(paste("Column", names(clv_data)[i], "is not numeric and will be skipped."))
}
}
# `boxplot()` This is the function used to plot the box and whisker plot visualization
par(mfrow = c(1, 2))
for (i in 1:2) {
if (is.numeric(clv_data[[i]])) {
boxplot(clv_data[[i]], main = names(clv_data)[i])
} else {
message(paste("Column", names(clv_data)[i], "is not numeric and will be skipped."))
}
}
pacman::p_load("Amelia")
missmap(clv_data, col = c("red", "grey"), legend = TRUE)
pacman::p_load("ggcorrplot")
ggcorrplot(cor(clv_data[,]))
pacman::p_load("corrplot")
pairs(clv_data$customer_lifetime_value ~ ., data = clv_data, col = clv_data$customer_lifetime_value)
pacman::p_load("ggplot2")
ggplot(clv_data,
aes(x = purchase_frequency, y = customer_lifetime_value)) +
geom_point() +
geom_smooth(method = lm) +
labs(
title = "Relationship between Customer Lifetime Value and Purchase Frequency",
x = "Purchase Frequency",
y = "Customer Lifetime Value"
)
slr_test <-lm(customer_lifetime_value~purchase_frequency, data = clv_data)
summary(slr_test)
##
## Call:
## lm(formula = customer_lifetime_value ~ purchase_frequency, data = clv_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -19.1176 -5.6169 -0.0491 5.6618 20.4837
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 52.2538 0.9042 57.79 <2e-16 ***
## purchase_frequency 19.5356 0.1700 114.91 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.734 on 498 degrees of freedom
## Multiple R-squared: 0.9637, Adjusted R-squared: 0.9636
## F-statistic: 1.32e+04 on 1 and 498 DF, p-value: < 2.2e-16
confint(slr_test, level = 0.95)
## 2.5 % 97.5 %
## (Intercept) 50.47731 54.03036
## purchase_frequency 19.20159 19.86965
plot(slr_test, which = 1)
pacman::p_load("lmtest")
dwtest(slr_test)
##
## Durbin-Watson test
##
## data: slr_test
## DW = 1.9104, p-value = 0.1573
## alternative hypothesis: true autocorrelation is greater than 0
plot(slr_test, which = 2)
plot(slr_test, which = 3)
pacman::p_load("gvlma")
gvlma_results <- gvlma(slr_test)
summary(gvlma_results)
##
## Call:
## lm(formula = customer_lifetime_value ~ purchase_frequency, data = clv_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -19.1176 -5.6169 -0.0491 5.6618 20.4837
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 52.2538 0.9042 57.79 <2e-16 ***
## purchase_frequency 19.5356 0.1700 114.91 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.734 on 498 degrees of freedom
## Multiple R-squared: 0.9637, Adjusted R-squared: 0.9636
## F-statistic: 1.32e+04 on 1 and 498 DF, p-value: < 2.2e-16
##
##
## ASSESSMENT OF THE LINEAR MODEL ASSUMPTIONS
## USING THE GLOBAL TEST ON 4 DEGREES-OF-FREEDOM:
## Level of Significance = 0.05
##
## Call:
## gvlma(x = slr_test)
##
## Value p-value Decision
## Global Stat 5.08943 0.27824 Assumptions acceptable.
## Skewness 0.03973 0.84201 Assumptions acceptable.
## Kurtosis 3.61252 0.05735 Assumptions acceptable.
## Link Function 0.01459 0.90385 Assumptions acceptable.
## Heteroscedasticity 1.42258 0.23298 Assumptions acceptable.
We can interpret the results of the statistical test with more confidence if the tests of assumptions are successful.
A simple linear regression was conducted to examine the relationship between customer lifetime value (CLV) and purchase frequency. The results indicated that purchase frequency significantly predicted CLV, β = 19.54, 95% CI[19.20, 19.87], SE = 0.17, t(498) = 114.91, p < .001. The model explained 96.37% of the variance in CLV (R2 = .96, F(1, 498) = 13,200, p < .001). For every unit increase in purchase frequency, CLV increased by approximately 19.54 units. The intercept was 52.25, 95 % CI [50.48, 54.03], and the residual standard error was 7.73, indicating strong predictive accuracy.
The strength of the relationship highlights the critical importance of customer retention. Initiatives that effectively encourage repeat purchases appear to be a primary driver of customer lifetime value based on this analysis. This understanding can guide the allocation of resources towards strategies that foster customer loyalty and encourage repeat business.
The model employed is a simple linear regression, which only considers the linear relationship between purchase frequency and CLV. Other potentially influential factors that are not included in this model could also play a significant role in determining CLV, e.g., the average monetary value of each purchase.