📘 Buổi 1: Giới thiệu R và Tư duy thống kê trong phân tích dữ liệu

🎯 Mục tiêu của buổi học

  • Làm quen với R và RStudio: giao diện, thao tác cơ bản

  • Hiểu các kiểu dữ liệu cơ bản trong R

  • Biết cách cài đặt gói, đọc dữ liệu vào R

  • Nắm bắt khái niệm tư duy thống kê và vai trò trong phân tích dữ liệu

  • Tập trung xây nền tảng để triển khai mô hình thống kê trong các buổi sau


🧩 Nội dung chi tiết

1. Giới thiệu về R và RStudio

✅ R là gì?

  • Ngôn ngữ lập trình mã nguồn mở chuyên dùng cho thống kê, phân tích dữ liệu và trực quan hóa
  • Mạnh mẽ, mở rộng được với hàng ngàn thư viện (packages)

✅ RStudio là gì?

  • Giao diện phát triển (IDE) phổ biến nhất của R
  • Giúp bạn dễ dàng viết code, xem dữ liệu, biểu đồ, cài gói, xuất báo cáo…

🎯 Thực hành:


2. Kiểu dữ liệu cơ bản trong R

Loại dữ liệu Ví dụ Ghi chú
numeric 1.5, 10 Số thực
integer 1L, 100L Số nguyên
character “Hello”, “R” Chuỗi văn bản
logical TRUE, FALSE Boolean
factor Nhóm danh mục (Male, Female) Biến phân loại
vector, list, data.frame, tibble Cấu trúc dữ liệu nâng cao

🎯 Thực hành:

x <- 5            # numeric
y <- "R course"   # character
z <- TRUE         # logical

typeof(x)
class(x)

Ví dụ sử dụng các gói dplyr trong tidyverse


if (!require("tidyverse")) {


# Cài đặt gói

  install.packages("tidyverse", repos = "https://cloud.r-project.org")
}
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── 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
# nạp gói sử dụng

library(tidyverse)


# Thử dùng dplyr trong tidyverse
mtcars %>%
  group_by(cyl) %>%
  summarise(Số_lượng = n(),
            Trung_binh_mpg = mean(mpg))
## # A tibble: 3 × 3
##     cyl Số_lượng Trung_binh_mpg
##   <dbl>    <int>          <dbl>
## 1     4       11           26.7
## 2     6        7           19.7
## 3     8       14           15.1
if (!require("tidyverse")) {


# Cài đặt gói

  install.packages("tidyverse", repos = "https://cloud.r-project.org")
}



  ## 1.1 khởi chạy thư viện tidyverse 
library("tidyverse")

  
  ## Gọi thư viện ggplot, dplyr
  library(ggplot2) 
  library(dplyr)

  ##2 Đọc thử dữ liệu mẫu MPG
  mpg
## # A tibble: 234 × 11
##    manufacturer model      displ  year   cyl trans drv     cty   hwy fl    class
##    <chr>        <chr>      <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
##  1 audi         a4           1.8  1999     4 auto… f        18    29 p     comp…
##  2 audi         a4           1.8  1999     4 manu… f        21    29 p     comp…
##  3 audi         a4           2    2008     4 manu… f        20    31 p     comp…
##  4 audi         a4           2    2008     4 auto… f        21    30 p     comp…
##  5 audi         a4           2.8  1999     6 auto… f        16    26 p     comp…
##  6 audi         a4           2.8  1999     6 manu… f        18    26 p     comp…
##  7 audi         a4           3.1  2008     6 auto… f        18    27 p     comp…
##  8 audi         a4 quattro   1.8  1999     4 manu… 4        18    26 p     comp…
##  9 audi         a4 quattro   1.8  1999     4 auto… 4        16    25 p     comp…
## 10 audi         a4 quattro   2    2008     4 manu… 4        20    28 p     comp…
## # ℹ 224 more rows
  ## 2.1 Xem dưới dạng bảng
#View(mpg)
 head(mpg)
