1. Giới thiệu

Báo cáo này trình bày các thao tác phân tích dữ liệu trên bộ dữ liệu nhóm chọn, gồm:
- Thông tin cơ bản về dữ liệu dữ liệu được tạo ra từ một loạt gồm ba hệ thống cảm biến (sensor arrays) giống hệt nhau, được xây dựng tùy chỉnh trên bảng mạch thử nghiệm (breadboard). Mỗi hệ thống cảm biến được kết nối với một thiết bị Raspberry Pi. Mỗi thiết bị IoT (Internet of Things) này được đặt tại một vị trí vật lý với các điều kiện môi trường khác nhau - Phân tích 10 biến

2. Thông tin cơ bản về dữ liệu

2.1 Số biến và số quan sát

library(readxl)
d <- read.csv("C:/Users/HP/OneDrive/HOC HANH/iot_telemetry_data.csv")
View(d) 

2.1.1 tổng quan dữ liệu

str(d)
## 'data.frame':    405184 obs. of  9 variables:
##  $ ts      : num  1.59e+09 1.59e+09 1.59e+09 1.59e+09 1.59e+09 ...
##  $ device  : chr  "b8:27:eb:bf:9d:51" "00:0f:00:70:91:0a" "b8:27:eb:bf:9d:51" "1c:bf:ce:15:ec:4d" ...
##  $ co      : num  0.00496 0.00284 0.00498 0.0044 0.00497 ...
##  $ humidity: num  51 76 50.9 76.8 50.9 ...
##  $ light   : chr  "false" "false" "false" "true" ...
##  $ lpg     : num  0.00765 0.00511 0.00767 0.00702 0.00766 ...
##  $ motion  : chr  "false" "false" "false" "false" ...
##  $ smoke   : num  0.0204 0.0133 0.0205 0.0186 0.0204 ...
##  $ temp    : num  22.7 19.7 22.6 27 22.6 ...

2.1.2 số biến

ncol(d)
## [1] 9

2.1.3 số quan sát

nrow(d)
## [1] 405184

##2.1.4 tổng quan về dữ liệu

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.1     ✔ stringr   1.5.2
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
glimpse(d)
## Rows: 405,184
## Columns: 9
## $ ts       <dbl> 1594512094, 1594512095, 1594512098, 1594512100, 1594512102, 1…
## $ device   <chr> "b8:27:eb:bf:9d:51", "00:0f:00:70:91:0a", "b8:27:eb:bf:9d:51"…
## $ co       <dbl> 0.004955939, 0.002840089, 0.004976012, 0.004403027, 0.0049673…
## $ humidity <dbl> 51.0, 76.0, 50.9, 76.8, 50.9, 77.9, 50.9, 76.0, 77.9, 50.9, 5…
## $ light    <chr> "false", "false", "false", "true", "false", "true", "false", …
## $ lpg      <dbl> 0.007650822, 0.005114383, 0.007673227, 0.007023337, 0.0076635…
## $ motion   <chr> "false", "false", "false", "false", "false", "false", "false"…
## $ smoke    <dbl> 0.02041127, 0.01327484, 0.02047513, 0.01862823, 0.02044762, 0…
## $ temp     <dbl> 22.7, 19.7, 22.6, 27.0, 22.6, 27.0, 22.6, 19.7, 27.0, 22.6, 2…

##2.1.5 kiem tra missing value

sum(is.na(d))
## [1] 0

##2.1.6 kiem tra so quan sát trung lập

sum(duplicated(d))
## [1] 13

##2.1.7 kiểm tra cụ thể vị trí xuất hiện quan sát trùng lập

d[duplicated(d),""]
## NULL

liệu kê bao nhiêu biến trùng lặp ở cột device

unique(d$device)
## [1] "b8:27:eb:bf:9d:51" "00:0f:00:70:91:0a" "1c:bf:ce:15:ec:4d"
##2 thay doi 3 loai device thanh 3 ten khac "thiet bi 1" thiet bi 2" "thiet bi 3"
d$device <- ifelse(d$device == "b8:27:eb:bf:9d:51", "Thiết bị 1",
                     ifelse(d$device == "00:0f:00:70:91:0a", "Thiết bị 2",
                            ifelse(d$device == "1c:bf:ce:15:ec:4d", "Thiết bị 3", 
                            d$device)))

3.Data cleaning

3.1 tinh gia tri sum , mean , max , min

library(dplyr)
library(tidyr)
stats_frame <- d %>%
  summarise(across(where(is.numeric),
                   list(
                     Tong = ~sum(., na.rm = TRUE),
                     Trung_binh = ~mean(., na.rm = TRUE),
                     Max = ~max(., na.rm = TRUE),
                     Min = ~min(., na.rm = TRUE)
                   ))) %>%
  pivot_longer(everything(),
               names_to = c("Bien", "Thong_ke"),
               names_sep = "_") %>%
  pivot_wider(names_from = "Thong_ke", values_from = "value") %>%
  mutate(across(where(is.numeric), ~round(., 2)))
## Warning: Expected 2 pieces. Additional pieces discarded in 6 rows [2, 6, 10, 14, 18,
## 22].
cat("=== FRAME THỐNG KÊ - FILE d ===\n")
## === FRAME THỐNG KÊ - FILE d ===
print(stats_frame)
## # A tibble: 6 × 5
##   Bien        Tong         Trung           Max           Min
##   <chr>      <dbl>         <dbl>         <dbl>         <dbl>
## 1 ts       6.46e14 1594858017.   1595203417.   1594512094.  
## 2 co       1.88e 3          0             0.01          0   
## 3 humidity 2.45e 7         60.5          99.9           1.1 
## 4 lpg      2.93e 3          0.01          0.02          0   
## 5 smoke    7.81e 3          0.02          0.05          0.01
## 6 temp     9.10e 6         22.4          30.6           0

