Tiến hành cài và nhập gói vào phiên làm việc

# để hết các lệnh nhập package trên đầu file
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library(writexl)


1. Một số hàm thao tác với dataset

Một số hàm có sẵn trong R để thao tác với Dataset

Đọc dữ liệu csv

application <- read.csv("data/application_sample.csv")
# application <- read.csv("~/Library/CloudStorage/OneDrive-SciEco/R Courses/R KOICA/PHASE 1/chuong_1/Bài tập chương 1/application_sample.csv")


head(data): Xem 6 dòng đầu tiên của dataset

head(application)


tail(data): xem 6 dòng cuối cùng của dataset

tail(application)


head(data, n) xem n dòng đầu tiên

head(application, 10)


tail(data, n) xem n dòng cuối cùng

tail(application, 10)


str(data): cấu trúc của dataset, cung cấp thông tin:

str(application)
## 'data.frame':    20000 obs. of  11 variables:
##  $ SK_ID_CURR        : int  411019 360800 238560 130181 216974 128257 205326 160384 317054 369746 ...
##  $ TARGET            : int  0 0 0 0 0 0 1 0 0 0 ...
##  $ NAME_CONTRACT_TYPE: chr  "Cash loans" "Revolving loans" "Cash loans" "Cash loans" ...
##  $ CODE_GENDER       : chr  "F" "F" "M" "M" ...
##  $ FLAG_OWN_CAR      : chr  "N" "N" "N" "N" ...
##  $ FLAG_OWN_REALTY   : chr  "Y" "Y" "Y" "N" ...
##  $ CNT_CHILDREN      : int  0 1 1 1 0 1 3 0 0 0 ...
##  $ CNT_FAM_MEMBERS   : int  1 2 2 3 1 3 5 2 1 1 ...
##  $ AMT_INCOME_TOTAL  : num  180000 94500 157500 157500 202500 ...
##  $ AMT_CREDIT        : num  675000 180000 675000 746280 961146 ...
##  $ NAME_FAMILY_STATUS: chr  "Single / not married" "Single / not married" "Separated" "Married" ...


dim(data): Số dòng và số cột của bảng

dim(application)
## [1] 20000    11


nrow(data): số dòng (số quan sát) của bảng

nrow(application)
## [1] 20000


ncol(data): số cột (số biến) của bảng

ncol(application)
## [1] 11


summary(data): thống kê mô tả nhanh các biến

summary(application)
##    SK_ID_CURR         TARGET       NAME_CONTRACT_TYPE CODE_GENDER       
##  Min.   :100031   Min.   :0.0000   Length:20000       Length:20000      
##  1st Qu.:187757   1st Qu.:0.0000   Class :character   Class :character  
##  Median :276387   Median :0.0000   Mode  :character   Mode  :character  
##  Mean   :277116   Mean   :0.0774                                        
##  3rd Qu.:366167   3rd Qu.:0.0000                                        
##  Max.   :456238   Max.   :1.0000                                        
##                                                                         
##  FLAG_OWN_CAR       FLAG_OWN_REALTY     CNT_CHILDREN     CNT_FAM_MEMBERS 
##  Length:20000       Length:20000       Min.   : 0.0000   Min.   : 1.000  
##  Class :character   Class :character   1st Qu.: 0.0000   1st Qu.: 2.000  
##  Mode  :character   Mode  :character   Median : 0.0000   Median : 2.000  
##                                        Mean   : 0.4153   Mean   : 2.152  
##                                        3rd Qu.: 1.0000   3rd Qu.: 3.000  
##                                        Max.   :12.0000   Max.   :14.000  
##                                                          NA's   :1       
##  AMT_INCOME_TOTAL     AMT_CREDIT      NAME_FAMILY_STATUS
##  Min.   :   27000   Min.   :  45000   Length:20000      
##  1st Qu.:  112500   1st Qu.: 270000   Class :character  
##  Median :  148500   Median : 512064   Mode  :character  
##  Mean   :  170469   Mean   : 599440                     
##  3rd Qu.:  202500   3rd Qu.: 808650                     
##  Max.   :18000090   Max.   :3375000                     
## 


2. Package dplyr

dplyr là một thư viện có chức năng thao tác và biến đổi dữ liệu một cách trực quan. Package dplyr cung cấp những function hoán chuyển và thao tác trên dữ liệu sau khi nó đã được tải vào R.

