1 Giới thiệu.

Làm sạch và biến đổi dữ liệu là bước quan trọng nhất trong phân tích dữ liệu, nó chiếm đến 90% trong thời gian phân tích, việc biến đổi dữ liệu và phân tích là 2 quá trình diễn ra song song và tuần hoàn khép kín, là quá trình thử chọn diễn ra liên tục khi người phân tích đạt được kết quả phù hợp với thực tiễn và mong muốn. Hình mình họa cho quá trình biến đổi dữ liệu và phân tích:

2 Giới thiệu về toán tử Pipe operator.

Ngoài cách viết code bằng phương pháp thuần túy thông thường đó là viết hàm lồng (nested) tức là khi đọc code chúng ta sẽ đọc kết quả từ trong ra ngoài, khi sử dụng quá nhiều () trong 1 câu code dễ dẫn đến việc không hiểu ý tưởng của tác giả muốn truyền đạt là gì, thì trong gói dplyr đã giới thiệu cách viết code mới có thể gọi là để trả về kết quả mong muốn, không những thế nó còn giúp cho người viết code và người sử dụng code hiểu được thông tin mà tác giả muốn truyền đạt. Đó chính là cách viết code có thứ tự Pipe operator ( %>% ) . Cách đọc code cũng khác đó là đọc thông tin từ trái qua phải 1 cách có thứ tự, kết quả của về trái tử Pipe là yếu tố đầu vào cho vế bên phải của toán tử.
Trong bài viết này chủ yếu sẽ sử dụng cách viết này trong việc biến đổi dữ liệu.

  • %>% : Sử dụng tổ hợp phím: Ctrl + Shift + m

3 Biến đổi dữ liệu với dplyr.

Trong phần này chúng ta sẽ sử dụng những bộ dữ liệu có sẵn trong R để thực hành: mtcars, iris, ….

Trước hết để thực hiện biến đổi dữ liệu với package: dplyr thì cần 1 số những thủ tục sau:

  • Bước 1: Máy tính cần cài đặt R: Link R.

  • Bước 2: Máy tính cần cài đặt R -studio hỗ trợ: Link R studio.

  • Bước 3: Cài đặt package dplyr gõ lệnh này trong R studio : install.packages(“dplyr”).

  • Bước 4: Sau khi cài đặt, để làm việc với gói này: library(dplyr).

3.1 Một số hàm cơ bản.

3.1.1 Tạo mẫu dữ liệu - subset data.

3.1.1.1 Lọc dữ liệu với hàm filter().

Trong phân tích và báo cáo việc tạo các mẫu quan sát nhỏ để tính toán cũng như phân tích là vô cùng quan trọng để giúp người làm phân tích tìm ra đặc điểm riêng của các nhóm, để từ đó có những chính sách riêng đối với mỗi thông tin được tìm ra cho từng nhóm.

mtcars %>% 
  filter(am == "1")
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 5  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 6  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 7  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 8  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 9  30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 10 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 11 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 12 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 13 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Ví dụ trên chỉ là ví dụ lọc có điều kiện với 1 yếu tố, nếu chúng ta có nhiều điều kiện Đồng thời:& và điều kiện Hoặc:|.

  • Ví dụ: Lấy danh sách những hãng oto mà có am == 1 và gear ==4. Kết quả:
mtcars %>% 
  filter(am == 1 &
           gear == 4)
##    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 5 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 6 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 7 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 8 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
  • Ví dụ: Lấy danh sách những hãng oto mà có am == 1 hoặc gear ==4. Kết quả:
mtcars %>% 
  filter(am == 1 |
           gear == 4)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 5  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 6  19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 7  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 8  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 9  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 10 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 11 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 12 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 13 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 14 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 15 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 16 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 17 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

3.1.1.2 Lọc các giá trị giống nhau với hàm distinct().

  • Ngoài việc sử dụng hàm filter để tạo ra các subset nhỏ thì hàm distinct() cũng là một họ thuộc nhánh này, tuy nhiên, nó cho chúng ta thông tổng quá hơn cho 1 trường dữ liệu cụ thể. Xét ví dụ trong tập dữ liệu iris, chúng ta có 150 bông hoa, để biết chúng thuộc những họ nào thì hàm distinct() sẽ giúp chúng ta.
