Vòng lặp For trong R với các ví dụ về Danh sách và Ma trận
⚡ Tóm tắt thông minh
Vòng lặp `for` trong R thực thi một khối mã một lần cho mỗi phần tử của một chuỗi, cho dù chuỗi đó là một vectơ, một danh sách hay một ma trận. Hướng dẫn này sẽ lặp qua từng trường hợp và chỉ ra khi nào mã được vector hóa là lựa chọn tốt hơn.

A vòng lặp for Lặp lại một khối mã một lần cho mỗi phần tử của một chuỗi. Chuỗi đó có thể là một vectơ, một danh sách, một khung dữ liệu, một ma trận hoặc bất kỳ đối tượng nào khác mà R có thể lặp qua. R phân biệt chữ hoa chữ thường, vì vậy từ khóa luôn được viết thường. chovà dấu ngoặc nhọn là bắt buộc khi nội dung trải dài hơn một dòng.
Cú pháp vòng lặp for trong R
for (i in vector) { Exp }
Ở đây,
R sẽ lặp qua tất cả các biến trong vector và thực hiện phép tính được viết bên trong exp.

Hãy xem một vài ví dụ.
Vòng lặp For trong R Ví dụ 1: Chúng ta lặp lại tất cả các phần tử của một vectơ và in ra giá trị hiện tại.
# Create fruit vector fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # Create the for statement for ( i in fruit){ print(i) }
Đầu ra:
## [1] "Apple" ## [1] "Orange" ## [1] "Passion fruit" ## [1] "Banana"
Vòng lặp For trong R Ví dụ 2Bình phương mọi số nguyên từ 1 đến 4 và lưu kết quả vào một danh sách.
# Create an empty list list <- c() # Create a for statement to populate the list for (i in seq(1, 4, by=1)) { list[[i]] <- i*i } print(list)
Đầu ra:
## [1] 1 4 9 16
Vòng lặp for rất hữu ích trong công việc học máy. Việc điều chỉnh tham số điều chuẩn có nghĩa là phải kiểm tra nhiều giá trị ứng cử viên và giữ cho...ping Phương pháp tối thiểu hóa hàm mất mát là sử dụng vòng lặp for, và đây là cách đơn giản nhất để quét phạm vi đó.
Cách sử dụng break và next trong vòng lặp for
Hai từ khóa làm gián đoạn trình tự hoạt động bình thường của vòng lặp for.
- phá vỡ Thoát khỏi vòng lặp ngay lập tức và bỏ qua tất cả các phần tử còn lại.
- tiếp theo Chỉ bỏ qua phần tử hiện tại và chuyển sang phần tử tiếp theo.
fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # break: stop at the first match for (i in fruit) { if (i == 'Passion fruit') { print('Found it, stopping here') break } print(i) } # next: skip one element and carry on for (i in fruit) { if (i == 'Orange') next print(i) }
Trong các vòng lặp lồng nhau, lệnh break và next chỉ tác động lên vòng lặp trong cùng chứa chúng. Để giữ nguyên cả hai vòng lặp trong ví dụ ma trận, hãy đặt một biến cờ và kiểm tra nó trong vòng lặp ngoài cùng.
Sử dụng seq_along() cho chỉ mục. Việc viết vòng lặp for (i in 1:length(x)) trông có vẻ vô hại nhưng sẽ gặp lỗi với một đối tượng rỗng, vì 1:0 tạo ra chuỗi 1, 0 và vòng lặp chạy hai lần. Hàm seq_along(x) trả về một chuỗi rỗng, do đó vòng lặp được bỏ qua một cách chính xác:
for (i in seq_along(fruit)) { cat(i, fruit[i], '\n') }
Vòng lặp for trên một danh sách
Looping Việc liệt kê hoạt động chính xác như loo.ping trên một vectơ, ngoại trừ mỗi phần tử có thể chứa một kiểu dữ liệu khác nhau:
# Create a list with three vectors fruit <- list(Basket = c('Apple', 'Orange', 'Passion fruit', 'Banana'), Money = c(10, 12, 15), purchase = FALSE) for (p in fruit) { print(p) }
Đầu ra:
## [1] "Apple" "Orange" "Passion fruit" "Banana" ## [1] 10 12 15 ## [1] FALSE
Vòng lặp for trên ma trận
Ma trận có hai chiều, hàng và cột, vì vậy việc lặp qua từng ô cần hai vòng lặp for lồng nhau: một vòng lặp bên ngoài cho hàng và một vòng lặp bên trong cho cột.
# Create a matrix mat <- matrix(data = seq(10, 20, by=1), nrow = 6, ncol =2) # Create the loop with r and c to iterate over the matrix for (r in 1:nrow(mat)) for (c in 1:ncol(mat)) print(paste("Row", r, "and column",c, "have values of", mat[r,c]))
Đầu ra:
## [1] "Row 1 and column 1 have values of 10" ## [1] "Row 1 and column 2 have values of 16" ## [1] "Row 2 and column 1 have values of 11" ## [1] "Row 2 and column 2 have values of 17" ## [1] "Row 3 and column 1 have values of 12" ## [1] "Row 3 and column 2 have values of 18" ## [1] "Row 4 and column 1 have values of 13" ## [1] "Row 4 and column 2 have values of 19" ## [1] "Row 5 and column 1 have values of 14" ## [1] "Row 5 and column 2 have values of 20" ## [1] "Row 6 and column 1 have values of 15" ## [1] "Row 6 and column 2 have values of 10"
Vòng lặp for trên một DataFrame trong R
DataFrame là một danh sách các cột, vì vậy vòng lặp for thông thường sẽ duyệt qua các cột chứ không phải các hàng của nó. Đó thường là điều bạn muốn:
df <- data.frame(a = 1:5, b = 6:10, c = 11:15) # Loop over the columns for (col in names(df)) { cat(col, 'has mean', mean(df[[col]]), '\n') }
Lưu ý dấu ngoặc kép. df[[col]] extracts cột dưới dạng một vectơ, trong khi df[col] trả về một khung dữ liệu một cột mà mean() không thể xử lý.
Looping trên các hàng. Việc lặp từng hàng là khả thi nhưng chậm, vì R sao chép hàng đó trong mỗi lần lặp:
for (r in seq_len(nrow(df))) { cat('Row', r, 'sums to', sum(df[r, ]), '\n') }
Đối với bất kỳ số lượng hàng nào vượt quá vài nghìn hàng, hãy ưu tiên sử dụng rowSums(df), apply(df, 1, sum) hoặc dplyr. group_by() và summarise() các quy trình, tất cả đều thực hiện cùng một công việc mà không cần sao chép.
So sánh vòng lặp for và vector hóa trong R
R là một ngôn ngữ lập trình hướng đối tượng (vectorized): hầu hết các toán tử và hàm của nó đều tác động đồng thời lên toàn bộ vector trong mã C đã biên dịch. Một vòng lặp tường minh lặp lại thao tác hướng đối tượng từng phần tử một sẽ dài hơn và chậm hơn.
# Loop version squares <- c() for (i in 1:4) { squares[i] <- i * i } # Vectorized version, same result squares <- (1:4)^2
| Nhiệm vụ | Vòng lặp | Tương đương dạng vector |
|---|---|---|
| phép toán từng phần tử | cho mỗi phần tử | x * 2, x + y, x^2 |
| Áp dụng một hàm cho mỗi cột | cho các tên (df) | áp dụng(df, trung bình) |
| Áp dụng một hàm cho mỗi hàng | cho trên seq_len(nrow(df)) | áp dụng(df, 1, sum) |
| Lập danh sách kết quả | với danh sách[[i]] <- … | lapply(v, f) |
| Mã hóa lại có điều kiện | với điều kiện if và else | ifelse(cond, a, b) |
Khi vòng lặp vẫn là giải pháp đúng. Hãy giữ lại vòng lặp for khi mỗi lần lặp phụ thuộc vào kết quả trước đó, khi bạn gọi một dịch vụ bên ngoài hoặc ghi tệp, hoặc khi sự rõ ràng quan trọng hơn tốc độ đối với một đối tượng nhỏ.
Nếu bắt buộc phải sử dụng vòng lặp, hãy cấp phát bộ nhớ trước. Việc mở rộng một đối tượng bên trong vòng lặp buộc R phải sao chép nó trong mỗi lần lặp. Hãy tạo đối tượng ở kích thước đầy đủ trước:
# Slow: the vector is reallocated on every pass out <- c() for (i in 1:1000) out[i] <- i^2 # Fast: allocated once out <- numeric(1000) for (i in 1:1000) out[i] <- i^2
Vòng lặp For trong R: Hướng dẫn nhanh
Tất cả các cấu trúc được sử dụng trong hướng dẫn này đều được liệt kê bên dưới:
| Mục tiêu | Code |
|---|---|
| Lặp qua một vectơ |
for (i in v) { print(i) } |
| Lặp qua các chỉ mục một cách an toàn |
for (i in seq_along(v)) { print(v[i]) } |
| Lặp qua một danh sách |
for (p in my_list) { print(p) } |
| Lặp qua các cột của khung dữ liệu |
for (col in names(df)) { print(mean(df[[col]])) } |
| Lặp qua ma trận |
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c]) |
| Thoát khỏi vòng lặp sớm |
if (condition) break
|
| Bỏ qua một lần lặp |
if (condition) next
|
| Phân bổ trước đầu ra |
out <- numeric(n) |