2.1. Thao tác với dòng


2.1.1. filter(): lọc dữ liệu

Lọc những khoản vay có thu nhập >= 100.000 USD

head(
  filter(application, AMT_INCOME_TOTAL >= 100000)
)


Đếm số khoản vay mà người đi vay có thu nhập >= 100.000 USD

nrow(
  filter(application, AMT_INCOME_TOTAL >= 100000)
)
## [1] 15873


2.1.2. distinct(): bỏ quan sát trùng

Số lượng quan sát ban đầu chưa bỏ trùng là 20000

nrow(application)
## [1] 20000


Sau khi thực hiện bỏ quan sát trùng thì số quan sát không thay đổi, do đó dataset này không có quan sát trùng

nrow(distinct(application, SK_ID_CURR))
## [1] 20000


Có thể dùng distinct(data, tên cột) để kiểm tra số lượng biểu hiện có trong cột đó, ví dụ cột CODE_GENDER chỉ có 2 biểu hiện là MF

distinct(application, CODE_GENDER)


2.1.3. arrange(): sắp xếp dữ liệu

Sắp xếp quan sát theo thứ tự tăng dần của thu nhập

head(
  arrange(application, AMT_INCOME_TOTAL),
  10
)


Sắp xếp quan sát theo thứ tự giảm dần của thu nhập

head(
  arrange(application, desc(AMT_INCOME_TOTAL)),
  10
)


Lưu ý: trường hợp dữ liệu bị khuyết (missing data - NA) thì dù sắp xếp tăng dần hay giảm dần thì giá trị khuyết luôn được đưa xuống cuối cùng của bảng

str(application)
## 'data.frame':    20000 obs. of  11 variables:
##  $ SK_ID_CURR        : int  411019 360800 238560 130181 216974 128257 205326 160384 317054 369746 ...
##  $ TARGET            : int  0 0 0 0 0 0 1 0 0 0 ...
##  $ NAME_CONTRACT_TYPE: chr  "Cash loans" "Revolving loans" "Cash loans" "Cash loans" ...
##  $ CODE_GENDER       : chr  "F" "F" "M" "M" ...
##  $ FLAG_OWN_CAR      : chr  "N" "N" "N" "N" ...
##  $ FLAG_OWN_REALTY   : chr  "Y" "Y" "Y" "N" ...
##  $ CNT_CHILDREN      : int  0 1 1 1 0 1 3 0 0 0 ...
##  $ CNT_FAM_MEMBERS   : int  1 2 2 3 1 3 5 2 1 1 ...
##  $ AMT_INCOME_TOTAL  : num  180000 94500 157500 157500 202500 ...
##  $ AMT_CREDIT        : num  675000 180000 675000 746280 961146 ...
##  $ NAME_FAMILY_STATUS: chr  "Single / not married" "Single / not married" "Separated" "Married" ...
arrange(application, CODE_GENDER, AMT_CREDIT)

2.2. Thao tác với cột

2.2.1. select()

Chọn cột cần thiết, bỏ cột không cần thiết trong bảng

data1 <- select(
  application, 
  CODE_GENDER, 
  AMT_INCOME_TOTAL, 
  AMT_CREDIT
  )
head(data1)
str(application)
## 'data.frame':    20000 obs. of  11 variables:
##  $ SK_ID_CURR        : int  411019 360800 238560 130181 216974 128257 205326 160384 317054 369746 ...
##  $ TARGET            : int  0 0 0 0 0 0 1 0 0 0 ...
##  $ NAME_CONTRACT_TYPE: chr  "Cash loans" "Revolving loans" "Cash loans" "Cash loans" ...
##  $ CODE_GENDER       : chr  "F" "F" "M" "M" ...
##  $ FLAG_OWN_CAR      : chr  "N" "N" "N" "N" ...
##  $ FLAG_OWN_REALTY   : chr  "Y" "Y" "Y" "N" ...
##  $ CNT_CHILDREN      : int  0 1 1 1 0 1 3 0 0 0 ...
##  $ CNT_FAM_MEMBERS   : int  1 2 2 3 1 3 5 2 1 1 ...
##  $ AMT_INCOME_TOTAL  : num  180000 94500 157500 157500 202500 ...
##  $ AMT_CREDIT        : num  675000 180000 675000 746280 961146 ...
##  $ NAME_FAMILY_STATUS: chr  "Single / not married" "Single / not married" "Separated" "Married" ...


