IF, ELSE, ELSE IF คำสั่งในอาร์
⚡ สรุปอย่างชาญฉลาด
คำสั่ง if-else และ else-if ในภาษา R ใช้เลือกบล็อกโค้ดที่จะทำงานโดยอิงจากเงื่อนไขเชิงตรรกะ บทแนะนำนี้จะครอบคลุมรูปแบบสองสาขา รูปแบบหลายสาขา ฟังก์ชัน ifelse() แบบเวกเตอร์ และ switch() สำหรับการจับคู่ที่ตรงกันทุกประการ
คำสั่ง if else ในภาษา R
An ถ้าเป็นอย่างอื่น คำสั่งนี้จะรันโค้ดชุดหนึ่งเมื่อเงื่อนไขเป็นจริง และอีกชุดหนึ่งเมื่อเงื่อนไขเป็นเท็จ ในภาษา R ไวยากรณ์คือ:
if (condition) { Expr1 } else { Expr2 }
ตรวจสอบว่าตัวแปรชื่อ quantity มีค่ามากกว่า 20 หรือไม่ ถ้าใช่ โค้ดจะพิมพ์ “คุณขายได้เยอะมาก!” มิเช่นนั้นจะพิมพ์ “สินค้าไม่พอสำหรับวันนี้”
# Create vector quantity quantity <- 25 # Set the if-else statement if (quantity > 20) { print('You sold a lot!') } else { print('Not enough for today') }
Output:
## [1] "You sold a lot!"
หมายเหตุการเว้นวรรคไม่เปลี่ยนแปลงวิธีการทำงานของโค้ดใน R แต่การเว้นวรรคที่สม่ำเสมอจะช่วยให้เงื่อนไขที่ยาวๆ อ่านง่ายขึ้น นอกจากนี้ โปรดสังเกตว่าวงเล็บปิดและคำว่า else ต้องอยู่บรรทัดเดียวกัน มิฉะนั้น R จะถือว่าบล็อก if เสร็จสมบูรณ์และแสดงข้อผิดพลาด
คำสั่ง else if ในภาษา R
ทดสอบเพิ่มเติมด้วย อื่นถ้าR ไม่มีคีย์เวิร์ด elif นั่นคือ Pythonใน R คุณเขียนคำสองคำแยกกัน และคุณสามารถเพิ่มสาขาได้มากเท่าที่ต้องการ ไวยากรณ์คือ:
if (condition1) { expr1 } else if (condition2) { expr2 } else if (condition3) { expr3 } else { expr4 }
สมมติว่าคุณต้องการผลลัพธ์สามแบบ: พิมพ์น้อยกว่า 20 ครั้ง “ไม่พอสำหรับวันนี้”, พิมพ์ระหว่าง 20 ถึง 30 ครั้ง “วันธรรมดา”, และพิมพ์มากกว่า 30 ครั้ง “เป็นวันที่ยอดเยี่ยม!”
คุณสามารถลองเปลี่ยนปริมาณปริมาณได้
# Create the variable quantity quantity <- 10 # Create multiple condition statement if (quantity < 20) { print('Not enough for today') } else if (quantity >= 20 & quantity <= 30) { print('Average day') } else { print('What a great day!') }
Output:
## [1] "Not enough for today"
2 ตัวอย่าง:
อัตราภาษีมูลค่าเพิ่มแตกต่างกันไปตามประเภทสินค้า ลองนึกภาพสินค้าสามประเภท แต่ละประเภทมีอัตราภาษีของตัวเอง:
| หมวดหมู่ | สินค้า | ภาษีมูลค่าเพิ่ม |
|---|---|---|
| A | หนังสือ นิตยสาร หนังสือพิมพ์ ฯลฯ | 8% |
| B | ผัก เนื้อสัตว์ เครื่องดื่ม ฯลฯ | 10% |
| C | เสื้อยืด กางเกงยีนส์ กางเกง ฯลฯ.. | 20% |
เงื่อนไข else if จะกำหนดอัตราที่ถูกต้องให้กับสินค้าที่ลูกค้าซื้อ:
category <- 'A' price <- 10 if (category =='A'){ cat('A vat rate of 8% is applied.','The total price is',price *1.08) } else if (category =='B'){ cat('A vat rate of 10% is applied.','The total price is',price *1.10) } else { cat('A vat rate of 20% is applied.','The total price is',price *1.20) }
Output:
## A vat rate of 8% is applied. The total price is 10.8
ฟังก์ชัน ifelse() ในรูปแบบเวกเตอร์ใน R
คำสั่ง if จะประมวลผลค่าเพียงค่าเดียวเท่านั้น หากป้อนเวกเตอร์เข้าไป R เวอร์ชัน 4.2 หรือใหม่กว่าจะเกิดข้อผิดพลาด เนื่องจากเงื่อนไขต้องเป็น TRUE หรือ FALSE เพียงค่าเดียว ฟังก์ชัน ifelse() แก้ปัญหานี้โดยการตรวจสอบทุกองค์ประกอบพร้อมกันและส่งคืนเวกเตอร์ที่มีความยาวเท่ากัน
quantities <- c(10, 25, 40, 18) # if cannot do this result <- ifelse(quantities > 20, 'You sold a lot!', 'Not enough for today') result
Output:
## [1] "Not enough for today" "You sold a lot!" "You sold a lot!" ## [4] "Not enough for today"
อาร์กิวเมนต์ทั้งสามได้แก่ การทดสอบ ค่าที่ส่งคืนเมื่อการทดสอบเป็นจริง และค่าที่ส่งคืนเมื่อการทดสอบเป็นเท็จ ทั้งสามค่าจะถูกนำกลับมาใช้ใหม่ให้มีความยาวเท่ากัน
การใช้ ifelse() ซ้อนกันจะสร้างลำดับของ else if ขึ้นมาตลอดทั้งเวกเตอร์:
ifelse(quantities < 20, 'Not enough for today', ifelse(quantities <= 30, 'Average day', 'What a great day!'))
มีข้อจำกัดสองประการที่ควรทราบ คือ ifelse() จะตัดแอตทริบิวต์ เช่น ระดับปัจจัยและคลาส Date ออกจากผลลัพธ์ และจะประเมินทั้งสองสาขาสำหรับทุกองค์ประกอบ ดังนั้นจึงสิ้นเปลืองเมื่อสาขาใดสาขาหนึ่งมีค่าใช้จ่ายสูง ทางเลือกอื่นคือ dplyr กรณี_เมื่อ() หลีกเลี่ยงการซ้อนโครงสร้างโดยสิ้นเชิงและคงประเภทข้อมูลไว้เหมือนเดิม:
library(dplyr) case_when( quantities < 20 ~ 'Not enough for today', quantities <= 30 ~ 'Average day', TRUE ~ 'What a great day!' )
คำสั่ง switch() ในภาษา R
เมื่อแต่ละสาขาทดสอบความเท่าเทียมกันของตัวแปรเดียวกัน การใช้คำสั่ง else if ที่ยาวเหยียดจะทำให้ยากต่อการอ่าน ฟังก์ชัน switch() จะเข้ามาแทนที่ด้วยการค้นหาเพียงครั้งเดียว
category <- 'A' price <- 10 vat <- switch(category, 'A' = 1.08, 'B' = 1.10, 'C' = 1.20, 1.20) # the unnamed last value is the default cat('The total price is', price * vat)
มีกฎสามข้อที่ควบคุมพฤติกรรมของมัน:
- เมื่อส่งอาร์กิวเมนต์เป็นอักขระ ฟังก์ชัน switch() จะจับคู่ชื่ออย่างแม่นยำ ไม่มีการจับคู่บางส่วนและไม่มีการจับคู่ตามรูปแบบ
- องค์ประกอบสุดท้ายที่ไม่มีชื่อจะทำหน้าที่เป็นค่าเริ่มต้น หากไม่มีองค์ประกอบดังกล่าว ค่าที่ไม่ตรงกันจะส่งคืนค่า NULL โดยไม่แสดงให้เห็น ซึ่งเป็นสาเหตุทั่วไปของข้อผิดพลาดที่มองไม่เห็น
- เมื่อส่งค่าจำนวนเต็มเป็นอาร์กิวเมนต์ ฟังก์ชัน switch() จะเลือกตามตำแหน่งแทน: switch(2, “a”, “b”, “c”) จะคืนค่า “b”
ใช้ switch() สำหรับการจับคู่ที่ตรงกันทุกประการกับชุดค่าที่กำหนดไว้ และใช้ else if สำหรับช่วงค่าและเงื่อนไขที่ซับซ้อน ซึ่ง switch() ไม่สามารถแสดงได้ ในการใช้เงื่อนไขซ้ำๆ กับลำดับ ให้รวมเงื่อนไขนั้นเข้ากับ else if สำหรับห่วง หรือ ในขณะที่วนซ้ำ.
ตรรกะ Operaทอร์ในเงื่อนไข R
ตัวดำเนินการที่สร้างเงื่อนไขนั้นมีพฤติกรรมแตกต่างกัน และความแตกต่างนั้นมีความสำคัญ
| OperaTor | ความหมาย | ใช้ใน |
|---|---|---|
| & | องค์ประกอบและ | ifelse(), filter(), เวกเตอร์ทั้งหมด |
| && | AND ค่าเดียว, ลัดวงจร | ถ้า () และในขณะที่ () |
| | | OR ตามองค์ประกอบ | ifelse(), filter(), เวกเตอร์ทั้งหมด |
| || | OR ค่าเดียว, วงจรลัด | ถ้า () และในขณะที่ () |
| ! | ไม่ใช่ ปฏิเสธการทดสอบ | ทุกแห่ง |
| %ใน% | ค่าในชุดนี้ใช่หรือไม่? | ใช้แทนโซ่ยาวแบบ OR |
เหตุใดการลัดวงจรจึงมีความสำคัญ สมการแบบสองทางจะหยุดทำงานทันทีที่ได้คำตอบ ดังนั้นด้านขวาจะไม่ถูกประเมินอีกเลยเมื่อด้านซ้ายตัดสินผลลัพธ์ไปแล้ว ซึ่งทำให้สามารถเขียนเงื่อนไขป้องกันได้อย่างปลอดภัย:
# Safe: length() is checked before x[1] is touched if (length(x) > 0 && x[1] > 10) print('ok')
เปรียบเทียบกับค่าต่างๆ หลายค่า เลือกใช้ %in% แทนการใช้การทดสอบความเท่าเทียมกันแบบต่อเนื่อง ซึ่งทั้งสั้นกว่าและพิมพ์ผิดยากกว่า:
if (category %in% c('A', 'B')) { print('Reduced VAT rate applies') }
คำเตือนสุดท้าย: เครื่องหมายเท่ากับตัวเดียวใช้สำหรับกำหนดค่า ไม่ใช่การเปรียบเทียบ ควรเขียน == ไว้ภายในเงื่อนไขเสมอ
คำสั่งเงื่อนไขใน R: คู่มืออ้างอิงฉบับย่อ
โครงสร้างทุกอย่างที่ใช้ในบทเรียนนี้แสดงไว้ด้านล่างนี้:
| วัตถุประสงค์ | Code |
|---|---|
| สองสาขา |
if (cond) { a } else { b } |
| หลายสาขา |
if (c1) { a } else if (c2) { b } else { c } |
| เงื่อนไขเวกเตอร์ |
ifelse(test, yes, no)
|
| กิ่งก้านหลายกิ่งบนเวกเตอร์ |
case_when(c1 ~ a, c2 ~ b, TRUE ~ c)
|
| การค้นหาแบบตรงกันทุกประการ |
switch(x, "A" = 1, "B" = 2, 0) |
| การทดสอบสมาชิกภาพ |
if (x %in% c("A", "B")) { } |