3.2 Tao cot moi lay du lieu tu cot CO

d <- d %>%
  mutate(chat_luong = case_when(
    co < 0.002 ~ "Rất sạch",
    co >= 0.002 & co < 0.004 ~ "Sạch",
    co >= 0.004 & co < 0.005 ~ "Trung bình",
    co >= 0.005 ~ "ô nhiễm",  # Xử lý các giá trị >= 0.005
    TRUE ~ "Không xác định"  # Xử lý NA hoặc giá trị không hợp lệ
  ))
library(ggplot2)

4.1 Histogram với humidity

ggplot(d, aes(x = humidity)) +
  geom_histogram(binwidth = 5, fill = "steelblue", color = "white", alpha = 0.8) +
  labs(title = "Phân phối Độ ẩm",
       subtitle = "Histogram của cột Humidity",
       x = "Độ ẩm (%)",
       y = "Tần số") +
  theme_minimal()

## 4.2 Pie chart voi light

library(ggplot2)
library(dplyr)

4.2.1 Tạo data frame cho biểu đồ

light_data <- d %>%
  count(light) %>%
  mutate(light_label = ifelse(light, "Có ánh sáng", "Không có ánh sáng"),
         percentage = n / sum(n) * 100,
         label = paste0(light_label, "\n", n, " (", round(percentage, 1), "%)"))

4.2.1 Kiểm tra toàn diện trước khi vẽ

cat("=== KIỂM TRA TOÀN DIỆN ===\n")
## === KIỂM TRA TOÀN DIỆN ===

4.2.1 Kiểm tra object

cat("1. Class của d:", class(d), "\n")
## 1. Class của d: data.frame
cat("2. Is data frame?", is.data.frame(d), "\n")
## 2. Is data frame? TRUE
cat("3. Dimensions:", if(!is.null(dim(d))) dim(d) else "No dimensions", "\n")
## 3. Dimensions: 405184 10
cat("4. Length:", length(d), "\n")
## 4. Length: 10
cat("5. Names:", names(d), "\n")
## 5. Names: ts device co humidity light lpg motion smoke temp chat_luong
cat("6. Có cột 'light'?", "light" %in% names(d), "\n")
## 6. Có cột 'light'? TRUE
if ("light" %in% names(d)) {
  cat("7. Class của light:", class(d$light), "\n")
  cat("8. Số lượng TRUE:", sum(d$light == TRUE, na.rm = TRUE), "\n")
  cat("9. Số lượng FALSE:", sum(d$light == FALSE, na.rm = TRUE), "\n")
  cat("10. Số lượng NA:", sum(is.na(d$light)), "\n")}
## 7. Class của light: character 
## 8. Số lượng TRUE: 0 
## 9. Số lượng FALSE: 0 
## 10. Số lượng NA: 0

4.2.1 Fix và vẽ biểu đồ

if (!is.data.frame(d)) {
  d <- as.data.frame(d)
  cat("\nĐã chuyển đổi thành data frame\n")
}

4.2.2 Vẽ biểu đồ tròn (luôn hoạt đông)

pie(table(d$light), 
    main = "Phân phối Light",
    col = c("red", "green"),
    labels = c("FALSE", "TRUE"))

## 4.3 Tạo ma trân tương quan giữa 10 biến ## 4.3.1 Tạo ma trân tương quan giữa 10 biến

library(ggplot2)
library(reshape2)
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths

4.3.2 Chọn 10 biến số

numeric_vars <- names(d)[sapply(d, is.numeric)]
selected_vars <- numeric_vars[1:min(10, length(numeric_vars))]

4.3.3 Tính ma trận tương quan

cor_matrix <- cor(d[selected_vars], use = "complete.obs")

4.3.4 chuyển thành data frame dài

cor_melted <- melt(cor_matrix)
names(cor_melted) <- c("Var1", "Var2", "Correlation")

4.3.5 Heat map với ggplot2

ggplot(cor_melted, aes(x = Var1, y = Var2, fill = Correlation)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Correlation, 2)), color = "black", size = 3) +
  scale_fill_gradient2(low = "blue", high = "red", mid = "white", 
                       midpoint = 0, limit = c(-1, 1), space = "Lab",
                       name = "Tương quan") +
  labs(title = "Heat Map Ma trận Tương quan",
       x = "", y = "") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5, face = "bold"))

## 4.4 Scatter plot về các biến co , lgp , ts , smoke

data <- data.frame(
  co = rnorm(100, mean = 50, sd = 10),
  lbg = rnorm(100, mean = 30, sd = 5),
  ts = rnorm(100, mean = 70, sd = 15),
  smoke = sample(c("Yes", "No"), 100, replace = TRUE)
)

4.4.1 Biểu đồ phân tán với ggplot2

library(ggplot2)

ggplot(data, aes(x = co, y = lbg, color = smoke, size = ts)) +
  geom_point(alpha = 0.7) +
  labs(
    title = "Scatter Plot of co vs lbg",
    x = "CO Levels",
    y = "LBG Levels",
    color = "Smoking Status",
    size = "TS Levels"
  ) +
  theme_minimal()

  library(knitr)

4.5 Vẽ biểu đồ Histogram