## # A tibble: 6 × 11
##   manufacturer model displ  year   cyl trans      drv     cty   hwy fl    class 
##   <chr>        <chr> <dbl> <int> <int> <chr>      <chr> <int> <int> <chr> <chr> 
## 1 audi         a4      1.8  1999     4 auto(l5)   f        18    29 p     compa…
## 2 audi         a4      1.8  1999     4 manual(m5) f        21    29 p     compa…
## 3 audi         a4      2    2008     4 manual(m6) f        20    31 p     compa…
## 4 audi         a4      2    2008     4 auto(av)   f        21    30 p     compa…
## 5 audi         a4      2.8  1999     6 auto(l5)   f        16    26 p     compa…
## 6 audi         a4      2.8  1999     6 manual(m5) f        18    26 p     compa…
##2.2 Đánh giá thống kê thông tin chung về bộ dữ liệu xe
summary(mpg)
##  manufacturer          model               displ            year     
##  Length:234         Length:234         Min.   :1.600   Min.   :1999  
##  Class :character   Class :character   1st Qu.:2.400   1st Qu.:1999  
##  Mode  :character   Mode  :character   Median :3.300   Median :2004  
##                                        Mean   :3.472   Mean   :2004  
##                                        3rd Qu.:4.600   3rd Qu.:2008  
##                                        Max.   :7.000   Max.   :2008  
##       cyl           trans               drv                 cty       
##  Min.   :4.000   Length:234         Length:234         Min.   : 9.00  
##  1st Qu.:4.000   Class :character   Class :character   1st Qu.:14.00  
##  Median :6.000   Mode  :character   Mode  :character   Median :17.00  
##  Mean   :5.889                                         Mean   :16.86  
##  3rd Qu.:8.000                                         3rd Qu.:19.00  
##  Max.   :8.000                                         Max.   :35.00  
##       hwy             fl               class          
##  Min.   :12.00   Length:234         Length:234        
##  1st Qu.:18.00   Class :character   Class :character  
##  Median :24.00   Mode  :character   Mode  :character  
##  Mean   :23.44                                        
##  3rd Qu.:27.00                                        
##  Max.   :44.00
  # 3. trực quan hóa dữ liệu

## 3.1 Đánh giá hiệu suất tiêu hao nguyên liệu và kích thước động cơ

plot(mpg$displ, mpg$hwy) 

#hoặc


ggplot(data = mpg) +    geom_point(mapping = aes(x= displ, y = hwy)) 

## 3.2 biểu đồ phân bổ hiệu suất tiêu hao nguyên liệu
hist(mpg$hwy)

## 3.3 Biểu đồ phân bổ theo số lượng hãng xe

# thống kê số hãng xe với hàm table
demhx <- table(mpg$manufacturer)

# Chuyển kết quả thành dataframe bảng dữ liệu
hx_df <- as.data.frame(demhx)



# đổi tên tiêu đề bảng dữ liệu
names(hx_df) <- c("Hang_xe", "So_luong")
hist(hx_df$So_luong) 

Các thao tác phổ biến

📘 Bài tập thực hành bổ sung

Thao tác cơ bản với dữ liệu có sẵn

📘Titanic: - Hành khách trên tàu Titanic

Tập dữ liệu Titanic chứa thông tin về hành khách trên tàu Titanic, bao gồm các biến như: Class (Hạng vé), Sex (Giới tính), Age (Độ tuổi: Trẻ em/Người lớn), Survived (Sống sót hay không), và Freq (Số lượng hành khách trong nhóm). Dữ liệu này có sẵn trong R dưới dạng bảng tần suất (table).

# Cài đặt tidyverse (nếu chưa có)
if (!require("tidyverse")) {
  install.packages("tidyverse", repos = "https://cloud.r-project.org")
}

# Nạp gói tidyverse
library(tidyverse) 


# Chuyển Titanic thành dataframe để dễ thao tác
titanic_df <- as.data.frame(Titanic)
head(titanic_df) # Xem 6 dòng đầu tiên
##   Class    Sex   Age Survived Freq
## 1   1st   Male Child       No    0
## 2   2nd   Male Child       No    0
## 3   3rd   Male Child       No   35
## 4  Crew   Male Child       No    0
## 5   1st Female Child       No    0
## 6   2nd Female Child       No    0
# thống kê tóm tắt dữ liệu
summary(titanic_df)
##   Class       Sex        Age     Survived      Freq       
##  1st :8   Male  :16   Child:16   No :16   Min.   :  0.00  
##  2nd :8   Female:16   Adult:16   Yes:16   1st Qu.:  0.75  
##  3rd :8                                   Median : 13.50  
##  Crew:8                                   Mean   : 68.78  
##                                           3rd Qu.: 77.00  
##                                           Max.   :670.00
# Tính tổng số hành khách theo giới tính
titanic_df %>%
  group_by(Sex) %>%
  summarise(Tổng_số = sum(Freq))
## # A tibble: 2 × 2
##   Sex    Tổng_số
##   <fct>    <dbl>
## 1 Male      1731
## 2 Female     470
# Tính tỉ lệ sống xót theo hạng vé