iris %>% 
  distinct(Species)
##      Species
## 1     setosa
## 2 versicolor
## 3  virginica
  • Kết quả trả ra, ứng với 150 loại hoa chúng thuộc 3 họ là: setosa, versicolor, virginica.

  • Hàm này ứng dụng trong ngân hàng đó là xem có bao nhiều khách hàng có giái ngân trong 1 khoảng thời gian, xem chiếm bao nhiều % danh mục khách hàng có giải ngân, từ đó giúp kinh doanh đưa ra chính sách Marketing để nhằm thu hút thêm khách hàng giải ngân từ đó tạo lợi nhuận cho ngân hàng.

3.1.1.3 Lấy các dòng theo thứ tự với hàm slice().

  • Gần giống với hàm head() trong R base thì trong dplyr giới thiệu hàm slide() lấy các dòng theo vị trí cho trước. Ví dụ ta muốn lấy các loại oto thuộc dòng từ 3:15
mtcars %>% 
  slice(3:15)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 2  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 3  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 4  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 5  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 6  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 7  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 8  19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 9  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 10 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 11 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 12 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 13 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4

3.1.1.4 Một số hàm lấy subset cơ bản khác.

  • Ngoài những hàm filter(), distinct() và slice() hay được sử dụng trong thực tế thì dplyr còn giới thiệu về các hàm để lấy subset như:
Tên hàm Ý nghĩa
sample_frac() lấy mẫu ngẫu nhiên theo 1 tỷ lệ cho trước
sample_n lấy ngẫu nhiên n dòng
top_n lấy và sắp xếp thứ tự theo n dòng đầu tiên
  • Những hàm như sample_frac() và hàm sample_n() này thường sẽ được ứng dụng để chia tập training và testing ứng dụng trong data mining - sẽ được giới thiệu trong những phần tiếp theo.

3.1.2 Sắp xếp dữ liệu với hàm arrange()

  • Trong phân tích và biến đổi dữ liệu để thực hiện sắp xếp dữ liệu theo 1 chiều nhất định là rất cần thiết, trong dplyr có giới thiệu hàm arrange() để sắp xếp dữ liệu.

Ví dụ:

- Ta sắp xếp mpg từ lớn đến bé của các loại xe trong bộ mtcars.
mtcars %>% 
  arrange(mpg %>% desc())
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 2  32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 3  30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 4  30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 5  27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 6  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 7  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 8  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 11 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 12 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## 13 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 14 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 15 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 16 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 17 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 18 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 19 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 20 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 21 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 22 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 23 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 24 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 25 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 26 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 27 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 28 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 29 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 30 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 31 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 32 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
- Ta sắp xếp mpg từ bé đến lớn của các loại xe trong bộ mtcars.
mtcars %>% 
  arrange(mpg)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## 2  10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## 3  13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## 4  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 5  14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## 6  15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 7  15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## 8  15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## 9  15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## 10 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 11 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 12 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## 13 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 14 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 15 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 16 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 17 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## 18 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 19 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 20 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 21 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 22 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## 23 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## 24 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 25 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 26 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 29 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 30 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 31 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 32 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1

3.1.3 Thêm trường thông tin mới - biến mới với hàm mutate().

  • Ngoài việc phải tạo các subset để thuận tiện cho việc phân tích, báo cáo, thì tùy theo yêu cầu cụ thể mà người phân tích cần phải tạo thêm những trường thông mới theo business rule, hoặc theo các logic có trước để thuận lợi cho việc tìm insign khách hàng từ những trường thông tin có sẵn. Thì trong dplyr giới thiệu hàm mutate() để thực hiện công việc này.

  • Ví dụ, nhóm tuổi khách hàng có ảnh hưởng tới doanh số giải ngân vay tín chấp. Với những người từ nhóm 18 - 30 tuổi khả năng vay tín chấp cao hơn nhóm nhóm tuổi từ trên 30 tuổi. Từ đây, để thuận tiện cho việc tính toán ta cần phải tạo ra 1 biến mới từ biến tuổi cho trước.

  • Phần này ta sẽ sử dụng bộ sữ liệu mtcars để thực hiện việc tạo 1 biến mới tên là mpg_id, nhận 2 giá trị lower: mpg <= 16 và higher: mpg >16

