BÁO CÁO TIỂU
LUẬN
NGÔN NGỮ
LẬP TRÌNH TRONG PHÂN TÍCH DỮ LIỆU
| Nhóm | : 28 |
| Thành viên thực hiện | : Võ Thị Kiều My |
| : Trần Huỳnh Ni Ka | |
| Mã lớp học phần | : 2531101140001 |
Bộ dữ liệu Vehicle Sales Data là một bộ dữ liệu công khai trên nền tảng Kaggle, được thu thập nhằm phục vụ cho các bài toán phân tích và dự đoán giá xe đã qua sử dụng. Dữ liệu bao gồm thông tin về hãng xe, năm sản xuất, số km đã đi, tình trạng xe và giá bán, giúp đánh giá các yếu tố ảnh hưởng đến giá trị của xe trên thị trường. # Dữ liệu
# Nạp các thư viện cần thiết
library(readr) # Đọc file CSV
library(dplyr) # Xử lý dữ liệu
library(kableExtra)
# Đọ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ố giá trị bị thiếu
total_NA <- sum(is.na(data))
NA_by_column <- sapply(data, function(x) sum(is.na(x)))
cat("Tổng số giá trị NA:", total_NA, "\n\n")
## Tổng số giá trị NA: 123376
NA_table <- tibble::enframe(NA_by_column, name = "variable", value = "n_missing") %>%
arrange(desc(n_missing))
kable(NA_table, caption = "Số giá trị thiếu (NA) theo biến") %>% kable_styling(full_width = FALSE)
| variable | n_missing |
|---|---|
| transmission | 65352 |
| body | 13195 |
| condition | 11820 |
| trim | 10651 |
| model | 10399 |
| make | 10301 |
| color | 749 |
| interior | 749 |
| odometer | 94 |
| mmr | 38 |
| sellingprice | 12 |
| saledate | 12 |
| vin | 4 |
| year | 0 |
| state | 0 |
| seller | 0 |
data <- data %>%
filter_all(all_vars(!is.na(.))) %>% # loại bỏ NA
filter_all(all_vars(!is.infinite(.))) # loại bỏ Inf
n_dup_rows <- sum(duplicated(data))
cat("\nSố dòng trùng lặp:", n_dup_rows, "\n")
##
## Số dòng trùng lặp: 0
if (n_dup_rows > 0) {
cat("Ví dụ vài dòng trùng lặp:\n")
print(head(data[duplicated(data) | duplicated(data, fromLast = TRUE), ], 6))
} else {
cat("Không tìm thấy dòng trùng lặp (theo toàn bộ hàng).\n")
}
## Không tìm thấy dòng trùng lặp (theo toàn bộ hàng).
orig_names <- names(data)
# Phát hiện tên có ký tự ngoài chữ/ số / underscore
bad_names <- orig_names[grepl("[^A-Za-z0-9_]", orig_names)]
cat("\nTên biến ban đầu:\n"); print(orig_names)
##
## Tên biến ban đầu:
## [1] "year" "make" "model" "trim" "body"
## [6] "transmission" "vin" "state" "condition" "odometer"
## [11] "color" "interior" "seller" "mmr" "sellingprice"
## [16] "saledate"
if (length(bad_names) > 0) {
cat("\nCác tên chứa ký tự đặc biệt hoặc khoảng trắng:\n"); print(bad_names)
} else {
cat("\nKhông phát hiện ký tự đặc biệt trong tên biến.\n")
}
##
## Không phát hiện ký tự đặc biệt trong tên biến.
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 ",
"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 ",
"Loại hộp số ",
"Số khung xe ",
"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
)
# Bảng kiểu dữ liệu
data_types <- data.frame(
Variable = names(data),
DataType = sapply(data, class),
stringsAsFactors = FALSE
)
# Gộp 2 bảng
variable_summary <- left_join(variable_meaning, data_types, by = "Variable")
# 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 | 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 | character |
| transmission | Loại hộp số | character |
| vin | Số khung xe | 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 |
Bộ dữ liệu gồm 16 biến, bao quát thông tin từ năm sản xuất, hãng xe, dòng xe, kiểu dáng, tình trạng, số km đã đi, đến giá bán thực tế.
Trong đó:
Biến định lượng (numeric): year,
condition, odometer, mmr,
sellingprice.
Biến định tính (character): chiếm đa số, mô tả
đặc điểm chi tiết của xe như make, model,
color, interior, seller,
…
➡️ Bộ dữ liệu kết hợp giữa dữ liệu định tính (mô tả đặc trưng xe) và dữ liệu định lượng (phục vụ cho phân tích giá bán).
# 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%) | 24.00000 | 28137.00 | 7425.00 | 7200.00 |
| Trung vị (50%) | 35.00000 | 51085.00 | 12300.00 | 12200.00 |
| Trung bình | 30.77418 | 66701.73 | 13837.06 | 13690.51 |
| Q3 (75%) | 41.00000 | 96590.00 | 18300.00 | 18200.00 |
| Giá trị lớn nhất | 49.00000 | 999999.00 | 182000.00 | 230000.00 |
| Số giá trị thiếu | 0.00000 | 0.00 | 0.00 | 0.00 |
data <- data %>%
mutate(
Nhom_nam = case_when(
year < 2000 ~ "Trước năm 2000",
year >= 2000 & year <= 2010 ~ "2000 - 2010",
year > 2010 ~ "Sau 2010"
)
)
data %>%
group_by(Nhom_nam) %>%
summarise(
So_luong_xe = n(),
Gia_ban_tb = mean(sellingprice, na.rm = TRUE)
)
## # A tibble: 3 × 3
## Nhom_nam So_luong_xe Gia_ban_tb
## <chr> <int> <dbl>
## 1 2000 - 2010 172016 7331.
## 2 Sau 2010 293937 17682.
## 3 Trước năm 2000 6372 1229.
Bảng thể hiện Top 10 hãng xe có số lượng giao dịch nhiều nhất
bang_phan_to <- data %>%
group_by(make) %>%
summarise(
So_luong_xe = n(),
Gia_trung_binh = mean(sellingprice, na.rm = TRUE),
Gia_thap_nhat = min(sellingprice, na.rm = TRUE),
Gia_cao_nhat = max(sellingprice, na.rm = TRUE)
) %>%
arrange(desc(So_luong_xe)) %>%
head(10)
bang_phan_to
## # A tibble: 10 × 5
## make So_luong_xe Gia_trung_binh Gia_thap_nhat Gia_cao_nhat
## <chr> <int> <dbl> <dbl> <dbl>
## 1 Ford 81013 14830. 1 230000
## 2 Chevrolet 54150 11866. 100 84500
## 3 Nissan 44043 11745. 100 86400
## 4 Toyota 35313 12422. 150 68900
## 5 Dodge 27181 10964. 100 51700
## 6 Honda 24781 10943. 200 37000
## 7 Hyundai 18659 11062. 100 55000
## 8 BMW 17509 21290. 100 165000
## 9 Kia 15828 11768. 200 42750
## 10 Chrysler 15133 10627. 100 41000
Hãng Ford có số lượng xe lớn nhất
(93.554 chiếc), chiếm tỷ trọng cao nhất trong toàn bộ
dữ liệu.
Các hãng Chevrolet, Nissan, Toyota cũng có lượng xe giao dịch lớn, dao động từ 39.000–60.000 xe.
Mức giá trung bình giữa các hãng có sự chênh lệch đáng kể:
Giá cao nhất trong dữ liệu lên tới 230.000 USD (Ford) — có thể là các dòng xe đặc biệt hoặc xe mới cao cấp.
➡️ Nhìn chung, thị trường xe có sự đa dạng lớn về giá và thương hiệu, thể hiện rõ xu hướng phổ biến của các hãng tầm trung.
data_phan_to_km <- data %>%
mutate(
Nhom_km = cut(
odometer,
breaks = c(-Inf, 10000, 50000, 100000, 200000, Inf),
labels = c("< 10.000 km", "10.000–50.000 km", "50.000–100.000 km", "100.000–200.000 km", "> 200.000 km")
)
) %>%
group_by(Nhom_km) %>%
summarise(
So_luong_xe = n(),
Gia_trung_binh = round(mean(sellingprice, na.rm = TRUE), 2),
Gia_thap_nhat = min(sellingprice, na.rm = TRUE),
Gia_cao_nhat = max(sellingprice, na.rm = TRUE)
) %>%
arrange(Nhom_km)
kable(data_phan_to_km, caption = "Bảng phân tổ số km đã đi và giá bán trung bình")
| Nhom_km | So_luong_xe | Gia_trung_binh | Gia_thap_nhat | Gia_cao_nhat |
|---|---|---|---|---|
| < 10.000 km | 22072 | 22799.91 | 1 | 173000 |
| 10.000–50.000 km | 210362 | 18428.14 | 1 | 230000 |
| 50.000–100.000 km | 129592 | 11718.66 | 100 | 108200 |
| 100.000–200.000 km | 101465 | 5368.72 | 100 | 43000 |
| > 200.000 km | 8834 | 2622.74 | 100 | 26800 |
Nhận xét:
data <- data %>%
mutate(
Nhom_gia = case_when(
sellingprice < 10000 ~ "< 10.000 USD",
sellingprice >= 10000 & sellingprice < 20000 ~ "10.000–20.000 USD",
sellingprice >= 20000 & sellingprice < 40000 ~ "20.000–40.000 USD",
sellingprice >= 40000 & sellingprice < 60000 ~ "40.000–60.000 USD",
sellingprice >= 60000 & sellingprice < 100000 ~ "60.000–100.000 USD",
sellingprice >= 100000 ~ "> 100.000 USD",
TRUE ~ NA_character_
)
)
bang_gia <- data %>%
group_by(Nhom_gia) %>%
summarise(
So_luong_xe = n(),
Gia_trung_binh = mean(sellingprice, na.rm = TRUE),
Gia_thap_nhat = min(sellingprice, na.rm = TRUE),
Gia_cao_nhat = max(sellingprice, na.rm = TRUE)
) %>%
arrange(Gia_trung_binh)
kable(bang_gia, caption = "Bảng phân tổ theo mức giá bán của xe")
| Nhom_gia | So_luong_xe | Gia_trung_binh | Gia_thap_nhat | Gia_cao_nhat |
|---|---|---|---|---|
| < 10.000 USD | 175481 | 5311.016 | 1e+00 | 9975 |
| 10.000–20.000 USD | 200976 | 14177.833 | 1e+04 | 19901 |
| 20.000–40.000 USD | 88089 | 25918.226 | 2e+04 | 39999 |
| 40.000–60.000 USD | 6484 | 46261.150 | 4e+04 | 59900 |
| 60.000–100.000 USD | 1143 | 72524.621 | 6e+04 | 99500 |
| > 100.000 USD | 152 | 125137.829 | 1e+05 | 230000 |
library(ggplot2)
ggplot(data, aes(x = odometer, y = sellingprice)) +
geom_point(alpha = 0.3, color = "steelblue") +
geom_smooth(method = "lm", color = "red") +
labs(
title = "Mối quan hệ giữa số km đã đi và giá bán xe",
x = "Số km đã đi (odometer)",
y = "Giá bán (USD)"
)
Biểu đồ cho thấy mối quan hệ nghịch chiều giữa số km đã đi và giá bán xe
— xe đi càng nhiều thì giá bán càng giảm. Điều này phản ánh giá trị xe
giảm dần theo mức độ hao mòn sử dụng. ## Mối quan hệ giữa năm sản xuất
(year) và giá bán (sellingprice)
ggplot(data, aes(x = factor(year), y = sellingprice)) +
geom_boxplot(fill = "lightblue", color = "darkblue") +
labs(
title = "Giá bán theo năm sản xuất của xe",
x = "Năm sản xuất",
y = "Giá bán (USD)"
)
## Mối quan hệ giữa tình trạng xe (condition) và giá bán
(sellingprice)
ggplot(data, aes(x = condition, y = sellingprice)) +
geom_boxplot(fill = "orange", color = "darkred") +
labs(
title = "Ảnh hưởng của tình trạng xe đến giá bán",
x = "Tình trạng xe",
y = "Giá bán (USD)"
)
## Mối quan hệ giữa hãng xe (make) và giá bán (sellingprice)
data_make <- data %>%
group_by(make) %>%
summarise(Gia_trung_binh = mean(sellingprice, na.rm = TRUE)) %>%
arrange(desc(Gia_trung_binh)) %>%
slice(1:10) # chỉ lấy top 10 hãng
ggplot(data_make, aes(x = reorder(make, Gia_trung_binh), y = Gia_trung_binh)) +
geom_col(fill = "skyblue") +
coord_flip() +
labs(
title = "Top 10 hãng xe có giá bán trung bình cao nhất",
x = "Hãng xe",
y = "Giá bán trung bình (USD)"
)
## Mối quan hệ giữa số km đã đi (odometer) và năm sản xuất (year)
ggplot(data, aes(x = year, y = odometer)) +
geom_point(alpha = 0.3, color = "darkgreen") +
geom_smooth(method = "lm", color = "red") +
labs(
title = "Mối quan hệ giữa năm sản xuất và số km đã đi",
x = "Năm sản xuất",
y = "Số km đã đi (odometer)"
)