Lấy từ <CỘT A> tới <CỘTB>: <CỘT A>:<CỘT B>

select(application, TARGET:AMT_CREDIT)


Dùng dấu - để bỏ đi cột không cần lấy

Lưu ý: chỉ bỏ cột, hoặc chọn cột, không làm cả hai

head(
  select(application, -SK_ID_CURR, -TARGET, -CODE_GENDER)
)


Ví dụ đặt tên cột bắt đầu bằng chữ q:

  • Ví dụ: q1, q2, …
select(application, 
       CODE_GENDER, 
       starts_with('C')
      )


2.2.2. rename()

Đổi tên cột CODE_GENDER -> gender

rename(
  application, 
  gender = CODE_GENDER,
  id = SK_ID_CURR,
  car = FLAG_OWN_CAR,
  income = AMT_INCOME_TOTAL,
  realty = FLAG_OWN_REALTY,
  target = TARGET,
  contract_type = NAME_CONTRACT_TYPE,
  n_children = CNT_CHILDREN,
  credit = AMT_CREDIT,
  n_fam_members = CNT_FAM_MEMBERS,
  fam_status = NAME_FAMILY_STATUS
)


2.2.3. mutate()

Tạo cột mới từ các cột trước đó

AMT_INCOME_TOTAL (USD)

Đổi đơn vị USD -> nghìn USD

mutate(
  application,
  income2 = AMT_INCOME_TOTAL / 1000
)


Muốn sửa đổi cột có trong bảng (AMT_INCOME_TOTAL)

mutate(
  application,
  AMT_INCOME_TOTAL = AMT_INCOME_TOTAL / 1000,
  AMT_CREDIT = AMT_CREDIT / 1000
)


Chia khách hàng thành ba nhóm, thu nhập cao, trung bình, thấp

min(application$AMT_INCOME_TOTAL) 
## [1] 27000
max(application$AMT_INCOME_TOTAL)
## [1] 18000090
mean(application$AMT_INCOME_TOTAL) # tính trung bình
## [1] 170468.9
median(application$AMT_INCOME_TOTAL) # trung vị
## [1] 148500
quantile(application$AMT_INCOME_TOTAL, 0.25) # phân vị mức 25
##    25% 
## 112500
var(application$AMT_INCOME_TOTAL) # phương sai
## [1] 35193056111
sd(application$AMT_INCOME_TOTAL) # độ lệch chuẩn
## [1] 187598.1


Chia làm 3 nhóm:

  • Thấp: < 100.000

  • Trung bình: 100.000 - 500.000

  • Cao: >= 500.000

mutate(
  application,
  income_class = case_when(
    AMT_INCOME_TOTAL < 100000 ~ "Thấp",
    AMT_INCOME_TOTAL < 500000 ~ "Trung bình",
    AMT_INCOME_TOTAL >= 500000 ~ "Cao",
    TRUE ~ "Không xác định" # những trường hợp còn lại
  ),
  have_child = case_when(
    CNT_CHILDREN > 0 ~ TRUE,
    CNT_CHILDREN == 0 ~ FALSE
  )
)


Chia thu nhập:

  • 0 - 100%

  • 25%: Thấp

  • 25% - 75%: Trung bình

  • 75%: Cao

q1 <- quantile(application$AMT_INCOME_TOTAL, .25)
q3 <- quantile(application$AMT_INCOME_TOTAL, .75)
mutate(
  application,
  income_class = case_when(
    AMT_INCOME_TOTAL < q1 ~ "Thấp",
    AMT_INCOME_TOTAL < q3 ~ "Trung bình",
    AMT_INCOME_TOTAL >= q3 ~ "Cao"
  )
)


2.2.4. summarize()

Tổng hợp dữ liệu, tạo bảng thống kê mô tả

as.data.frame(
  t(
    summarise(
      application,
      obs = n(), # tính số quan sát
      mean_income = mean(AMT_INCOME_TOTAL),
      var_income = var(AMT_INCOME_TOTAL),
      sd_income = sd(AMT_INCOME_TOTAL),
      q1 = quantile(AMT_INCOME_TOTAL, 0.25),
      median = median(AMT_INCOME_TOTAL),
      q3 = quantile(AMT_INCOME_TOTAL, 0.75)
    )
  )
)