mtcars %>% 
  mutate(mpg_id = ifelse(mpg <= 16,"Lower","Higher"))
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb mpg_id
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 Higher
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 Higher
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 Higher
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 Higher
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 Higher
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 Higher
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4  Lower
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 Higher
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 Higher
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 Higher
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4 Higher
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3 Higher
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 Higher
## 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3  Lower
## 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4  Lower
## 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4  Lower
## 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4  Lower
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1 Higher
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2 Higher
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1 Higher
## 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 Higher
## 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2  Lower
## 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2  Lower
## 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4  Lower
## 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2 Higher
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1 Higher
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2 Higher
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2 Higher
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4  Lower
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6 Higher
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8  Lower
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2 Higher

3.1.4 Tổng hợp các chỉ tiêu tính toán với hàm group_by và summmarise()

  • Trong thực tế, khi phân tích và báo cáo để có cái nhìn tông quan về các thông tin về khách hàng nhiều khi chúng ta cần phải tổng hợp dữ liệu như tính tổng doanh số giải ngân khách hàng, trung bình giải ngân khách hàng , xem sự biến động về doanh số giải ngân của từng khách hàng ta cần tínhphương sai và độ lệch chuẩn về doanh số giải ngân, thì trong dplyr có giới thiệu hàm summaries() để thực hiện công việc này.

  • Ví dụ, với gọi mtcars chúng ta sẽ thực hiện một số chỉ tiêu của các loại oto.

mtcars %>% 
  summarise(mean = mean(mpg),
            max = max(mpg),
            min = min(mpg))
##       mean  max  min
## 1 20.09062 33.9 10.4
  • Ví dụ là một ví dụ đơn giản để tổng hợp một số chỉ tiêu, tuy nhiên khi kết hợp hàm summaries() với hàm group_by() trong dplyr sẽ cho chúng ta có một cái nhìn đa chiều hơn và nhiều thông tin hơn. Hàm group_by() sẽ giúp chúng ta tổng hợp tính toán các chỉ tiêu dữ liệu theo các trường thông tin khách nhau, ví dụ phía trên chỉ cho biết thông tin về mean, min và max của chỉ tiêu của toàn bộ các loại oto, tuy nhiên chúng ta cần xem xét mean, max, min của từng nhóm oto. ( nhóm oto mà Transmission(0 = automatic, 1 = manual)) để có sự so sanh và từ đó đưa ra những quyết định với từng nhóm.
mtcars %>% 
  group_by(am) %>% 
  summarise(mean = mean(mpg),
            max = max(mpg),
            min = min(mpg))
## # A tibble: 2 x 4
##      am     mean   max   min
##   <dbl>    <dbl> <dbl> <dbl>
## 1     0 17.14737  24.4  10.4
## 2     1 24.39231  33.9  15.0
  • Rõ ràng ở đây ta thấy rằng, nhóm oto mà transmission = 1 là tiêu tốn xăng hơn so với nhóm oto mà transmisstion = 0, với những người mà có nhu cầu mua xe tiết kiệm xăng thì rõ rằng đối tượng họ nhắm đến là nhóm oto mà transmission = 0. Đây chỉ là 1 ví dụ đơn giản về quyết định dụa trên 1 số chỉ tiêu thống kê, thực tế còn nhiều yếu tố khác để khách hàng ra quyết định cuối cùng như, loại xe, thị hiếu, giá cả,…..

3.1.5 Một số hàm nâng cao

3.1.5.1 Nối các trường thông tin dữ liệu từ các bảng khác nhau.

