สำหรับ Loop ใน R พร้อมตัวอย่างสำหรับรายการและเมทริกซ์
⚡ สรุปอย่างชาญฉลาด
ลูป for ใน R จะรันบล็อกโค้ดหนึ่งครั้งสำหรับแต่ละองค์ประกอบของลำดับ ไม่ว่าลำดับนั้นจะเป็นเวกเตอร์ รายการ หรือเมทริกซ์ บทความนี้จะวนซ้ำไปทีละกรณีและแสดงให้เห็นว่าเมื่อใดที่การเขียนโค้ดแบบเวกเตอร์เป็นตัวเลือกที่ดีกว่า

A สำหรับห่วง คำสั่งนี้จะทำซ้ำบล็อกโค้ดหนึ่งครั้งสำหรับแต่ละองค์ประกอบของลำดับ ลำดับนั้นอาจเป็นเวกเตอร์ รายการ เฟรมข้อมูล เมทริกซ์ หรือวัตถุอื่นใดที่ R สามารถวนซ้ำได้ R คำนึงถึงตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก ดังนั้นคำหลักจึงเป็นตัวพิมพ์เล็กเสมอ สำหรับและต้องใช้เครื่องหมายวงเล็บปีกกาเมื่อเนื้อหาข้อความยาวเกินหนึ่งบรรทัด
ไวยากรณ์ของลูป for ในภาษา R
for (i in vector) { Exp }
ที่นี่
R จะวนซ้ำตัวแปรทั้งหมดในเวกเตอร์และทำการคำนวณที่เขียนภายใน exp