titanic_df %>%
  group_by(Class, Survived) %>%
  summarise(Tổng_số = sum(Freq)) %>%
  mutate(Tỷ_lệ = Tổng_số / sum(Tổng_số))
## `summarise()` has grouped output by 'Class'. You can override using the
## `.groups` argument.
## # A tibble: 8 × 4
## # Groups:   Class [4]
##   Class Survived Tổng_số Tỷ_lệ
##   <fct> <fct>      <dbl> <dbl>
## 1 1st   No           122 0.375
## 2 1st   Yes          203 0.625
## 3 2nd   No           167 0.586
## 4 2nd   Yes          118 0.414
## 5 3rd   No           528 0.748
## 6 3rd   Yes          178 0.252
## 7 Crew  No           673 0.760
## 8 Crew  Yes          212 0.240
# Khai thác dữ liệu với lọc và sắp xếp

# Lọc các bông hoa có chiều dài đài hoa lớn hơn 5
iris_lọc <- iris %>%
  filter(Sepal.Length > 5)
head(iris_lọc)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          5.4         3.9          1.7         0.4  setosa
## 3          5.4         3.7          1.5         0.2  setosa
## 4          5.8         4.0          1.2         0.2  setosa
## 5          5.7         4.4          1.5         0.4  setosa
## 6          5.4         3.9          1.3         0.4  setosa
# Sắp xếp kim cương theo giá giảm dần
diamonds_sắp_xếp <- diamonds %>%
  arrange(desc(price))
head(diamonds_sắp_xếp)
## # A tibble: 6 × 10
##   carat cut       color clarity depth table price     x     y     z
##   <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  2.29 Premium   I     VS2      60.8    60 18823  8.5   8.47  5.16
## 2  2    Very Good G     SI1      63.5    56 18818  7.9   7.97  5.04
## 3  1.51 Ideal     G     IF       61.7    55 18806  7.37  7.41  4.56
## 4  2.07 Ideal     G     SI2      62.5    55 18804  8.2   8.13  5.11
## 5  2    Very Good H     SI1      62.8    57 18803  7.95  8     5.01
## 6  2.29 Premium   I     SI1      61.8    59 18797  8.52  8.45  5.24
# Tạo cột mới: tỷ lệ chiều dài và chiều rộng đài hoa
iris <- iris %>%
  mutate(Tỷ_lệ_Sepal = Sepal.Length / Sepal.Width)
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species Tỷ_lệ_Sepal
## 1          5.1         3.5          1.4         0.2  setosa    1.457143
## 2          4.9         3.0          1.4         0.2  setosa    1.633333
## 3          4.7         3.2          1.3         0.2  setosa    1.468750
## 4          4.6         3.1          1.5         0.2  setosa    1.483871
## 5          5.0         3.6          1.4         0.2  setosa    1.388889
## 6          5.4         3.9          1.7         0.4  setosa    1.384615

📘Iris: - Hoa Lan

###Tập dữ liệu iris chứa thông tin về 150 bông hoa lan thuộc 3 loài (Species: Setosa, Versicolor, Virginica). Các biến bao gồm: Sepal.Length (Chiều dài đài hoa), Sepal.Width (Chiều rộng đài hoa), Petal.Length (Chiều dài cánh hoa), Petal.Width (Chiều rộng cánh hoa).

if(!require("tidyverse")){
  install.packages("tidyverse", repos = "https://cloud.r-project.org")
}
  
  library(tidyverse)

# xem dữ liệu 
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species Tỷ_lệ_Sepal
## 1          5.1         3.5          1.4         0.2  setosa    1.457143
## 2          4.9         3.0          1.4         0.2  setosa    1.633333
## 3          4.7         3.2          1.3         0.2  setosa    1.468750
## 4          4.6         3.1          1.5         0.2  setosa    1.483871
## 5          5.0         3.6          1.4         0.2  setosa    1.388889
## 6          5.4         3.9          1.7         0.4  setosa    1.384615
head(iris3)
## , , Setosa
## 
##      Sepal L. Sepal W. Petal L. Petal W.
## [1,]      5.1      3.5      1.4      0.2
## [2,]      4.9      3.0      1.4      0.2
## [3,]      4.7      3.2      1.3      0.2
## [4,]      4.6      3.1      1.5      0.2
## [5,]      5.0      3.6      1.4      0.2
## [6,]      5.4      3.9      1.7      0.4
## 
## , , Versicolor
## 
##      Sepal L. Sepal W. Petal L. Petal W.
## [1,]      7.0      3.2      4.7      1.4
## [2,]      6.4      3.2      4.5      1.5
## [3,]      6.9      3.1      4.9      1.5
## [4,]      5.5      2.3      4.0      1.3
## [5,]      6.5      2.8      4.6      1.5
## [6,]      5.7      2.8      4.5      1.3
## 
## , , Virginica
## 
##      Sepal L. Sepal W. Petal L. Petal W.
## [1,]      6.3      3.3      6.0      2.5
## [2,]      5.8      2.7      5.1      1.9
## [3,]      7.1      3.0      5.9      2.1
## [4,]      6.3      2.9      5.6      1.8
## [5,]      6.5      3.0      5.8      2.2
## [6,]      7.6      3.0      6.6      2.1
# tổng hợp
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species    Tỷ_lệ_Sepal   
##  setosa    :50   Min.   :1.268  
##  versicolor:50   1st Qu.:1.546  
##  virginica :50   Median :2.032  
##                  Mean   :1.954  
##                  3rd Qu.:2.225  
##                  Max.   :2.962
# Tính giá trị trung bình chiều dài đài hoa theo loài:
iris%>%
  group_by(Species) %>%
  summarise(do_dai_dai_hoa_TB = mean(Sepal.Length))