3.1.5.1.1 Hàm inner_join
  • Giả sử chúng ta cần gộp 2 bảng dữ liệu x và y, các hàm để gộp 2 bảng dữ liệu sẽ như sau:

  • Bảng x:

x <- data.frame(`StudentID` = seq(1, 10, 1), maths = c(10, 8, 7, 6, 7.8, 4, 7.7, 9, 9.5, 6.5))
x %>% 
  head()
##   StudentID maths
## 1         1  10.0
## 2         2   8.0
## 3         3   7.0
## 4         4   6.0
## 5         5   7.8
## 6         6   4.0
  • Bảng y:
y <- data.frame(`StudentID` = seq(2, 20, 2), physics = c(8, 9.5, 7.5, 6, 5.5, 6.5, 7.8, 8.2, 8, 7.5))
y %>% 
  head()
##   StudentID physics
## 1         2     8.0
## 2         4     9.5
## 3         6     7.5
## 4         8     6.0
## 5        10     5.5
## 6        12     6.5
  • Hàm inner_join(x, y…): được xử dụng để lấy tất cả dữ liệu chỉ có trên bảng x và y, ví dụ:
x %>%
  inner_join(y, by = "StudentID") # gộp 2 bảng dữ liệu x và y, dùng trường StudentID để map 2 bảng với nhau, lấy các dòng dữ liệu mà 2 bảng cùng có.
##   StudentID maths physics
## 1         2   8.0     8.0
## 2         4   6.0     9.5
## 3         6   4.0     7.5
## 4         8   9.0     6.0
## 5        10   6.5     5.5
3.1.5.1.2 Hàm full_join
  • Hàm full_join(x, y…): lấy dữ liệu có cả trên bảng x, y, ví dụ:
x %>%
  full_join(y, by = "StudentID") # gộp 2 bảng dữ liệu a và b, dùng trường StudentID để map 2 bảng với nhau, lấy tất cả dữ liệu của 2 bảng
##    StudentID maths physics
## 1          1  10.0      NA
## 2          2   8.0     8.0
## 3          3   7.0      NA
## 4          4   6.0     9.5
## 5          5   7.8      NA
## 6          6   4.0     7.5
## 7          7   7.7      NA
## 8          8   9.0     6.0
## 9          9   9.5      NA
## 10        10   6.5     5.5
## 11        12    NA     6.5
## 12        14    NA     7.8
## 13        16    NA     8.2
## 14        18    NA     8.0
## 15        20    NA     7.5
  • Các giá trị về điểm toán (maths) sẽ trả về NA cho các StudentID không tồn tại trên bảng y và ngược lại cho bảng x với các giá trị điểm vật lý (physics) của các StudentID không tồn tại trên bảng x.
3.1.5.1.3 Hàm left_join
  • Hàm left_join(x, y…): lấy dữ liệu chỉ có trên bảng x, ví dụ:
x %>%
  left_join(y, by = "StudentID") # gộp 2 bảng dữ liệu x và y, dùng trường StudentID để map 2 bảng với nhau, chỉ lấy dữ liệu có trên bảng x
##    StudentID maths physics
## 1          1  10.0      NA
## 2          2   8.0     8.0
## 3          3   7.0      NA
## 4          4   6.0     9.5
## 5          5   7.8      NA
## 6          6   4.0     7.5
## 7          7   7.7      NA
## 8          8   9.0     6.0
## 9          9   9.5      NA
## 10        10   6.5     5.5
  • Với các StudentID không có giá trị trên bảng y, cột physics sẽ trả về giá trị NA
3.1.5.1.4 Một số hàm nối khác.
  • Tìm hiểu chi tiết trong cheatsheet có trong phần Tài liệu tham khảo.

Kết luận: Ở trên chúng tôi đã giới thiệu về gói dplyr trong việc biến đổi dữ liệu và một số hàm cơ bản hay được sử dụng trong thực tế. Dưới đây sẽ là một ví dụ tổng hợp từ bộ dữ liệu thực tế.

