Giảng viên hướng dẫn: ThS. Trần Mạnh Tường
Sinh viên
thực hiện: Lê Ngọc Tường Vy và Trần Hoàng Minh Nhật
Bộ dữ liệu “Retail Transaction Export Dataset” được lấy từ nền tảng Gigasheet, một nguồn dữ liệu công khai được thiết kế nhằm hỗ trợ học tập và thực hành phân tích dữ liệu. Bộ dữ liệu mô tả các giao dịch bán lẻ phát sinh trong hệ thống quản lý của một doanh nghiệp thương mại trong giai đoạn tháng 4/2023 - 4/2024. Mỗi dòng dữ liệu tương ứng với một giao dịch cụ thể, bao gồm các thông tin như mã khách hàng, mã sản phẩm, giá bán, ngày giao dịch, phương thức thanh toán, địa điểm cửa hàng, loại sản phẩm, mức giảm giá áp dụng và tổng số tiền thanh toán. Dữ liệu được xây dựng dưới dạng dữ liệu chi tiết theo từng giao dịch, phản ánh hoạt động mua bán cụ thể trong lĩnh vực bán lẻ. Mục tiêu của bộ dữ liệu là cập nhật xu hướng bán hàng, đồng thời đánh giá hành vi tiêu dùng của khách hàng thông qua các yếu tố như giá bán, chiết khấu, phương thức thanh toán và địa điểm cửa hàng.
Ta tiến hành đọc tệp CSV và gán dữ liệu vào một đối tượng có tên là tieuluan để phục vụ cho quá trình phân tích.
library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(DT)
library(readxl)
#Đọc dữ liệu
tieuluan <- read.csv("~/Downloads/TLHK3:2025/Ngôn ngữ lập trình R/Retail Transaction Export Dataset.csv")
#Xem 6 dòng đầu tiên
head(tieuluan)
#Xem 6 dòng cuối cùng
tail(tieuluan)
Ta sử dụng sử dụng một số lệnh bên dưới để xem thông tin chung của tieuluan.
# 4. Kiểm tra kích thước bộ dữ liệu
dim(tieuluan)
## [1] 100000 10
Nhận xét: Sử dụng lệnh dim() kết quả trả về cho thấy bộ dữ liệu tieuluan có 100.000 hàng (quan sát) và 10 cột (biến), phản ánh quy mô và số lượng biến của tập dữ liệu.
#Xem tên các biến
names(tieuluan)
## [1] "CustomerID" "ProductID" "Quantity"
## [4] "Price" "TransactionDate" "PaymentMethod"
## [7] "StoreLocation" "ProductCategory" "DiscountApplied..."
## [10] "TotalAmount"
Nhận xét: Sử dụng lệnh names() kết quả trả về tên các biến trong bộ dữ liệu. Trong bộ dữ liệu tieuluan, các biến bao gồm: “CustomerID”, “ProductID”, “Quantity”, “Price”, “TransactionDate”, “PaymentMethod”, “StoreLocation”, “ProductCategory”, “DiscountApplied”, “TotalAmount”.
Dữ liệu bao gồm các biến sau, được tổng hợp chi tiết trong bảng dưới đây nhằm phục vụ cho quá trình phân tích:
# Tạo bảng thông tin biến
variable_info <- data.frame(
Variable = c("CustomerID", "ProductID", "Quantity", "Price", "TransactionDate",
"PaymentMethod", "StoreLocation", "ProductCategory", "DiscountApplied", "TotalAmount"),
Type = c("Integer", "Character", "Integer", "Numeric", "Date",
"Factor", "Character", "Factor", "Numeric", "Numeric"),
Description = c("Mã định danh duy nhất của khách hàng",
"Mã định danh sản phẩm được giao dịch",
"Số lượng sản phẩm mua trong giao dịch",
"Giá bán đơn vị của sản phẩm",
"Ngày thực hiện giao dịch",
"Phương thức thanh toán (Cash, Credit Card, Debit Card, PayPal)",
"Địa chỉ cửa hàng hoặc địa điểm thực hiện giao dịch",
"Danh mục sản phẩm (Books, Electronics, Clothing, …)",
"Giá trị chiết khấu được áp dụng cho giao dịch",
"Tổng số tiền của giao dịch sau khi tính chiết khấu"),
stringsAsFactors = FALSE
)
# Xem bảng
variable_info
#Xem cấu trúc tổng quát của dữ liệu
str(tieuluan)
## 'data.frame': 100000 obs. of 10 variables:
## $ CustomerID : int 109318 993229 579675 799826 121413 463050 888163 843385 839609 184135 ...
## $ ProductID : chr "C" "C" "A" "D" ...
## $ Quantity : int 7 4 8 5 7 3 7 8 5 4 ...
## $ Price : num 80.1 75.2 31.5 98.9 93.2 ...
## $ TransactionDate : chr "2023-12-26 12:32:00.000" "2023-08-05 00:00:00.000" "2024-03-11 18:51:00.000" "2023-10-27 22:00:00.000" ...
## $ PaymentMethod : chr "Cash" "Cash" "Cash" "PayPal" ...
## $ StoreLocation : chr "176 Andrew Cliffs\nBaileyfort, HI 93354" "11635 William Well Suite 809\nEast Kara, MT 19483" "910 Mendez Ville Suite 909\nPort Lauraland, MO 99563" "87522 Sharon Corners Suite 500\nLake Tammy, MO 76234" ...
## $ ProductCategory : chr "Books" "Home Decor" "Books" "Books" ...
## $ DiscountApplied...: num 18.68 14.12 15.94 6.69 4.03 ...
## $ TotalAmount : num 456 258 212 461 626 ...
Nhận xét: Sử dụng lệnh str() kết quả trả về cấu trúc tổng quát của bộ dữ liệu, bao gồm số quan sát, số biến, tên biến và kiểu dữ liệu của từng biến. Trong bộ dữ liệu tieuluan có 100.000 quan sát và 10 biến với các kiểu dữ liệu như int (số nguyên), num (số thực) và chr (chuỗi ký tự).
#Xem kiểu dữ liệu theo từng cột
sapply(tieuluan, class)
## CustomerID ProductID Quantity Price
## "integer" "character" "integer" "numeric"
## TransactionDate PaymentMethod StoreLocation ProductCategory
## "character" "character" "character" "character"
## DiscountApplied... TotalAmount
## "numeric" "numeric"
Nhận xét: Sử dụng lệnh sapply() với class kết quả trả về kiểu dữ liệu của từng biến trong bộ dữ liệu. Trong tieuluan, các biến có kiểu integer (CustomerID, Quantity), numeric (Price, DiscountApplied…, TotalAmount) và character (ProductID, TransactionDate, PaymentMethod, StoreLocation, ProductCategory).
#Xem thống kê mô tả cơ bản
summary(tieuluan)
## CustomerID ProductID Quantity Price
## Min. : 14 Length:100000 Min. :1.000 Min. : 10.00
## 1st Qu.:250694 Class :character 1st Qu.:3.000 1st Qu.: 32.55
## Median :499679 Mode :character Median :5.000 Median : 55.12
## Mean :500464 Mean :5.009 Mean : 55.07
## 3rd Qu.:751105 3rd Qu.:7.000 3rd Qu.: 77.46
## Max. :999997 Max. :9.000 Max. :100.00
## TransactionDate PaymentMethod StoreLocation ProductCategory
## Length:100000 Length:100000 Length:100000 Length:100000
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## DiscountApplied... TotalAmount
## Min. : 0.000046 Min. : 8.275
## 1st Qu.: 5.001013 1st Qu.: 95.163
## Median :10.030353 Median :200.368
## Mean :10.020155 Mean :248.335
## 3rd Qu.:15.018367 3rd Qu.:362.010
## Max. :19.999585 Max. :896.141
Nhận xét: Sử dụng lệnh summary() kết quả trả về thống kê mô tả cơ bản của từng biến trong bộ dữ liệu, bao gồm giá trị nhỏ nhất (Min), giá trị lớn nhất (Max), trung vị (Median), trung bình (Mean) và các phần trăm phân vị (1st Qu., 3rd Qu.) cho biến số, đồng thời hiển thị số lượng và phân bố của các giá trị cho biến phân loại. Ví dụ, trong tieuluan, biến Quantity dao động từ 1–9 với trung bình 5.009, Price từ 10–100 với trung bình 55.07, và các phương thức thanh toán được phân bố tương đối đều với khoảng 25.000 quan sát cho mỗi loại.
# Kiểm tra toàn bộ giá trị bị thiếu trong dữ liệu (hiển thị 6 dòng đầu tiên)
head(is.na(tieuluan))
## CustomerID ProductID Quantity Price TransactionDate PaymentMethod
## [1,] FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE FALSE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE FALSE FALSE
## [6,] FALSE FALSE FALSE FALSE FALSE FALSE
## StoreLocation ProductCategory DiscountApplied... TotalAmount
## [1,] FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE
## [6,] FALSE FALSE FALSE FALSE
Nhận xét: Sử dụng lệnh is.na()) kết quả trả về kiểm tra giá trị bị thiếu (NA) trong bộ dữ liệu. Trong tieuluan, kết quả cho thấy không có (FALSE) giá trị thiếu ở bất kỳ biến nào, tất cả các quan sát đều đầy đủ.
# Kiểm tra xem dữ liệu có giá trị NA nào không
any(is.na(tieuluan))
## [1] FALSE
Nhận xét: Sử dụng lệnh any(is.na()) kết quả trả về kiểm tra xem có bất kỳ giá trị thiếu nào trong toàn bộ bộ dữ liệu hay không. Trong tieuluan, kết quả là FALSE, cho thấy toàn bộ dữ liệu đều đầy đủ, không có giá trị NA.
# Đếm tổng số giá trị bị thiếu trong toàn bộ dataset
sum(is.na(tieuluan))
## [1] 0
Nhận xét: Sử dụng lệnh sum(is.na()) kết quả trả về tổng số giá trị bị thiếu trong toàn bộ bộ dữ liệu. Trong tieuluan, kết quả là 0, nghĩa là không có bất kỳ giá trị NA nào trong dataset.
# Đếm số lượng giá trị NA trong từng cột
colSums(is.na(tieuluan))
## CustomerID ProductID Quantity Price
## 0 0 0 0
## TransactionDate PaymentMethod StoreLocation ProductCategory
## 0 0 0 0
## DiscountApplied... TotalAmount
## 0 0
Nhận xét: Sử dụng lệnh colSums(is.na()) kết quả trả về số lượng giá trị NA trong từng biến của bộ dữ liệu. Trong tieuluan, tất cả các biến đều có giá trị NA bằng 0, cho thấy không có giá trị thiếu ở bất kỳ cột nào.
# Liệt kê tên các cột có giá trị bị thiếu
names(tieuluan)[colSums(is.na(tieuluan)) > 0]
## character(0)
Nhận xét: Sử dụng lệnh names()[colSums(is.na()) > 0] kết quả trả về tên các biến có giá trị bị thiếu. Trong tieuluan, kết quả là character(0), nghĩa là không có cột nào bị thiếu giá trị.
# Xác định vị trí (hàng, cột) của các giá trị bị thiếu
which(is.na(tieuluan))
## integer(0)
Nhận xét: Sử dụng lệnh which(is.na()) kết quả trả về vị trí (hàng, cột) của các giá trị bị thiếu trong bộ dữ liệu. Trong tieuluan, kết quả là integer(0), nghĩa là không có giá trị NA nào trong toàn bộ dataset.
# Xem 6 giá trị đầu tiên của kết quả duplicated()
head(duplicated(tieuluan))
## [1] FALSE FALSE FALSE FALSE FALSE FALSE
Nhận xét: Sử dụng lệnh duplicated() kết quả trả về kiểm tra các quan sát trùng lặp trong bộ dữ liệu. Trong tieuluan, 6 giá trị đầu tiên đều là FALSE, nghĩa là các quan sát này không bị trùng lặp.
# Đếm tổng số dòng bị trùng
sum(duplicated(tieuluan))
## [1] 0
Nhận xét: Sử dụng lệnh sum(duplicated()) kết quả trả về tổng số quan sát trùng lặp trong bộ dữ liệu. Trong tieuluan, kết quả là 0, nghĩa là không có dòng nào bị trùng lặp.
# Xem thống kê biến Price để phát hiện giá trị bất thường
summary(tieuluan$Price)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 10.00 32.55 55.12 55.07 77.46 100.00
Nhận xét: Sử dụng lệnh summary() cho biến Price kết quả trả về thống kê mô tả cơ bản, giúp phát hiện giá trị bất thường. Biến Price dao động từ 10 đến 100, với trung bình 55.07 và trung vị 55.12, cho thấy không có giá trị ngoại lệ quá khác biệt trong dữ liệu.
# Tìm giá bán nhỏ hơn 0 (sai logic)
subset(tieuluan, Price < 0)
Nhận xét: Sử dụng lệnh subset() để tìm các giá trị Price nhỏ hơn 0 (sai logic). Kết quả trả về 0 hàng, nghĩa là không có giá trị bất thường nào về giá âm trong bộ dữ liệu tieuluan.
# Tìm các giao dịch có tổng tiền âm
subset(tieuluan, TotalAmount < 0)
Nhận xét: Sử dụng lệnh subset() để tìm các giao dịch có TotalAmount âm. Kết quả trả về 0 hàng, nghĩa là không có giao dịch nào có tổng tiền âm, dữ liệu hợp lý về mặt logic.
# Kiểm tra phương thức thanh toán để phát hiện lỗi chính tả
unique(tieuluan$PaymentMethod)
## [1] "Cash" "PayPal" "Debit Card" "Credit Card"
Nhận xét: Sử dụng lệnh unique() để liệt kê các giá trị khác nhau của phương thức thanh toán. Kết quả cho thấy chỉ có các giá trị “Cash”, “Credit Card”, “Debit Card” và “PayPal”, nghĩa là không có lỗi chính tả hay giá trị lạ trong cột PaymentMethod.
# Chuyển TransactionDate sang kiểu ngày tháng
tieuluan$TransactionDate <- as.Date(tieuluan$TransactionDate, format = "%Y-%m-%d")
# Chuyển Product.Category sang kiểu phân loại (factor)
tieuluan$ProductCategory<-as.factor(tieuluan$ProductCategory)
# Chuyển Payment.Method sang kiểu phân loại
tieuluan$PaymentMethod <- as.factor(tieuluan$PaymentMethod)
names(tieuluan)[names(tieuluan) == "DiscountApplied..."] <- "DiscountApplied"
# Kiểm tra kiểu dữ liệu của toàn bộ biến
sapply(tieuluan, class)
## CustomerID ProductID Quantity Price TransactionDate
## "integer" "character" "integer" "numeric" "Date"
## PaymentMethod StoreLocation ProductCategory DiscountApplied TotalAmount
## "factor" "character" "factor" "numeric" "numeric"
CustomerID ProductID Quantity “integer” “character” “integer” Price TransactionDate PaymentMethod “numeric” “Date” “factor” StoreLocation ProductCategory DiscountApplied “character” “factor” “numeric” TotalAmount “numeric”
Tác giả thực hiện các lệnh để truy cập dữ liệu dưới đây:
# Lấy cột mã khách hàng
head(tieuluan$CustomerID)
## [1] 109318 993229 579675 799826 121413 463050
# Lấy cột giá sản phẩm
head(tieuluan$Price)
## [1] 80.07984 75.19523 31.52882 98.88022 93.18851 54.09315
# Lấy cột tổng tiền bằng cách gọi theo tên
head(tieuluan[, "TotalAmount"])
## [1] 455.8628 258.3065 212.0157 461.3438 626.0305 144.6092
# Lấy hàng đầu tiên của dữ liệu
tieuluan[1, ]
# Lấy hàng thứ 4
tieuluan[4, ]
# Lấy các hàng từ 2 đến 4
tieuluan[2:4, ]
# Lấy hàng thứ 2 và 4
tieuluan[c(2, 4), ]
# Lấy cột thứ 2 (ProductID)
head(tieuluan[, 2])
## [1] "C" "C" "A" "D" "A" "D"
# Lấy giá trị Price của dòng thứ 5
tieuluan[5, "Price"]
## [1] 93.18851
# Lấy giá và số lượng của 3 dòng đầu tiên
tieuluan[1:3, c("Price", "Quantity")]
# Tìm giao dịch có tổng tiền lớn nhất
which.max(tieuluan$TotalAmount)
## [1] 52098
# Hiển thị thông tin giao dịch có tổng tiền lớn nhất
tieuluan[which.max(tieuluan$TotalAmount), ]
# Tìm giao dịch có tổng tiền nhỏ nhất
which.min(tieuluan$TotalAmount)
## [1] 74088
# Hiển thị giao dịch có tổng tiền nhỏ nhất
tieuluan[which.min(tieuluan$TotalAmount), ]
# Tìm sản phẩm có giá cao nhất
which.max(tieuluan$Price)
## [1] 465
tieuluan[which.max(tieuluan$Price), ]
# Tìm sản phẩm có giá thấp nhất
which.min(tieuluan$Price)
## [1] 85886
tieuluan[which.min(tieuluan$Price), ]
Tác giả thực hiện các lệnh lọc dữ liệu cơ bản theo điều kiện:
# Lọc các giao dịch có giá >= 500
tieuluan[tieuluan$Price >= 500, ]
# Lọc các giao dịch có tổng tiền lớn hơn 1000
tieuluan[tieuluan$TotalAmount > 1000, ]
# Lọc các giao dịch có giảm giá (DiscountApplied...) khác 0
tieuluan[tieuluan$DiscountApplied... != 0, ]
# Lọc các giao dịch thanh toán bằng thẻ (Credit Card)
tieuluan[tieuluan$PaymentMethod == "Credit Card", ]
# Lọc các giao dịch KHÔNG thanh toán bằng tiền mặt
tieuluan[tieuluan$PaymentMethod != "Cash", ]
# Lọc sản phẩm thuộc danh mục “Electronics”
tieuluan[tieuluan$ProductCategory == "Electronics", ]
# Lọc các giao dịch có giảm giá trên 10%
tieuluan[tieuluan$DiscountApplied> 10, ]
# Lọc các giao dịch có tổng tiền từ 500 đến 1000
tieuluan[tieuluan$TotalAmount >= 500 & tieuluan$TotalAmount <= 1000, ]
# Lọc giao dịch có giá cao HOẶC giảm giá trên 5%
tieuluan[tieuluan$Price > 300 | tieuluan$DiscountApplied > 5, ]
Tác giả thực hiện các lệnh thêm và sửa dữ liệu dưới đây:
# Chỉnh lại phương thức thanh toán ở dòng đầu tiên
tieuluan$PaymentMethod[1] <- "Cash"
# Cập nhật lại tên địa điểm cho dòng thứ 5
tieuluan$StoreLocation[5] <- "2804 Michelle Island Suite 143 Holand, VA 80142"
# Thêm cột đánh số thứ tự giao dịch
tieuluan$TransactionNo <- 1:nrow(tieuluan)
# Xóa cột vừa thêm (nếu không cần)
tieuluan$TransactionNo <- NULL
# Xóa hàng thứ 3 khỏi dữ liệu
tieuluan <- tieuluan[-3, ]
# Kiểm tra lại kích thước dữ liệu sau khi xóa
dim(tieuluan)
## [1] 99999 10
library(dplyr)
tieuluan <- tieuluan %>%
mutate(
mucgia = case_when( #phân loại Price thành các mức
is.na(Price) ~ NA_character_, # Nếu Price bị thiếu, giữ nguyên NA nếu thiếu dữ liệu
Price < 20.000 ~ "Rất rẻ",
Price >= 20.000 & Price < 40.000 ~ "Rẻ",
Price >= 40.000 & Price < 60.000 ~ "Trung bình",
Price >= 60.000 & Price < 80.000 ~ "Mắc",
Price >= 80.000 ~ "Rất mắc"
)
)
tieuluan <- tieuluan %>%
mutate(
TotalAmount_mucgia = cut( #chia các gtrị thành nhóm nhỏ
TotalAmount,
breaks = 6, #chia 6 khoảng gtrị bằng nhau
labels = c("Rất thấp", "Thấp", "TB thấp", "TB cao", "Cao", "Rất cao"),
include.lowest = TRUE #gtrị nhỏ nhất vào nhóm đầu
)
)
library(dplyr)
library(stringr)
tieuluan <- tieuluan %>%
mutate(
tieubang = str_extract(StoreLocation, "[A-Z]{2}(?=\\s[0-9]{5}$)"),
) #2 chữ in hoa liên tiếp, khoảng trắng, 5 chữ số, cuối chuỗi, k lấy
data1 <- subset(
tieuluan,
ProductID == "A" &
Quantity > 3 &
PaymentMethod == "Cash"
)
head(data1)
table(data1$Quantity)
##
## 4 5 6 7 8 9
## 656 712 637 697 708 698
data2 <- subset(
tieuluan,
PaymentMethod == "PayPal" &
TotalAmount_mucgia %in% c("Cao", "Rất cao") #các dòng cao hoặc rất cao
)
head(data2)
data3 <- subset(
tieuluan,
mucgia == "Rất mắc" &
Quantity >= 5
)
head(data3)
dim(data3)
## [1] 12529 13
data4 <- subset(
tieuluan,
ProductID %in% c("A", "B") &
Quantity >= 5 &
TotalAmount > mean(tieuluan$TotalAmount, na.rm = TRUE) #bỏ qua các gtrị trung bình
)
head(data4)
tieuluan$TransactionDate <- as.POSIXct(tieuluan$TransactionDate) # đảm bảo là dạng ngày-giờ không phải văn bản
data5 <- subset(
tieuluan,
TransactionDate >= as.POSIXct("2023-07-01") & #tạo mốc thời gian
TransactionDate <= as.POSIXct("2023-12-31") &
PaymentMethod %in% c("PayPal", "Credit Card")
)
head(data5)
tieuluan$TransactionDate <- as.POSIXct(tieuluan$TransactionDate)
data6 <- subset(
tieuluan,
TransactionDate >= as.POSIXct("2023-10-01") &
TransactionDate <= as.POSIXct("2023-12-31") &
PaymentMethod %in% c("PayPal", "Credit Card") &
tieubang %in% c("VA", "MO", "HI") &
TotalAmount > 300
)
head(data6)
#thêm cột tháng và quý
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
tieuluan <- tieuluan %>%
mutate(
Month = format(TransactionDate, "%m"),
Quarter = quarter(TransactionDate))
# Thống kê mô tả 1 biến
thongke1 <- tieuluan %>%
summarise(
Sogiaodich = n(),
Giatritb = mean(TotalAmount, na.rm = TRUE),
max = max(TotalAmount, na.rm = TRUE),
min = min(TotalAmount, na.rm = TRUE),
Trungvi = median(TotalAmount, na.rm = TRUE),
Dolechchuan = sd(TotalAmount, na.rm = TRUE),
Q1 = quantile(TotalAmount, 0.25, na.rm = TRUE),
Q3 = quantile(TotalAmount, 0.75, na.rm = TRUE)
)
head(thongke1)
Dựa vào bảng thông kê trên
Tổng giá trị giao dịch là 100.000 giao dịch
Giá trị trung bình của giá trị giao dịch là 248.335
Trung vị: 200.37
Giá trị tối thiểu và tối đa: 8.27 – 896.14 → khoảng cách rất lớn, nhấn mạnh biến động giao dịch đa dạng.
Độ lệch chuẩn: 184.55
Q1 và Q3: 95.16 – 362.01, phản ánh đa số giao dịch ở mức vừa phải
#tính thống kê mô tả cho từng loại sản phẩm (A–D) theo cột Price
thongke2 <- tieuluan %>%
group_by(ProductID) %>%
summarise(
Soluong = n(),
Giatritb = mean(Price, na.rm = TRUE),
max = max(Price, na.rm = TRUE),
min = min(Price, na.rm = TRUE),
Trungvi = median(Price, na.rm = TRUE),
Dolechchuan = sd(Price, na.rm = TRUE),
Q1 = quantile(Price, 0.25, na.rm = TRUE),
Q3 = quantile(Price, 0.75, na.rm = TRUE)
) %>%
arrange(ProductID)
head(thongke2)
Dựa vào bảng thông kê trên
Số lượng giao dịch của các sản phẩm tương đương nhau, khoảng 24.700–25.200 giao dịch, nghĩa là mức phổ biến gần như đồng đều.
Giá trung bình và trung vị đều xấp xỉ 55 cho tất cả sản phẩm, cho thấy giá bán ổn định giữa các sản phẩm.
Độ lệch chuẩn đều xấp xỉ gần 26
Khoảng giá Q1–Q3 đều vào khoảng 32–77 phản ánh phần lớn giao dịch nằm trong khoảng giá vừa phải
Giá tối đa đều xấp xỉ gần 100 và tối thiểu đều xấp xỉ gần bằng 10 cho tất cả sản phẩm → giá dao động rộng
#giá trung bình của từng sản phẩm theo cách thanh toán
thongke3 <- tieuluan %>%
group_by(ProductID, PaymentMethod) %>%
summarise(
Sogiaodich = n(),
Giatritb = mean(Price, na.rm = TRUE),
max = max(Price, na.rm = TRUE),
min = min(Price, na.rm = TRUE),
Trungvi = median(Price, na.rm = TRUE),
Dolechchuan = sd(Price, na.rm = TRUE),
Q1 = quantile(Price, 0.25, na.rm = TRUE),
Q3 = quantile(Price, 0.75, na.rm = TRUE)
) %>%
arrange(ProductID, desc(Giatritb)) #desc() theo thứ tự giảm dần,xem nhanh phương thức thanh toán nào có giá trung bình cao nhất cho từng sản phẩm.
## `summarise()` has grouped output by 'ProductID'. You can override using the
## `.groups` argument.
head(thongke3)
Dựa vào bảng thông kê trên
Giá trung bình của các sản phẩm A,B,C,D khá giống nhau, nằm trong khoảng 54.13 – 55.58.
Khi so sánh theo phương thức thanh toán: Cash và Credit Card có giá trung bình cao hơn Debit Card và PayPal khoảng 0.4 – 1.5 đơn vị.
Giá tối thiểu và tối đa cho tất cả sản phẩm dao động từ 10 – 100
Q1–Q3 nằm trong khoảng 31.6 – 78.2, cho thấy nửa số giao dịch rơi vào mức giá vừa phải
Độ lệch chuẩn đều xấp xỉ gần 26
#giá thay đổi theo quý và loại hàng hóa
thongke4 <- tieuluan %>%
group_by(Quarter, ProductCategory) %>%
summarise(
Giatritb = mean(Price, na.rm = TRUE),
max = max(Price, na.rm = TRUE),
min = min(Price, na.rm = TRUE),
Trungvi = median(Price, na.rm = TRUE),
Dolechchuan = sd(Price, na.rm = TRUE),
Q1 = quantile(Price, 0.25, na.rm = TRUE),
Q3 = quantile(Price, 0.75, na.rm = TRUE)
) %>%
arrange(Quarter, desc(Giatritb))
## `summarise()` has grouped output by 'Quarter'. You can override using the
## `.groups` argument.
head(thongke4)
Dựa vào bảng thống kê trên
Các loại hàng hóa có giá trung bình khá tương đồng, dao động quanh 54.5 – 55.3.
Giá Books và Clothing so với Electronics và Home Decor chênh lệch không nhiều.
Giá tối thiểu và tối đa cho tất cả sản phẩm dao động từ 10 – 100 cho tất cả sản phẩm theo quý, chứng tỏ giá dao động rộng
Q1–Q3 nằm trong khoảng 32 – 78, cho thấy nửa số giao dịch rơi vào mức giá vừa phải
Giá trung bình giữa các quý không thay đổi nhiều, dao động xấp xỉ 55, điều này cho thấy giá bán ổn định theo thời gian.
# Biểu đồ phân tán giữa Giá và Tổng tiền thanh toán
plot(tieuluan$Price, tieuluan$TotalAmount,
main = "Mối quan hệ giữa Giá sản phẩm và Tổng tiền",
xlab = "Giá sản phẩm",
ylab = "Tổng tiền thanh toán",
col = "steelblue",
pch = 16)
# Tổng doanh thu theo ngày giao dịch
library(dplyr)
daily_sales <- tieuluan %>%
group_by(TransactionDate) %>%
summarise(Total_Sales = sum(TotalAmount, na.rm = TRUE))
# Vẽ biểu đồ đường
plot(daily_sales$TransactionDate, daily_sales$Total_Sales,
type = "l",
main = "Doanh thu theo ngày giao dịch",
xlab = "Ngày giao dịch",
ylab = "Tổng doanh thu",
col = "red",
lwd = 2)
# Tổng doanh thu theo loại sản phẩm
category_sales <- tieuluan %>%
group_by(ProductCategory) %>%
summarise(Total_Sales = sum(TotalAmount, na.rm = TRUE))
barplot(category_sales$Total_Sales,
names.arg = category_sales$ProductCategory,
main = "Doanh thu theo danh mục sản phẩm",
xlab = "Danh mục sản phẩm",
ylab = "Tổng doanh thu",
col = c("skyblue", "gold", "salmon", "violet"))
# Biểu đồ tần suất của biến Price
hist(tieuluan$Price,
main = "Phân phối giá sản phẩm",
xlab = "Giá sản phẩm",
ylab = "Tần suất",
col = "lightblue",
border = "white")
# Biểu đồ hộp tổng tiền theo phương thức thanh toán
boxplot(TotalAmount ~ PaymentMethod, data = tieuluan,
main = "So sánh tổng tiền theo phương thức thanh toán",
xlab = "Phương thức thanh toán",
ylab = "Tổng tiền thanh toán",
col = c("lightgreen", "lightpink", "skyblue"))
# Tính số lượng sản phẩm theo danh mục
category_counts <- table(tieuluan$ProductCategory)
# Vẽ biểu đồ tròn
pie(category_counts,
main = "Tỷ lệ danh mục sản phẩm",
col = rainbow(length(category_counts)))