Toán tử pipe: %>% (phím tắt ctrl + shift + m)

options(scipen = 999) # tắt hiển thị science number
summarise(
  application,
  obs = n(), # tính số quan sát
  mean = mean(AMT_INCOME_TOTAL),
  var = var(AMT_INCOME_TOTAL),
  sd = sd(AMT_INCOME_TOTAL),
  q1 = quantile(AMT_INCOME_TOTAL, 0.25),
  median = median(AMT_INCOME_TOTAL),
  q3 = quantile(AMT_INCOME_TOTAL, 0.75)
) %>% 
  t() %>% 
  as.data.frame() %>% 
  rename(income = V1) %>% 
  mutate(
    info = rownames(.) # chuyển tên dòng thành 1 cột mới
  ) %>% 
  select(info, income)


Sử dụng group_by() kết hợp với summarise() tổng hợp theo từng nhóm

group_by(application, CODE_GENDER) %>% 
  summarise(
    obs = n(),
    mean_income = mean(AMT_INCOME_TOTAL),
    sd_income = sd(AMT_INCOME_TOTAL)
  ) %>% 
  rename(
    gender = CODE_GENDER
  ) %>% 
  write_xlsx('desc2.xlsx')


3. tidyr

3.1. gather() dạng wide sang long

head(application, 10) %>% 
  select(SK_ID_CURR, CODE_GENDER, AMT_CREDIT, AMT_INCOME_TOTAL) %>% 
  gather(
    CODE_GENDER, 
    AMT_CREDIT, 
    AMT_INCOME_TOTAL, 
    key="variable", 
    value = "value"
  )


Sử dụng data GDP

  • gdp.csv
  • pop.csv
gdp <- read.csv("data/gdp.csv")
pop <- read.csv("data/pop.csv")
head(gdp) # lấy từ năm cột X1960 tới X2021
gdp <- gather(gdp, X1960:X2021, key="Year", value="GDP") %>% 
  mutate(
    Year = as.numeric(gsub("X", "", Year)) # bỏ kí tự X, và đổi text sang số
  )
# Không dùng định danh khi reshape
head(gdp)
pop <- gather(pop, X1960:X2021, key="Year", value="Pop") %>% 
  mutate(
    Year = as.numeric(gsub("X", "", Year))
  )
head(pop)

3.2. spread() Chuyển từ long sang wide

spread(pop, key = Year, value = Pop) %>% 
  head()


4. Merge data

4.1. Ghép theo cột

select(gdp, -Country.Name) %>% 
  full_join(pop, by = c("Country.Code", "Year")) %>% 
  select(Country.Name, everything()) %>% 
  head()
  # đưa cột Country.Name lên đầu
  # everything() những cột còn lại

4.2. Nối theo dòng

data1 <- data.frame(
  x = c(1, 2),
  y = c(3, 4)
)
data1
data2 <- data.frame(
  x = c(5, 6),
  y = c(7, 8)
)
data2
rbind(data1, data2)

4.3. Nối theo cột

# income
desc_income <- summarise(
  application,
  mean = mean(AMT_INCOME_TOTAL),
  sd = sd(AMT_INCOME_TOTAL),
  q1 = quantile(AMT_INCOME_TOTAL, 0.25),
  median = median(AMT_INCOME_TOTAL),
  q3 = quantile(AMT_INCOME_TOTAL, 0.75),
  min = min(AMT_INCOME_TOTAL),
  max = max(AMT_INCOME_TOTAL)
) %>% 
  t() %>% 
  as.data.frame() %>% 
  rename(income = V1)

desc_income
desc_credit <- summarise(
  application,
  mean = mean(AMT_CREDIT),
  sd = sd(AMT_CREDIT),
  q1 = quantile(AMT_CREDIT, 0.25),
  median = median(AMT_CREDIT),
  q3 = quantile(AMT_CREDIT, 0.75),
  min = min(AMT_CREDIT),
  max = max(AMT_CREDIT)
) %>% 
  t() %>% 
  as.data.frame() %>% 
  rename(credit = V1)

desc_credit
cbind(desc_income, desc_credit)


Lưu ý: Trường hợp code bị lặp lại, cần phải tạo function