4 Ví dụ tổng hợp

Trong ngân hàng, hệ thống T24 core banking hay hệ thông Data WareHouse là hệ thông thông tin vô cùng lớn của ngân hàng, nó tập hợp lượng thông tin khổng lồ gồm rất nhiều các phân hệ như: Thông tin khách hàng, Cho vay, huy động, bảo lãnh, LC, transfer,…… (Nhớ hết là điều không thể).

Bây giờ chúng ta sẽ sử dụng gói dplyr để xử lý 3 bộ số liệu này.

Xét 3 bảng dữ liệu:

Bảng 1: Thông tin về CIF khách hàng.

Tên trường Ý nghĩa
CUST_NO Mã khách hàng
GENDER Giới tính
BOD Ngày sinh nhật
PROVINCE Tỉnh
customer <- read.csv(file = "D:/2.R/11.dplyr/DimCustomer.csv")
customer %>% 
  head()
##   CUST_NO GENDER        BOD  PROVINCE
## 1 1000124 Female 1963-04-19 Khanh Hoa
## 2 1000329 Female 1988-07-13   Da Nang
## 3 1000384   Male 1992-07-14    Ha Noi
## 4 1000439   Male 1983-10-03 Binh Dinh
## 5 1000490 Female 1987-04-06    Ha Noi
## 6 1000552   Male 1965-11-07    Ha Noi

Bảng 2: Thông tin về chi nhánh.

Tên trường Ý nghĩa
BRANCH_ID Mã chi nhánh
AREA Vùng
REGION Miền
branch <- read.csv(file = "D:/2.R/11.dplyr/DimBranch.csv")
branch %>% 
  head()
##   BRANCH_ID AREA REGION
## 1   VN10114  R01    BAC
## 2   VN10115  R07  TRUNG
## 3   VN10115  R11    NAM
## 4   VN10116  R09  TRUNG
## 5   VN10116  R13    NAM
## 6   VN10117  R10    NAM

Bảng 3: Thông tin về số dư khách hàng.

Tên trường Ý nghĩa
CUST_NO Mã khách hàng
CURRENCY Loại tiền vay
BRANCH_ID Mã chi nhánh
PRO_NAME Chương trình sản phẩm
DUE_DAYS Ngày quá hạn
BALANCE Số dư
loan <- read.csv(file = "D:/2.R/11.dplyr/FactLoan.csv")
loan %>% 
  head()
##   CUST_NO CURRENCY BRANCH_ID  PRO_NAME DUE_DAYS BALANCE
## 1 2200675      VND   VN10176 Household        5  128250
## 2 2856443      VND   VN10307  Mortgage        2     500
## 3 2791801      VND   VN10166  Mortgage       29   40986
## 4 2625376      VND   VN10250 Household        8  239500
## 5 2845801      VND   VN10120  Mortgage       10  112666
## 6 3375077      VND   VN10114  Mortgage        3   29297
  • Với 3 bộ số liệu này,một số công việc chúng ta cần thực hiện ứng dụng gói dplyr:
  1. Tạo bảng dữ liệu có thông tin về khách hàng về giới tính, , số dư nợ và nhóm nợ,……(gợi ý: dựa vào thông tin trên 2 bảng loan và customer và branch)

  2. Tổng hợp số liệu về tổng dư nợ, dư nợ trung bình, tổng số khách hàng theo giới tính, nhóm tuổi và nhóm nợ

  3. Vẽ đồ thì tổng hợp kết quả trên

  4. Tổng hợp dữ liệu về khách hàng về miền, giới tính, nhóm tuổi bao gồm tổng dư nợ, số dư trung bình và số lượng khách hàng

  5. Vẽ đồ thị tổng hợp kết quả trên

Trong phần này: chỉ giải quyết câu 1 và câu 2 còn câu 3-4-5 liên quan đến Visualization (trực quan hóa dữ liệu) sẽ được giới thiệu ở những tài liệu tiếp theo.

4.1 Xử lý dữ liệu và biến đổi dữ liệu

## Tạo nhóm nợ xấu
data_new <- 
  loan %>% 
  left_join(customer, by = c("CUST_NO" = "CUST_NO")) %>% 
  as.data.frame() %>% 
  left_join(branch, by = c("BRANCH_ID" = "BRANCH_ID")) %>% 
  # Tạo nhóm nợ KH.
  mutate(ovd_group = case_when(.$DUE_DAYS < 30 ~ "nhom 1",
                        .$DUE_DAYS >= 30 & .$DUE_DAYS < 60 ~ "nhom 2",
                        .$DUE_DAYS >= 60 & .$DUE_DAYS < 120 ~ "nhom 3",
                        .$DUE_DAYS >= 120 & .$DUE_DAYS < 360 ~ "nhom 4",
                        TRUE ~ "nhom 5")) 
data_new %>% DT::datatable(filter = 'top')

4.2 Tổng hợp dữ liệu theo các chiều thông tin khác nhau.

4.2.1 Theo REGION

# Theo REGION
data_new %>% 
  group_by(REGION) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame()
##   REGION     mean min     max
## 1    BAC 153358.3 500 9907437
## 2    NAM 132997.7 500 1979800
## 3  TRUNG 135643.0 500 1745500

4.2.2 Theo CURRENCY

data_new %>% 
  group_by(CURRENCY) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame()
##   CURRENCY   mean min     max
## 1      VND 142506 500 9907437

4.2.3 Theo ovd_group

data_new %>% 
  group_by(ovd_group) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame()
##   ovd_group     mean  min     max
## 1    nhom 1 143298.1  500 9907437
## 2    nhom 2 129352.3  500 1326798
## 3    nhom 3  92075.1 6177  461709

4.2.4 Theo giới tính

data_new %>% 
  group_by(GENDER) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame()
##   GENDER     mean    min     max
## 1 Female 165256.5    500 9907437
## 2   Male 127083.4    500 9507633
## 3   <NA> 270330.0 270330  270330

4.2.5 Theo chương trình sản phẩm

data_new %>% 
  group_by(PRO_NAME) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame()
##    PRO_NAME      mean  min     max
## 1      Auto 175888.11  500 1437005
## 2 Household 374658.30  500 9907437
## 3  Mortgage  29608.26  500  197527
## 4    Others 631016.00 7000 1979800

4.2.6 Theo tỉnh thành

data_new %>% 
  group_by(PROVINCE) %>% 
  summarise(mean =  mean(BALANCE),
            min = min(BALANCE),
            max = max(BALANCE)) %>% 
  as.data.frame() %>% 
  arrange(desc(mean))
