Các lệnh if-else, for-loop

Câu 1

Bạn có bộ dữ liệu sau gồm 6 file Excel là số điểm của học sinh ở các lớp 7a1 đến 7a6. [download]

Cụ thể, ta xem trong 1 file, ta sẽ thấy có 2 cột là ĐIỂM SỐKẾT QUẢ.

Bạn hãy thực hiện lệnh điều kiện để phân loại điểm số học sinh như sau:

• 10 - 9 : GIỎI

• >9 - 7 : KHÁ

• >7 - 5 : TRUNG BÌNH KHÁ

• >5 - 3 : YẾU

• >3 - 0 : KÉM

• KHÔNG CÓ ĐIỂM: KHÔNG ĐI THI

Sau đó bạn thực hiện lệnh vòng lặp for-loop để tính toán nhanh các file này và xuất ra folder OUTPUT.

Ta sẽ làm 2 cách, sử dụng function dplyr:::case_when() xuất ra folder OUTPUT_1 và function if-else của Base R xuất ra folder OUTPUT_2.

Import file

file_data <- list.files(path = "dataset/lop_7a",
                        full.names = TRUE, 
                        pattern = "*.xlsx")

file_data
[1] "dataset/lop_7a/lop_7a1.xlsx" "dataset/lop_7a/lop_7a2.xlsx" "dataset/lop_7a/lop_7a3.xlsx" "dataset/lop_7a/lop_7a4.xlsx" "dataset/lop_7a/lop_7a5.xlsx" "dataset/lop_7a/lop_7a6.xlsx"

Cách 1. Dùng dplyr:::case_when()

1.1 Xử lý chuẩn 1 file

library(readxl)
df <- read_excel(file_data[1])
df <- as.data.frame(df)
head(df, n = 10)
   STT             HỌ  TÊN ĐIỂM SỐ KẾT QUẢ
1    1    Nguyễn Diệp Hạnh       9      NA
2    2       Trần Nam Tuấn       5      NA
3    3     Hoàng Ngọc Liên       3      NA
4    4 Nguyễn Thị Kim  Mai      10      NA
5    5      Phạm Hồng Thúy       5      NA
6    6        Vũ Việt  Thư       2      NA
7    7      Phạm Ngọc  Trí       8      NA
8    8       Đào Minh Hạnh       4      NA
9    9        Đỗ Minh Hưng       9      NA
10  10      Lê Phương Liên       5      NA
library(dplyr)

# thứ tự điều kiện ưu tiên đi từ trên xuống

df |> dplyr:::mutate(`KẾT QUẢ` = case_when(
  
  is.na(`ĐIỂM SỐ`) == TRUE ~ "KHÔNG ĐI THI",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 9 & `ĐIỂM SỐ` <= 10 ~ "GIỎI",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 7 & `ĐIỂM SỐ` < 9 ~ "KHÁ",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 5 & `ĐIỂM SỐ` < 7 ~ "TRUNG BÌNH KHÁ",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 3 & `ĐIỂM SỐ` < 5 ~ "YẾU",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 0 & `ĐIỂM SỐ` < 3 ~ "KÉM",
  
  .default = NA
  
)) -> df_out_1

# Kiểm tra kết quả xem lệnh này đã tính toán ổn trên 1 file chưa
head(df_out_1, n = 10)
   STT             HỌ  TÊN ĐIỂM SỐ        KẾT QUẢ
1    1    Nguyễn Diệp Hạnh       9           GIỎI
2    2       Trần Nam Tuấn       5 TRUNG BÌNH KHÁ
3    3     Hoàng Ngọc Liên       3            YẾU
4    4 Nguyễn Thị Kim  Mai      10           GIỎI
5    5      Phạm Hồng Thúy       5 TRUNG BÌNH KHÁ
6    6        Vũ Việt  Thư       2            KÉM
7    7      Phạm Ngọc  Trí       8            KHÁ
8    8       Đào Minh Hạnh       4            YẾU
9    9        Đỗ Minh Hưng       9           GIỎI
10  10      Lê Phương Liên       5 TRUNG BÌNH KHÁ

1.2 Xử lý vòng lặp for-loop

library(openxlsx)

for(i in 1:length(file_data)){

library(readxl)
df <- read_excel(file_data[i])
df <- as.data.frame(df)

library(dplyr)

# thứ tự điều kiện ưu tiên đi từ trên xuống

df |> dplyr:::mutate(`KẾT QUẢ` = case_when(
  
  is.na(`ĐIỂM SỐ`) == TRUE ~ "KHÔNG ĐI THI",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 9 & `ĐIỂM SỐ` <= 10 ~ "GIỎI",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 7 & `ĐIỂM SỐ` < 9 ~ "KHÁ",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 5 & `ĐIỂM SỐ` < 7 ~ "TRUNG BÌNH KHÁ",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 3 & `ĐIỂM SỐ` < 5 ~ "YẾU",
  
  (is.na(`ĐIỂM SỐ`) == FALSE) &  `ĐIỂM SỐ` >= 0 & `ĐIỂM SỐ` < 3 ~ "KÉM",
  
  .default = NA
  
)) -> df_out


output <- basename(file_data[i])

output_name <- paste0("dataset/lop_7a/OUTPUT_1/", output)

openxlsx:::write.xlsx(x = df_out,
                      file = output_name)

}

Cách 2. Dùng ifelse()

2.1 Xử lý chuẩn 1 file

library(readxl)
df <- read_excel(file_data[1])
df <- as.data.frame(df)
head(df, n = 10)
   STT             HỌ  TÊN ĐIỂM SỐ KẾT QUẢ
1    1    Nguyễn Diệp Hạnh       9      NA
2    2       Trần Nam Tuấn       5      NA
3    3     Hoàng Ngọc Liên       3      NA
4    4 Nguyễn Thị Kim  Mai      10      NA
5    5      Phạm Hồng Thúy       5      NA
6    6        Vũ Việt  Thư       2      NA
7    7      Phạm Ngọc  Trí       8      NA
8    8       Đào Minh Hạnh       4      NA
9    9        Đỗ Minh Hưng       9      NA
10  10      Lê Phương Liên       5      NA
diem_thi <- df$`ĐIỂM SỐ`


for(j in 1:length(diem_thi)) {
        
        if(!(is.na(diem_thi[j])) & diem_thi[j] >= 9) {
            
          df$`KẾT QUẢ`[j] <- "GIỎI"
          
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 7) {
          
            df$`KẾT QUẢ`[j] <- "KHÁ"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 5) {
          
            df$`KẾT QUẢ`[j] <- "TRUNG BÌNH KHÁ"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 3) {
          
            df$`KẾT QUẢ`[j] <- "YẾU"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 0) {
          
            df$`KẾT QUẢ`[j] <- "KÉM"
            
        } else if(is.na(diem_thi[j])) {
          
            df$`KẾT QUẢ`[j] <- "KHÔNG ĐI THI"
            
        } else {
          
            df$`KẾT QUẢ`[j] <- NA
            
        }
        
}

df -> df_out_2

Kiểm tra xem kết quả tính bằng case_when()if-else có giống nhau không.

identical(df_out_1, df_out_2)
[1] TRUE

2.2 Xử lý vòng lặp for-loop

library(openxlsx)

for(i in 1:length(file_data)){

library(readxl)
df <- read_excel(file_data[i])

df <- as.data.frame(df)

diem_thi <- df$`ĐIỂM SỐ`


for(j in 1:length(diem_thi)) {
        
        if(!(is.na(diem_thi[j])) & diem_thi[j] >= 9) {
            
          df$`KẾT QUẢ`[j] <- "GIỎI"
          
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 7) {
          
            df$`KẾT QUẢ`[j] <- "KHÁ"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 5) {
          
            df$`KẾT QUẢ`[j] <- "TRUNG BÌNH KHÁ"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 3) {
          
            df$`KẾT QUẢ`[j] <- "YẾU"
            
        } else if(!(is.na(diem_thi[j])) & diem_thi[j] >= 0) {
          
            df$`KẾT QUẢ`[j] <- "KÉM"
            
        } else if(is.na(diem_thi[j])) {
          
            df$`KẾT QUẢ`[j] <- "KHÔNG ĐI THI"
            
        } else {
          
            df$`KẾT QUẢ`[j] <- NA
            
        }
        
}

df -> df_out

output <- basename(file_data[i])

output_name <- paste0("dataset/lop_7a/OUTPUT_2/", output)

openxlsx:::write.xlsx(x = df_out,
                      file = output_name)

}

CHECK

Ta có thể import lại cùng một file được tính bằng 2 cách khác nhau để xem kết quả có giống nhau không, cho thấy dùng cách case_when() hay if-else đều được.

library(readxl)
lop_7a5_cach1 <- read_excel("dataset/lop_7a/OUTPUT_1/lop_7a5.xlsx")

lop_7a5_cach2 <- read_excel("dataset/lop_7a/OUTPUT_2/lop_7a5.xlsx")

identical(lop_7a5_cach1, lop_7a5_cach2)
[1] TRUE