+ - 0:00:00
Notes for current slide
Notes for next slide

Sử dụng for loop để đọc nhiều file


Khóa học: Hướng dẫn sử dụng R để xử lý dữ liệu

Biên soạn: Duc Nguyen (Tự học R chấm com)

Đăng ký: tuhocr.com@gmail.com - Website: www.tuhocr.com

1 / 13

Đề bài

Download file diet_data.zip về thư mục làm việc và giải nén ra. Bộ dữ liệu trong ví dụ này là kết quả theo dõi trọng lượng của từng người sau 30 ngày theo cùng 1 chế độ dinh dưỡng.

Bạn có 5 file .csv trong folder diet_data ở thư mục làm việc. Nếu nhập riêng lẻ từng file .csv vào R thì sẽ dùng lệnh read.csv() lần lượt từng file sẽ khá mất công (tưởng tượng nếu bạn có trên 100 file .csv như vậy). Vậy cách nào để nhập hết dữ liệu này một lần cho tiện?

D:\garden>
│ garden.Rproj
│ diet_data.zip
└───diet_data
Andy.csv
David.csv
John.csv
Mike.csv
Steve.csv
2 / 13
3 / 13

Cách 1: Đưa hết file .csv vào 1 file data.frame

Đầu tiên cần đưa vị trí các file .csv vào 1 vector để làm cơ sở cho lệnh for loop đọc một lượt các file này.

> getwd()
[1] "D:/garden"
> list.files() # Liệt kê toàn bộ file trong thư mục làm việc. Tương tự lệnh dir()
[1] "diet_data" "diet_data.zip" "garden.Rproj"
# ↑ Folder ↑ File ↑ File
> list.files("diet_data") # ← Liệt kê file trong folder
[1] "Andy.csv" "David.csv" "John.csv" "Mike.csv" "Steve.csv"
# ↓ Liệt kê file và đường dẫn
> list.files("diet_data", full.names = TRUE)
[1] "diet_data/Andy.csv" "diet_data/David.csv" "diet_data/John.csv"
[4] "diet_data/Mike.csv" "diet_data/Steve.csv"
# Đưa giá trị đường dẫn này vào vector `files_full`
> files_full <- list.files("diet_data", full.names = TRUE)
4 / 13

Cách 1: Đưa hết file .csv vào 1 file data.frame

Khi cần so sánh, tính toán giữa các bệnh nhân (Andy, David, John, Mike, Steve) thì chỉ cần subset từ file data frame chung này. Tuy vậy nếu gộp hết vào 1 file data.frame master như vậy sẽ khá chậm khi có nhiều file .csv. Do đó cách tiếp cận gộp vào list sẽ nhanh hơn.

dat <- data.frame() # Tạo data frame rỗng để chứa các file `.csv` con
# ↓ Ứng với mỗi i từ 1 đến 5 (có 5 file `.csv`), hoặc dùng lệnh seq_along()
for (i in 1:5) {
dat <- rbind(dat, read.csv(files_full[i])) # ← Đọc lần lượt file theo thứ tự index
} # ↑ Ghép theo hàng các file `.csv` vào data frame `dat`
str(dat) # Kiểm tra kết quả cho thấy `dat` chứa đủ 5 file (tổng cộng 150 dòng)
'data.frame': 150 obs. of 4 variables:
$ Patient.Name: chr "Andy" "Andy" "Andy" "Andy" ...
$ Age : int 30 30 30 30 30 30 30 30 30 30 ...
$ Weight : int 140 140 140 139 138 138 138 138 138 138 ...
$ Day : int 1 2 3 4 5 6 7 8 9 10 ...
5 / 13

Cách 2: Đưa hết file .csv vào 1 file list

> tmp <- vector(mode = "list",
length = length(files_full))
> tmp # Bản chất `tmp` là
[[1]] # một list rỗng chứa
NULL # sẵn 5 vị trí (component)
# cho các file `.csv`
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
[[5]]
NULL
> summary(tmp)
Length Class Mode
[1,] 0 -none- NULL
[2,] 0 -none- NULL
[3,] 0 -none- NULL
[4,] 0 -none- NULL
[5,] 0 -none- NULL
6 / 13

Cách 2: Đưa hết file .csv vào 1 file list

Dùng lệnh for loop

# ↓ Tạo ra dãy số index trong vector `files_full` tương tự 1:5
for (i in seq_along(files_full)) {
# ↓ Tương ứng từng component `i` trong list (chú ý subset bằng `[[`)
tmp[[i]] <- read.csv(files_full[[i]]) # ← Đọc file `.csv`
} # ↑ Có thể dùng files_full[i] cũng ra cùng kết quả
str(tmp) # Xem cấu trúc của file list `tmp` sau khi combine theo cách trên
7 / 13
8 / 13

Cách 3: Đưa hết file .csv vào 1 file list

Dùng lệnh lapply. Bản chất là lệnh for loop nhưng tiện hơn.

> files_full
[1] "diet_data/Andy.csv" "diet_data/David.csv" "diet_data/John.csv"
[4] "diet_data/Mike.csv" "diet_data/Steve.csv"
# ↓ Vector chứa đường dẫn file `.csv`
> yes <- lapply(files_full, read.csv)
# ↑ Lệnh đọc file `.csv`
> str(yes) # Kết quả y chang như cách 2
9 / 13
10 / 13

Trích xuất data frame con trong list

> class(tmp)
[1] "list"
> tmp[[3]] -> john # Trích xuất thành phần trong list ra một data frame con
> head(john)
Patient.Name Age Weight Day
1 John 22 175 1
2 John 22 175 2
3 John 22 175 3
4 John 22 175 4
5 John 22 175 5
6 John 22 175 6
> class(john)
[1] "data.frame"
11 / 13

Câu hỏi

Làm sao gộp lại các data frame trong list vào lại thành file data frame master như cách 1?

12 / 13

Lệnh do.call()

# ↓ Hàm dùng ghép hàng các file
output <- do.call(rbind, tmp) # ← List chứa các data frame con cần ghép
> str(output) # Kết quả data frame `output`
'data.frame': 150 obs. of 4 variables:
$ Patient.Name: chr "Andy" "Andy" "Andy" "Andy" ...
$ Age : int 30 30 30 30 30 30 30 30 30 30 ...
$ Weight : int 140 140 140 139 138 138 138 138 138 138 ...
$ Day : int 1 2 3 4 5 6 7 8 9 10 ...
> identical(dat, output) # So sánh giữa `dat` (data frame master cách 1) và
[1] TRUE # `output` cho thấy y chang nhau
13 / 13

Đề bài

Download file diet_data.zip về thư mục làm việc và giải nén ra. Bộ dữ liệu trong ví dụ này là kết quả theo dõi trọng lượng của từng người sau 30 ngày theo cùng 1 chế độ dinh dưỡng.

Bạn có 5 file .csv trong folder diet_data ở thư mục làm việc. Nếu nhập riêng lẻ từng file .csv vào R thì sẽ dùng lệnh read.csv() lần lượt từng file sẽ khá mất công (tưởng tượng nếu bạn có trên 100 file .csv như vậy). Vậy cách nào để nhập hết dữ liệu này một lần cho tiện?

D:\garden>
│ garden.Rproj
│ diet_data.zip
└───diet_data
Andy.csv
David.csv
John.csv
Mike.csv
Steve.csv
2 / 13
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow