بيان IF وELSE وELSE IF في R
⚡ ملخص ذكي
تُحدد عبارات 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') }
الإخراج:
## [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!') }
الإخراج:
## [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) }
الإخراج:
## 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
الإخراج:
## [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() تحذف سمات مثل مستويات العامل وفئة التاريخ من النتيجة، وثانيهما أنها تُقيّم كلا الفرعين لكل عنصر، لذا فهي تُعتبر مُهدرة للموارد عندما يكون أحد الفرعين مُكلفًا. البديل هو مكتبة dplyr case_when() يتجنب التداخل تمامًا ويحافظ على الأنواع سليمة:
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() التعبير عنها. لتطبيق شرط بشكل متكرر على تسلسل، ادمجه مع لحلقة أو حائط اللوب.
منطقي Operaتورس في ظروف R
تتصرف العوامل التي تبني شرطًا ما بشكل مختلف عن بعضها البعض، وهذا الاختلاف مهم.
| المُشغل | معنى | استخدمه في |
|---|---|---|
| & | عملية AND على مستوى العناصر | ifelse()، filter()، المتجهات الكاملة |
| && | بوابة AND أحادية القيمة، دوائر قصر | إذا () و بينما () |
| | | أو على مستوى العنصر | ifelse()، filter()، المتجهات الكاملة |
| || | دائرة أو أحادية القيمة، دوائر قصر | إذا () و بينما () |
| ! | لا، بل ينفي الاختبار | في أى مكان |
| ٪في٪ | هل القيمة موجودة في هذه المجموعة؟ | يستبدل سلاسل 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")) { } |