##                  PROVINCE      mean    min     max
## 1              Quang Ninh 828376.92    500 9907437
## 2              Binh Thuan 510061.94   9203 1745500
## 3                Tra Vinh 441268.00 441268  441268
## 4                  HA NAM 373415.00 373415  373415
## 5                Bac Ninh 344284.85    500 2919327
## 6              BINH THUAN 337000.00 337000  337000
## 7         BA RIA VUNG TAU 296765.00 296765  296765
## 8              QUANG NINH 279500.00 279500  279500
## 9               DONG THAP 261699.00 261699  261699
## 10               Hoa Binh 258941.00   9058 1025180
## 11              HAI DUONG 246796.00 246796  246796
## 12            Thai Nguyen 246660.10   2641 1328700
## 13                 Ha Noi 240161.42    500 9507633
## 14                    HCM 236277.14   3646  600500
## 15                Ha Tinh 228146.00   6177  695000
## 16             Kien Giang 226327.60  18475  571497
## 17                Gia Lai 182755.57  22746  411128
## 18              NINH BINH 171020.00 171020  171020
## 19         TP HO CHI MINH 159412.00 159412  159412
## 20             BINH DUONG 152449.00 152449  152449
## 21                   <NA> 152415.00  34500  270330
## 22         TP Ho Chi Minh 147539.04    500 1157949
## 23             KIEN GIANG 143784.50   4538  283031
## 24                Yen Bai 143472.00 143472  143472
## 25              Ninh Binh 140616.25   4169  387696
## 26               LAM DONG 137578.00 137578  137578
## 27                Nghe An 132318.92  21198 1437005
## 28              Hai Phong 132220.98    500 1626540
## 29              Dong Thap 119625.00   6488  601744
## 30                Can Tho 117057.62    500  497492
## 31                CAN THO 112666.00 112666  112666
## 32               An Giang 109387.62   7555  396166
## 33              Vinh Phuc 106312.50   5438  289100
## 34              THANH HOA 101337.00  12352  299500
## 35               Hung Yen  99358.50  61517  137200
## 36              Bac Giang  98298.26    500  449500
## 37              BAC GIANG  92479.75    500  195383
## 38                 HA NOI  92322.05    500  482834
## 39               Dong Nai  92164.98    500  668051
## 40                nghe an  90499.50  49500  131499
## 41        TP. Ho Chi Minh  90475.22    500 1979800
## 42              Thai Binh  85854.50  22728  146140
## 43              Thanh Hoa  85816.43    500  544220
## 44                Ha Noi.  85720.00  85720   85720
## 45                  TPHCM  84034.00  84034   84034
## 46              Hai Duong  80398.40    500  361309
## 47               Nam Dinh  64612.75    500  223500
## 48                 TP HCM  64359.25    834  124500
## 49             Binh Duong  62802.67    500  783353
## 50              Vinh Long  61138.50  12093  137060
## 51              HAI PHONG  61100.00  61100   61100
## 52             Tien Giang  60773.80  15182  123909
## 53                Da Nang  58519.22    500  439500
## 54               Lam Dong  54506.00  54506   54506
## 55              Quang Tri  54148.33    500  199500
## 56               AN GIANG  50990.00   8463  134500
## 57        Tinh Kien Giang  48562.00  48562   48562
## 58             TIEN GIANG  47744.00  29955   65533
## 59                LONG AN  45520.00  20090   70950
## 60                Long An  44212.77    500  239500
## 61              Khanh Hoa  43462.67   3682  213840
## 62         Tinh Bac Giang  42208.00  42208   42208
## 63                Phu Tho  41944.60    500   76656
## 64             Quang Binh  36864.25  14143   83500
## 65               HOA BINH  36833.00  36833   36833
## 66              Binh Dinh  36479.67    500   65342
## 67       Thanh pho Ha Noi  36341.82   7206  130454
## 68                 Ha Nam  32556.00  32556   32556
## 69                HA TINH  28540.67    500   59093
## 70      Ba Ria - Vung Tau  27007.44    500   79390
## 71       Thua Thien - Hue  26370.27   3541   78155
## 72               DONG NAI  24962.00   7222   53900
## 73           Tinh Long An  24350.57   2300   49049
## 74             Binh Phuoc  23403.00  23403   23403
## 75         TP.Ho chi minh  22500.00  22500   22500
## 76              VINH LONG  21699.50   7233   36166
## 77                      2  21587.00  21587   21587
## 78 Tinh Ba Ria - Vung Tau  20061.00  20061   20061
## 79               NAM DINH  19500.00  19500   19500
## 80                 ha noi  19094.00  19094   19094
## 81          TPHo Chi Minh  17500.00  17500   17500
## 82         THUA THIEN HUE  16867.00  16867   16867
## 83               Cao Bang  16184.00  16184   16184
## 84          Tinh Tay Ninh  14215.00  14215   14215
## 85                 Ha noi  12737.00  12737   12737
## 86        Tinh Binh Duong  11980.75    500   28805
## 87          Tinh Dong Nai   9210.25   1395   29391
## 88                Ben Tre   7563.00   2769   12357
## 89              Quang Nam   4524.00   4524    4524
## 90          Tinh Hung Yen   2802.00   2802    2802
## 91         Tinh Thanh Hoa    500.00    500     500

5 Tài liệu tham khảo.