# Nạp thư viện
library(readr)
library(dplyr)
library(janitor)
library(tidyr)
library(knitr)
# Đọc dữ liệu
data <- read_csv("C:/Data/data.csv")
# Số lượng biến
cat("Số lượng biến (cột):", ncol(data), "\n")
## Số lượng biến (cột): 16
# Số lượng quan quan sát
cat("Số lượng quan sát (hàng):", nrow(data), "\n")
## Số lượng quan sát (hàng): 558837
# Số dòng trùng lặp
dup <- sum(duplicated(data))
cat("Số dòng trùng lặp là:", dup, "\n")
## Số dòng trùng lặp là: 0
na_count <- sum(is.na(data))
cat("Tổng số giá trị bị thiếu:", na_count, "\n")
## Tổng số giá trị bị thiếu: 123376
cat("Số lượng giá trị bị thiếu theo từng biến:\n")
## Số lượng giá trị bị thiếu theo từng biến:
print(colSums(is.na(data)))
## year make model trim body transmission
## 0 10301 10399 10651 13195 65352
## vin state condition odometer color interior
## 4 0 11820 94 749 749
## seller mmr sellingprice saledate
## 0 38 12 12
variable_meaning <- data.frame(
Variable = c("year", "make", "model", "trim", "body", "transmission", "vin", "state",
"condition", "odometer", "color", "interior", "seller",
"mmr", "sellingprice", "saledate"),
Meaning = c(
"Năm sản xuất của xe",
"Hãng sản xuất (VD: Kia, BMW, Toyota...)",
"Tên dòng xe cụ thể",
"Phiên bản hoặc cấp độ trang bị của xe",
"Kiểu dáng xe (Sedan, SUV, Coupe...)",
"Loại hộp số (tự động, tay)",
"Số khung xe (Vehicle Identification Number)",
"Bang hoặc khu vực đăng ký",
"Tình trạng của xe",
"Số km xe đã đi",
"Màu sơn bên ngoài",
"Màu nội thất bên trong",
"Tên người bán hoặc đại lý",
"Giá trị thị trường trung bình (MMR)",
"Giá bán thực tế (USD)",
"Ngày bán xe"
),
stringsAsFactors = FALSE
)
# 2️⃣ Bảng kiểu dữ liệu
data_types <- data.frame(
Variable = names(data),
DataType = sapply(data, class),
stringsAsFactors = FALSE
)
# 3️⃣ Gộp 2 bảng
variable_summary <- left_join(variable_meaning, data_types, by = "Variable")
# 4️⃣ Hiển thị bảng
kable(variable_summary, caption = "Bảng: Mô tả và kiểu dữ liệu của các biến trong bộ dữ liệu")
Variable | Meaning | DataType |
---|---|---|
year | Năm sản xuất của xe | numeric |
make | Hãng sản xuất (VD: Kia, BMW, Toyota…) | character |
model | Tên dòng xe cụ thể | character |
trim | Phiên bản hoặc cấp độ trang bị của xe | character |
body | Kiểu dáng xe (Sedan, SUV, Coupe…) | character |
transmission | Loại hộp số (tự động, tay) | character |
vin | Số khung xe (Vehicle Identification Number) | character |
state | Bang hoặc khu vực đăng ký | character |
condition | Tình trạng của xe | numeric |
odometer | Số km xe đã đi | numeric |
color | Màu sơn bên ngoài | character |
interior | Màu nội thất bên trong | character |
seller | Tên người bán hoặc đại lý | character |
mmr | Giá trị thị trường trung bình (MMR) | numeric |
sellingprice | Giá bán thực tế (USD) | numeric |
saledate | Ngày bán xe | character |
# Chọn các biến định lượng
data_numeric <- data %>%
select(condition, odometer, mmr, sellingprice)
# Tính các thống kê mô tả cơ bản
descriptive_stats <- data_numeric %>%
summarise(
`Số quan sát hợp lệ` = n(),
`Giá trị thiếu (NA)` = sum(is.na(condition)) + sum(is.na(odometer)) +
sum(is.na(mmr)) + sum(is.na(sellingprice)),
.groups = "drop"
)
# Tạo bảng mô tả từng biến
descriptive_table <- data_numeric %>%
summarise(
`Giá trị nhỏ nhất` = sapply(., min, na.rm = TRUE),
`Q1 (25%)` = sapply(., quantile, probs = 0.25, na.rm = TRUE),
`Trung vị (50%)` = sapply(., median, na.rm = TRUE),
`Trung bình` = sapply(., mean, na.rm = TRUE),
`Q3 (75%)` = sapply(., quantile, probs = 0.75, na.rm = TRUE),
`Giá trị lớn nhất` = sapply(., max, na.rm = TRUE),
`Số giá trị thiếu` = sapply(., function(x) sum(is.na(x)))
) %>%
t() %>%
as.data.frame()
# Gắn tên cột
colnames(descriptive_table) <- c("condition", "odometer", "mmr", "sellingprice")
# Hiển thị bảng
kable(
descriptive_table,
caption = "Bảng: Thống kê mô tả các biến định lượng"
)
condition | odometer | mmr | sellingprice | |
---|---|---|---|---|
Giá trị nhỏ nhất | 1.00000 | 1.00 | 25.00 | 1.00 |
Q1 (25%) | 23.00000 | 28371.00 | 7100.00 | 6900.00 |
Trung vị (50%) | 35.00000 | 52254.00 | 12250.00 | 12100.00 |
Trung bình | 30.67236 | 68320.02 | 13769.38 | 13611.36 |
Q3 (75%) | 42.00000 | 99109.00 | 18300.00 | 18200.00 |
Giá trị lớn nhất | 49.00000 | 999999.00 | 182000.00 | 230000.00 |
Số giá trị thiếu | 11820.00000 | 94.00 | 38.00 | 12.00 |
# Phân tổ giá trung bình theo hãng và năm
phan_to_year_make <- data %>%
group_by(year, make) %>%
summarise(
`Giá bán trung bình (USD)` = mean(sellingprice, na.rm = TRUE),
`Số lượng xe` = n(),
.groups = "drop"
) %>%
arrange(desc(`Giá bán trung bình (USD)`))
# Vẽ xu hướng giá trung bình theo năm cho 5 hãng phổ biến
top5 <- data %>%
count(make, sort = TRUE) %>%
slice_head(n = 5) %>%
pull(make)
library(ggplot2)
data %>%
filter(make %in% top5) %>%
group_by(year, make) %>%
summarise(mean_price = mean(sellingprice, na.rm = TRUE), .groups = "drop") %>%
ggplot(aes(x = year, y = mean_price, color = make)) +
geom_line(linewidth = 1.1) +
geom_point(size = 2) +
labs(title = "Xu hướng giá bán trung bình theo năm của 5 hãng xe phổ biến",
x = "Năm sản xuất", y = "Giá trung bình (USD)", color = "Hãng xe") +
theme_minimal()
# Lọc dữ liệu chỉ lấy xe sản xuất năm 2015
data_2015 <- data %>%
filter(year == 2015)
# Tính giá trung bình theo hãng xe trong năm 2015
price_by_make_2015 <- data_2015 %>%
group_by(make) %>%
summarise(
`Giá bán trung bình (USD)` = mean(sellingprice, na.rm = TRUE),
`Trung vị (USD)` = median(sellingprice, na.rm = TRUE),
`Số lượng xe` = n(),
.groups = "drop"
) %>%
arrange(desc(`Giá bán trung bình (USD)`))
# ✅ Hiển thị TẤT CẢ các hãng (bỏ head)
kable(
price_by_make_2015,
caption = "Bảng: Giá bán trung bình của tất cả các hãng xe trong năm sản xuất 2015"
)
make | Giá bán trung bình (USD) | Trung vị (USD) | Số lượng xe |
---|---|---|---|
Jaguar | 75706.667 | 85500 | 15 |
Porsche | 60881.250 | 57375 | 8 |
Cadillac | 58142.742 | 68550 | 62 |
Land Rover | 55750.000 | 44500 | 8 |
Mercedes-Benz | 52187.879 | 39500 | 132 |
Infiniti | 47235.000 | 41125 | 10 |
BMW | 42937.234 | 40250 | 658 |
Lexus | 41307.812 | 39500 | 96 |
GMC | 38531.328 | 37750 | 241 |
Lincoln | 34945.000 | 32950 | 30 |
Ram | 34639.362 | 36900 | 47 |
Chevrolet | 31763.397 | 29300 | 1435 |
Acura | 31159.091 | 33700 | 22 |
Audi | 29541.667 | 26950 | 126 |
Ford | 27346.500 | 27500 | 990 |
Jeep | 27038.855 | 28050 | 332 |
Volvo | 26107.683 | 24700 | 397 |
Subaru | 24541.314 | 23700 | 236 |
Buick | 23759.426 | 23300 | 122 |
MINI | 23460.417 | 23000 | 48 |
Honda | 22065.584 | 19400 | 77 |
Kia | 19684.312 | 20200 | 1482 |
Scion | 19333.333 | 19800 | 9 |
Toyota | 19302.996 | 16800 | 237 |
NA | 19202.804 | 18400 | 214 |
Dodge | 19175.203 | 19450 | 246 |
Mazda | 18604.692 | 18800 | 373 |
Hyundai | 17441.706 | 14900 | 504 |
Chrysler | 16951.222 | 16400 | 491 |
Nissan | 16513.403 | 13200 | 623 |
chevrolet | 15733.333 | 17700 | 3 |
Mitsubishi | 15593.939 | 14350 | 66 |
Volkswagen | 15184.831 | 14800 | 89 |
smart | 9166.667 | 9000 | 3 |
FIAT | 8740.000 | 10000 | 5 |
###Hãng xe
unique(data$make)
## [1] "Kia" "BMW" "Volvo" "Nissan"
## [5] "Chevrolet" "Audi" "Ford" "Hyundai"
## [9] "Buick" "Cadillac" "Acura" "Lexus"
## [13] "Infiniti" "Jeep" "Mercedes-Benz" "Mitsubishi"
## [17] "Mazda" "MINI" "Land Rover" "Lincoln"
## [21] "lincoln" "Jaguar" "Volkswagen" "Toyota"
## [25] "Subaru" "Scion" "Porsche" NA
## [29] "bmw" "Dodge" "FIAT" "Chrysler"
## [33] "ford" "Ferrari" "Honda" "GMC"
## [37] "mitsubishi" "Ram" "smart" "chevrolet"
## [41] "Bentley" "chrysler" "pontiac" "Pontiac"
## [45] "Saturn" "Maserati" "Mercury" "HUMMER"
## [49] "landrover" "cadillac" "land rover" "mercedes"
## [53] "mazda" "toyota" "lexus" "gmc truck"
## [57] "honda" "nissan" "porsche" "Saab"
## [61] "Suzuki" "dodge" "subaru" "Oldsmobile"
## [65] "oldsmobile" "hyundai" "jeep" "Isuzu"
## [69] "dodge tk" "Geo" "acura" "volkswagen"
## [73] "suzuki" "kia" "audi" "Rolls-Royce"
## [77] "gmc" "maserati" "mazda tk" "mercury"
## [81] "buick" "hyundai tk" "mercedes-b" "vw"
## [85] "Daewoo" "chev truck" "ford tk" "plymouth"
## [89] "Plymouth" "ford truck" "Tesla" "airstream"
## [93] "dot" "Aston Martin" "Fisker" "Lamborghini"
## [97] "Lotus"
###transmission
unique(data$transmission)
## [1] "automatic" NA "manual" "Sedan" "sedan"
. sellingprice
(Giá bán): Biến mục
tiêu, là trung tâm của câu chuyện. 2. odometer
(Số
km đã đi): Một biến số (numeric) quan trọng, giả thuyết là đi
càng nhiều giá càng giảm. 3. make
(Hãng
xe): Một biến phân loại (categorical) quan trọng, giả thuyết là
các hãng xe sang sẽ có giá cao hơn. ##Khám phá biến trung tâm
sellingprice
(Giá bán) Mục tiêu: Hiểu được
mức giá bán xe trong bộ dữ liệu này phân bố như thế nào. Xe thường được
bán ở khoảng giá nào? Tính toán thống kê mô tả: Dùng
hàm summary()
để có cái nhìn tổng quan (giá nhỏ nhất, lớn
nhất, trung bình, trung vị).
summary(data$sellingprice)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1 6900 12100 13611 18200 230000 12
Vẽ biểu đồ Histogram: Đây là cách tốt nhất để trực quan hóa sự phân phối của một biến số.
library(ggplot2)
ggplot(data = data, aes(x = sellingprice)) +
geom_histogram(bins = 50, fill = "dodgerblue", alpha = 0.7) +
labs(title = "Phân phối của Giá Bán Xe (sellingprice)",
x = "Giá bán ($)",
y = "Số lượng xe") +
theme_minimal()
Nhận xét: Biểu đồ cho thấy phân phối giá bán xe bị lệch phải,
phần lớn xe có giá từ 5.000–25.000 USD. ## So sánh
sellingprice
giữa các make
(Hãng xe)
Mục tiêu: Xem xét yếu tố thương hiệu ảnh hưởng đến giá bán như thế nào. Hãng xe nào được định giá cao nhất trên thị trường xe cũ?
dplyr
để nhóm dữ liệu theo hãng và tính giá trung bình. Chỉ
nên chọn khoảng 15 hãng xe phổ biến nhất để biểu đồ không bị rối. library(dplyr)
# Lọc ra 15 hãng xe có số lượng nhiều nhất
top_makes <-data %>%
count(make, sort = TRUE) %>%
slice(1:15) %>%
pull(make)
# Tính giá trung bình cho các hãng này và vẽ biểu đồ
gia_theo_hang <- data %>%
filter(make %in% top_makes) %>%
group_by(make) %>%
summarise(gia_trung_binh = mean(sellingprice))
ggplot(data = gia_theo_hang, aes(x = reorder(make, -gia_trung_binh), y = gia_trung_binh)) +
geom_col(fill = "goldenrod") +
labs(title = "Giá bán trung bình của 15 hãng xe phổ biến nhất",
x = "Hãng xe",
y = "Giá bán trung bình ($)") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))