## # A tibble: 3 × 2
##   Species    do_dai_dai_hoa_TB
##   <fct>                  <dbl>
## 1 setosa                  5.01
## 2 versicolor              5.94
## 3 virginica               6.59
#Vẽ biểu đồ phân tán (scatter plot):
ggplot(iris, aes(x= Sepal.Length, y= Sepal.Width, color = Species)) + 
  geom_point() +
  labs((title = " Biểu đồ phân tán chiều dài và chiều rộng của đài hoa"))

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point() +
  labs(title = "Biểu đồ phân tán chiều dài và chiều rộng đài hoa")

📘Diamonds: Kim cương

###Tập dữ liệu diamonds (có sẵn trong gói ggplot2, thuộc tidyverse) chứa thông tin về 53,940 viên kim cương với các biến như: carat (Trọng lượng), cut (Chất lượng cắt), color (Màu sắc), clarity (Độ trong), price (Giá tiền), v.v.

 if(! require ("tidyverse")){
      install.pakages("tidyverse")
}
   library(tidyverse)

# Xem dạng bảng
#View(diamonds)

## Tóm tắt
summary(diamonds)
##      carat               cut        color        clarity          depth      
##  Min.   :0.2000   Fair     : 1610   D: 6775   SI1    :13065   Min.   :43.00  
##  1st Qu.:0.4000   Good     : 4906   E: 9797   VS2    :12258   1st Qu.:61.00  
##  Median :0.7000   Very Good:12082   F: 9542   SI2    : 9194   Median :61.80  
##  Mean   :0.7979   Premium  :13791   G:11292   VS1    : 8171   Mean   :61.75  
##  3rd Qu.:1.0400   Ideal    :21551   H: 8304   VVS2   : 5066   3rd Qu.:62.50  
##  Max.   :5.0100                     I: 5422   VVS1   : 3655   Max.   :79.00  
##                                     J: 2808   (Other): 2531                  
##      table           price             x                y         
##  Min.   :43.00   Min.   :  326   Min.   : 0.000   Min.   : 0.000  
##  1st Qu.:56.00   1st Qu.:  950   1st Qu.: 4.710   1st Qu.: 4.720  
##  Median :57.00   Median : 2401   Median : 5.700   Median : 5.710  
##  Mean   :57.46   Mean   : 3933   Mean   : 5.731   Mean   : 5.735  
##  3rd Qu.:59.00   3rd Qu.: 5324   3rd Qu.: 6.540   3rd Qu.: 6.540  
##  Max.   :95.00   Max.   :18823   Max.   :10.740   Max.   :58.900  
##                                                                   
##        z         
##  Min.   : 0.000  
##  1st Qu.: 2.910  
##  Median : 3.530  
##  Mean   : 3.539  
##  3rd Qu.: 4.040  
##  Max.   :31.800  
## 
##Tính trung bình theo chất lượng cut
diamonds %>%
  group_by(cut) %>%
  summarise(Gia_trungbinh = mean(price))
## # A tibble: 5 × 2
##   cut       Gia_trungbinh
##   <ord>             <dbl>
## 1 Fair              4359.
## 2 Good              3929.
## 3 Very Good         3982.
## 4 Premium           4584.
## 5 Ideal             3458.
## Biểu đồ giá theo trọng lượng carat
ggplot(diamonds, aes(x = carat, y= price, color = cut)) +
  geom_point() + 
  labs(title = "Giá kim cương theo trọng lượng carat")