IF, ELSE, ELSE IF คำสั่งในอาร์

⚡ สรุปอย่างชาญฉลาด

คำสั่ง if-else และ else-if ในภาษา R ใช้เลือกบล็อกโค้ดที่จะทำงานโดยอิงจากเงื่อนไขเชิงตรรกะ บทแนะนำนี้จะครอบคลุมรูปแบบสองสาขา รูปแบบหลายสาขา ฟังก์ชัน ifelse() แบบเวกเตอร์ และ switch() สำหรับการจับคู่ที่ตรงกันทุกประการ

  • 🔀 ไวยากรณ์หลัก: ถ้า (เงื่อนไข) { } มิเช่นนั้น { } จะเรียกใช้สาขาหนึ่งเมื่อเงื่อนไขเป็นจริง และเรียกใช้สาขาอื่นเมื่อเงื่อนไขเป็นเท็จ
  • 🔗 หลายสาขา: R เขียน else if เป็นสองคำแยกกัน ไม่มีคำหลัก elif เหมือนในภาษาอื่น Python.
  • ⚠️ การดูแลขอบเขต: ใช้เงื่อนไขมากกว่าหรือเท่ากับ และน้อยกว่าหรือเท่ากับ เพื่อป้องกันไม่ให้ค่าใดๆ ตกหล่นไปในช่องว่างที่ไม่ต้องการระหว่างสาขาต่างๆ
  • ⚡ รูปแบบเวกเตอร์: คำสั่ง ifelse(test, yes, no) จะประเมินเวกเตอร์ทั้งหมดในครั้งเดียว ซึ่งคำสั่ง if ทั่วไปทำไม่ได้
  • 🗂️ การจับคู่ที่แน่นอน: switch() จะแทนที่การทดสอบความเท่าเทียมกันที่ยาวเหยียดด้วยการค้นหาเพียงครั้งเดียว
  • 🧮 Operaตัวเลือกสำหรับ: เครื่องหมายแอมเปอร์แซนด์เดี่ยวใช้สำหรับกำหนดค่า TRUE หรือ FALSE เพียงค่าเดียวภายในเงื่อนไข if

คำสั่ง If Else Else If ในภาษา R

คำสั่ง 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")) { }

คำถามที่พบบ่อย

`if` จัดการค่า `TRUE` หรือ `FALSE` เพียงค่าเดียว และควบคุมว่าโค้ดส่วนใดจะทำงาน `ifelse()` เป็นฟังก์ชันแบบเวกเตอร์ที่ทดสอบทุกองค์ประกอบในเวกเตอร์และส่งคืนเวกเตอร์ของผลลัพธ์

ใช้รูปแบบคู่ภายในคำสั่ง if และ while ซึ่งเงื่อนไขต้องมีค่าเดียว และการลัดวงจรจะช่วยป้องกันด้านขวามือ ใช้รูปแบบเดี่ยวสำหรับการทดสอบแบบทีละองค์ประกอบบนเวกเตอร์ทั้งหมด

ตั้งแต่ R เวอร์ชัน 4.2 เงื่อนไข if ต้องมีค่า TRUE หรือ FALSE เพียงค่าเดียวเท่านั้น เวกเตอร์ที่ยาวกว่านั้นจะทำให้เกิดข้อผิดพลาดแทนที่จะเป็นคำเตือน ให้ใช้ ifelse(), any() หรือ all() ขึ้นอยู่กับสิ่งที่คุณต้องการ

เงื่อนไขต่างๆ เป็นตัวกำหนดกฎเกณฑ์ด้านวิศวกรรมคุณลักษณะและการหยุดก่อนกำหนดping ตรวจสอบระหว่างการฝึกอบรม และตัดสินใจเกี่ยวกับเกณฑ์ผลลัพธ์ของโมเดล รูปแบบเวกเตอร์ เช่น case_when() เป็นที่นิยมมากกว่า เนื่องจากสามารถรองรับชุดข้อมูลทั้งหมดได้

ใช่แล้ว ผู้ช่วย AI สามารถตรวจจับช่องโหว่ต่างๆ ได้ เช่น ค่าขอบเขตที่ทับซ้อนกับทุกสาขา หรือเครื่องหมายเท่ากับตัวเดียวที่ใช้ในการเปรียบเทียบ ลองทดสอบการแก้ไขห่วงโซ่ด้วยค่าขอบเขตด้วยตัวคุณเอง

สรุปโพสต์นี้ด้วย: