Thống kê mô tả bằng R


Liên hệ:


Bài này có sử dụng kiến thức vẽ biểu đồ bằng ggplot2, nếu bạn chưa có kiến thức về ggplot2 có thể xem lại ở đây.


Thư viện cần thiết

Nếu chưa cài package pacman, bạn dùng lệnh install.packages("pacman")

pacman::p_load(tidyverse, janitor, psych, crosstable, flextable)

Trong đó:

  • tidyverse: giúp biến đổ số liệu tốt hơn.
  • janitor: giúp tính số lượng và tỷ lệ % nhanh hơn.
  • psych: giúp phân tích mô tả cho biến định lượng.
  • crosstable: giúp kẻ bảng tương quan.
  • flextable: giúp xuất output ra dưới dạng html, dễ đọc hơn trên console.

Data mẫu sử dụng

df = ggplot2::mpg
head(df)
## # 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…

Thống kê mô tả cho biến định tính (categorical)

Ví dụ biến số manufacturer trong dataset trên là tên các hãng xe/nhà sản xuất. Đây là ví dụ về biến định tính.

Những thống kê áp dụng cho 01 biến định tính có thể là:

  • Số lượng
  • Tỷ lệ (%)
  • Biểu đồ cột
  • Biểu đồ quạt (ít dùng)

Số lượng, tỷ lệ

Package janitor cung cấp hàm tabyl() giúp ta có thể tính cả 2 giá trị này cùng một lúc như sau:

tabyl(df$manufacturer)
##  df$manufacturer  n    percent
##             audi 18 0.07692308
##        chevrolet 19 0.08119658
##            dodge 37 0.15811966
##             ford 25 0.10683761
##            honda  9 0.03846154
##          hyundai 14 0.05982906
##             jeep  8 0.03418803
##       land rover  4 0.01709402
##          lincoln  3 0.01282051
##          mercury  4 0.01709402
##           nissan 13 0.05555556
##          pontiac  5 0.02136752
##           subaru 14 0.05982906
##           toyota 34 0.14529915
##       volkswagen 27 0.11538462

Thử chuyển tỷ lệ sang % và thay đổi format dễ nhìn hơn một chút:

ket_qua = tabyl(df$manufacturer)

tibble(
  'Hãng xe' = ket_qua$`df$manufacturer`, 
  'Số lượng' = ket_qua$n,
  'Tỷ lệ' = paste(round(ket_qua$percent*100, 2), '%') # Chuyển đổi tỷ lệ sang tỷ lệ %
      ) %>% 
  arrange(desc(`Số lượng`)) %>% # Sắp xếp bảng theo thứ tự giảm dần
  flextable() # Xuất output ra ở định dạng html

Biểu đồ

Biểu đồ cột

df %>% 
  ggplot(aes(x = manufacturer, fill = manufacturer)) +
  geom_bar() +
  coord_flip() + # dùng biểu đồ cột ngang thay vì cột dọc
  theme(legend.position="none") + # Ẩn chú thích không cần thiết đi
  xlab('Hãng xe') +
  ylab('Số lượng')

Chúng ta nên sử dụng biểu đồ cột ngang trong trường hợp này vì có rất nhiều nhóm nhỏ.

Biểu đồ quạt ít dùng, nhưng nếu bạn muốn dùng có thể thử lệnh sau

df %>% 
  select(manufacturer) %>% 
  group_by(manufacturer) %>% 
  count() %>% 
  arrange(desc(n)) %>% # Sắp xếp các hãng xe theo thứ tự giảm dần
  ggplot(aes(x="", y=n, fill=manufacturer)) +
  geom_bar(stat="identity", width=1) +
  coord_polar("y", start=0) + 
  labs(fill = "Hãng xe") + # Đổi tên chú thích
  theme_void() # Bỏ bớt các giá trị thừa

Thống kê mô tả cho biến định lượng (continuous)

Biến displ trong dataset trên là một biến định lượng. Ta sẽ tiến hành phân tích trên biến này.

Các thông kê mô tả thường sử dụng cho biền định lượng là:

  • Trung bình
  • Trung vị
  • Độ lệch chuẩn
  • Min, Max
  • Skewness, Kurtosis

Các chỉ số trên có thể dùng hàm describe() trong package psych để tính toán:

describe(df$displ)
##    vars   n mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 234 3.47 1.29    3.3    3.39 1.33 1.6   7   5.4 0.44    -0.91 0.08

Biểu đồ thường dùng trong mô tả biến liên tục là histogramboxplot

# Histogram
df %>% 
  ggplot(aes(x=displ)) +
  geom_histogram(aes(y = ..density..)) +
  geom_density() # Vẽ thêm đường cong tỷ trọng.

Nhìn qua phân bố trên, ta có thể kết luận biến displ không có phân bố chuẩn.

# Boxplot
df %>% 
  ggplot(aes(x=displ)) +
  geom_boxplot()

Bạn có thể xem lại boxplot tại đây

Gộp biến liên tục thành các khoảng (biến thứ hạng - ordinal)

Đây là thao tác gộp các khoảng của biến liên tục thành các nhóm (biến thứ hạng) để tiến hành mô tả như biến định tính.

Ví dụ ta nhóm biến tuổi thành nhiều nhóm khác nhau như 0-18; 18-45 và >45 tuổi chẳng hạn.

Ta sẽ thực hành trên biến hwy trong dataset trên.

Cách 1: dùng hàm cut()

Hàm cut() giúp “cắt” biến liên tục thành nhiều khoảng.

Đầu tiên ta xem giới hạn min, max của biến hwy trước

describe(df$hwy)
##    vars   n  mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 234 23.44 5.95     24   23.23 7.41  12  44    32 0.36     0.14 0.39

Như vậy, biến hwy dao động từ 12 đến 44 Giả sử ta phân nhóm ra thành các khoảng 12-20; 20-3030-44:

cut(df$hwy, 
    breaks = c(12, 20, 30, 44),  # Các khoảng chia
    include.lowest = T) %>%  # Lấy giá trị nhỏ nhất
  tabyl()
##        .   n    percent
##  [12,20]  89 0.38034188
##  (20,30] 123 0.52564103
##  (30,44]  22 0.09401709

Cách 2: dùng case_when() trong package dplyr

Đây là cách sử dụng các mệnh đề điều kiện để phân khoảng. Không những có thể chia khoảng cho biến liên tục mà còn có thể nhóm các biến định tính (categorical)

case_when(
    df$hwy <=20 ~ '[12,20]',
    df$hwy > 20 & df$hwy <= 30 ~ '(20,30]',
    df$hwy > 30 ~ '(30,44]'
) %>% 
  tabyl()
##        .   n    percent
##  (20,30] 123 0.52564103
##  (30,44]  22 0.09401709
##  [12,20]  89 0.38034188

Thống kê mô tả cho 2 biến số

Đây là khi ta mô tả mối quan hệ giữa 2 biến.

02 biến định tính

Cách mô tả hợp lý nhất cho 2 biến định tính là dùng bảng tương quan (contingency table hay cross table, crosstab) bằng hàm crosstable().

Ví dụ: ta thử mô tả 2 biến yearclass trong dataset trên:

crosstable(df, class, by = year) %>% 
  as_flextable() # Thử chuyển output sang định dạng html

Ta có thể sử dụng biến thể của biểu đồ phân tán để minh họa số liệu trong trường hợp 2 biến định tính.

df %>% 
  ggplot(aes(x = class, y = model)) +
  geom_count()

01 biến định tính + 01 biến định lượng

Trường hợp này ta mô tả biến định lượng (trung bình, min, max,…) theo biến định tính (biến phân nhóm)

Ví dụ: ta mô tả biến hwy theo year:

describeBy(df$hwy, group = df$year)
## 
##  Descriptive statistics by group 
## group: 1999
##    vars   n  mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 117 23.43 6.08     25   23.04 5.93  15  44    29 0.67     0.86 0.56
## ------------------------------------------------------------ 
## group: 2008
##    vars   n  mean   sd median trimmed  mad min max range skew kurtosis   se
## X1    1 117 23.45 5.85     24   23.44 7.41  12  37    25 0.02    -0.77 0.54

Biểu đồ trong trường hợp này có nhiều loại tùy thuộc mục đích sử dụng của chúng ta. Ví dụ ta muốn so sánh phân bố của hwy giữa 2 nhóm, ta có thể sử dụng boxplot chẳng hạn.

  ggplot(data = df) +
  geom_boxplot(aes(x = factor(year), y = hwy)) +
  xlab('years')

02 biến định lượng

Ta có thể mô tả 2 biến định lượng bằng hệ số tương quan. Hoặc gộp biến định lượng thành biến định tính rối làm như trên.

Ví dụ ta mô tả 2 biến ctyhwy

cor(df$cty, df$hwy)
## [1] 0.9559159
# cor.test(df$cty, df$hwy) để kiểm định hệ số tương quan

r = 0.956, tương quan giữa ctyhwy là rất mạnh.

Biểu đồ sử dụng trong trường hợp này là biểu đồ phân tán ± phương trình hồi quy:

df %>% 
  ggplot(aes(x = cty, y = hwy)) +
  geom_point() +
  geom_smooth(method = 'lm') # Sử dụng mô hình hồi quy tuyến tính
## `geom_smooth()` using formula 'y ~ x'


Hết phần thống kê mô tả cơ bản!