เรามาดูตัวอย่างกัน
สำหรับการวนซ้ำใน R ตัวอย่างที่ 1: เราวนซ้ำองค์ประกอบทั้งหมดของเวกเตอร์และพิมพ์ค่าปัจจุบัน
# Create fruit vector fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # Create the for statement for ( i in fruit){ print(i) }
Output:
## [1] "Apple" ## [1] "Orange" ## [1] "Passion fruit" ## [1] "Banana"
สำหรับการวนซ้ำใน R ตัวอย่างที่ 2ยกกำลังสองจำนวนเต็มทุกจำนวนตั้งแต่ 1 ถึง 4 แล้วเก็บผลลัพธ์ไว้ในลิสต์
# 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)
Output:
## [1] 1 4 9 16
ลูป for มีประโยชน์ในงานด้านการเรียนรู้ของเครื่อง การปรับค่าพารามิเตอร์การทำให้เป็นระเบียบหมายถึงการทดสอบค่าที่เป็นไปได้หลายค่าและรักษาค่าเหล่านั้นไว้ping คือวิธีที่ทำให้ฟังก์ชันความสูญเสียมีค่าน้อยที่สุด และลูป for เป็นวิธีที่ตรงไปตรงมาที่สุดในการกวาดหาค่าในช่วงนั้น
วิธีการใช้ break และ next ในลูป For
คำหลักสองคำขัดจังหวะลำดับการทำงานปกติของลูป for
- ทำลาย ออกจากลูปทันทีและข้ามองค์ประกอบที่เหลือทั้งหมด
- ถัดไป ละทิ้งองค์ประกอบปัจจุบันและไปยังองค์ประกอบถัดไป
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) }
ในลูปซ้อนกัน ให้ใช้คำสั่ง break และ next เฉพาะกับลูปชั้นในสุดที่บรรจุคำสั่งเหล่านั้นเท่านั้น ในตัวอย่างเมทริกซ์ หากต้องการออกจากทั้งสองลูป ให้ตั้งค่าตัวแปรแฟล็กและตรวจสอบค่าในลูปชั้นนอกด้วย
ใช้ seq_along() สำหรับดัชนี การเขียน for (i in 1:length(x)) ดูเหมือนจะไม่เป็นอันตราย แต่จะล้มเหลวเมื่อใช้กับอ็อบเจ็กต์ว่าง เนื่องจาก 1:0 จะสร้างลำดับ 1, 0 และลูปจะทำงานสองครั้ง ส่วน seq_along(x) จะส่งคืนลำดับว่างแทน ดังนั้นจึงข้ามลูปไปได้อย่างถูกต้อง:
for (i in seq_along(fruit)) { cat(i, fruit[i], '\n') }
วนลูป for ผ่านรายการ
ห้องน้ำping การใช้รายการแบบเดิม ๆ ทำงานเหมือนกับการใช้ห้องน้ำทุกประการping โดยใช้เวกเตอร์เป็นตัวนำ ยกเว้นว่าแต่ละองค์ประกอบสามารถเก็บค่าประเภทที่แตกต่างกันได้:
# 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) }
Output:
## [1] "Apple" "Orange" "Passion fruit" "Banana" ## [1] 10 12 15 ## [1] FALSE
วนลูป for บนเมทริกซ์
เมทริกซ์มีสองมิติ คือ แถวและคอลัมน์ ดังนั้นการวนซ้ำในแต่ละเซลล์จึงต้องใช้ลูป for ซ้อนกันสองชั้น: ลูปภายนอกสำหรับแถว และลูปภายในสำหรับคอลัมน์
# 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]))
Output:
## [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"
วนลูป for บน DataFrame ในภาษา R
ดาต้าเฟรมคือรายการของคอลัมน์ ดังนั้นลูป for ธรรมดาจะวนไปตามคอลัมน์แทนที่จะเป็นแถว ซึ่งโดยปกติแล้วจะเป็นสิ่งที่คุณต้องการ:
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') }
โปรดสังเกตวงเล็บสองชั้น df[[col]] extracts ส่งคืนคอลัมน์เป็นเวกเตอร์ ในขณะที่ df[col] ส่งคืนเฟรมข้อมูลแบบคอลัมน์เดียว ซึ่งฟังก์ชัน mean() ไม่สามารถจัดการได้
ห้องน้ำping ข้ามแถว การประมวลผลแบบวนซ้ำตามแถวนั้นเป็นไปได้ แต่ช้า เนื่องจาก R จะคัดลอกแถวนั้นในทุกรอบการประมวลผล:
for (r in seq_len(nrow(df))) { cat('Row', r, 'sums to', sum(df[r, ]), '\n') }
สำหรับข้อมูลที่มีมากกว่าสองสามพันแถว ควรใช้ rowSums(df), apply(df, 1, sum) หรือ dplyr แทน group_by() และ summarise() ไปป์ไลน์ ซึ่งทั้งหมดนี้ทำงานเหมือนกันโดยไม่ต้องคัดลอกข้อมูล
ลูป For เทียบกับการใช้เวกเตอร์ใน R
R เป็นภาษาที่ใช้การประมวลผลแบบเวกเตอร์: ตัวดำเนินการและฟังก์ชันส่วนใหญ่ของมันทำงานกับเวกเตอร์ทั้งหมดพร้อมกันอยู่แล้วในโค้ด C ที่คอมไพล์แล้ว การวนลูปแบบชัดเจนที่ทำซ้ำการดำเนินการแบบเวกเตอร์ทีละองค์ประกอบนั้นทั้งยาวกว่าและช้ากว่า
# Loop version squares <- c() for (i in 1:4) { squares[i] <- i * i } # Vectorized version, same result squares <- (1:4)^2
| งาน | ห่วง | เทียบเท่าเวกเตอร์ |
|---|---|---|
| การคำนวณเลขคณิตแบบทีละองค์ประกอบ | สำหรับองค์ประกอบแต่ละอย่าง | x * 2, x + y, x^2 |
| ใช้ฟังก์ชันกับแต่ละคอลัมน์ | สำหรับชื่อที่มากกว่า (df) | sapply(df, mean) |
| ใช้ฟังก์ชันกับแต่ละแถว | สำหรับความยาวลำดับเกิน (nrow(df)) | apply(df, 1, sum) |
| สร้างรายการผลลัพธ์ | สำหรับรายการที่มี list[[i]] <- … | ลัปพลี (กริยา, ฉ) |
| การเข้ารหัสแบบมีเงื่อนไข | สำหรับด้วยเงื่อนไขและมิฉะนั้น | ถ้ามิฉะนั้น (เงื่อนไข, a, b) |
เมื่อการใช้ลูปยังคงเป็นคำตอบที่ถูกต้อง ควรใช้ลูป for เมื่อแต่ละรอบขึ้นอยู่กับผลลัพธ์ก่อนหน้า เมื่อคุณเรียกใช้บริการภายนอกหรือเขียนไฟล์ หรือเมื่อความชัดเจนมีความสำคัญมากกว่าความเร็วสำหรับวัตถุขนาดเล็ก
ถ้าจำเป็นต้องใช้ลูป ให้จัดสรรหน่วยความจำล่วงหน้า การขยายขนาดวัตถุภายในลูปจะบังคับให้ R คัดลอกวัตถุนั้นในทุกรอบการทำงาน ดังนั้นควรสร้างวัตถุให้มีขนาดเต็มก่อน:
# 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
ลูป for ใน R: คู่มือฉบับย่อ
โครงสร้างทุกอย่างที่ใช้ในบทเรียนนี้แสดงไว้ด้านล่างนี้:
| วัตถุประสงค์ | Code |
|---|---|
| วนลูปตามเวกเตอร์ |
for (i in v) { print(i) } |
| วนลูปผ่านดัชนีอย่างปลอดภัย |
for (i in seq_along(v)) { print(v[i]) } |
| วนลูปผ่านรายการ |
for (p in my_list) { print(p) } |
| วนลูปผ่านคอลัมน์ของดาต้าเฟรม |
for (col in names(df)) { print(mean(df[[col]])) } |
| วนลูปผ่านเมทริกซ์ |
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c]) |
| ออกจากลูปก่อนกำหนด |
if (condition) break
|
| ข้ามไปหนึ่งรอบ |
if (condition) next
|
| จัดสรรเอาต์พุตล่วงหน้า |
out <- numeric(n) |
