R: R تدفق التحكم: if/for/while — العبارات الشرطية والحلقات

آخر تحديث: 2026-08-26

في الدرس السابق، تعرفنا على العوامل الحسابية، وأصبحت برامجنا المكتوبة بلغة R قادرة الآن على «تحديد ما إذا كان شيء ما صحيحًا أم خطأً». لكن مجرد القدرة على اتخاذ مثل هذه القرارات لا تكفي — فالبرامج تحتاج أيضًا إلى أن تكون قادرة على تكرار المهام (الحلقات) واتخاذ قرارات التفرع (الشروط). في هذا الدرس، سنتعرف على «تدفق التحكم» في لغة R: شروط if/else، وحلقات for/while، وعبارة repeat.

يختلف تدفق التحكم في لغة R قليلاً عن لغة Python: تُحيط لغة R كتل التعليمات بـ {} (بدلاً من استخدام المسافة البادئة)، ويُعد جملة if/else بأكملها تعبيرًا واحدًا. في هذا الدرس، سنتعرف على هذه الاختلافات.

1. ما ستتعلمه



2. قصة عن تصفية البيانات

(1) المشكلة: التصنيف اليدوي

شياو تشاو محلل بيانات. طلب منه مديره تصنيف 100 عميل حسب العمر:

إذا كنت تستخدم برنامج Excel، فسيتعين عليك كتابة أربع صيغ IF متداخلة؛ أما إذا كنت تستخدم لغة Python، فسيتعين عليك كتابة حلقات وجمل if-else. لكن لغة R تحتوي على ifelse()، وهي مصممة خصيصًا للمتجهات—

(2) الحل باستخدام لغة R

R
# 5 The age of each customer
ages <- c(15, 22, 35, 50, 65)

# Done in one line of code 4 File Categories(Vectorization ifelse)
labels <- ifelse(ages < 18, "Minor",
          ifelse(ages < 31, "Youth",
            ifelse(ages < 51, "Middle Age", "Old Age")))

cat("Customer Segmentation:\n")
print(data.frame(Age = ages, Category = labels))

حل مشكلة تصنيف ذات 4 فئات باستخدام 3 أسطر فقط من التعليمات البرمجية. هذه هي الميزة «المتجهة» لتدفق التحكم في لغة R — باختصار، كل جملة برمجية هي متجه قرار.



3. if/else: التفرع الشرطي

(1) القواعد الأساسية لعبارة if

R
# R uses { } to enclose a code block (Python uses indentation)
if (Conditions) {
  Execute when the condition is true
}
R
age <- 18

if (age >= 18) {
  cat("You're an adult now.\n")
}
# Output:You're an adult now.

(2) if-else: الاختيار الثنائي

R
if (Conditions) {
  Execute when the condition is true
} else {
  Execute when the condition is false
}
R
score <- 45

if (score >= 60) {
  cat("Passed!\n")
} else {
  cat("Fail,Need to take a makeup exam\n")
}
# Output:Fail,Need to take a makeup exam

(3) if-else if-else: التفرع المتعدد

R
if (Conditions1) {
  Branch1
} else if (Conditions2) {
  Branch2
} else {
  Other
}
R
score <- 85

if (score >= 90) {
  cat("Excellent\n")
} else if (score >= 80) {
  cat("Good\n")
} else if (score >= 60) {
  cat("Passing Grade\n")
} else {
  cat("Fail\n")
}
# Output:Good

(4) الاختلافات الرئيسية بين لغتي R و Python

ميزة R بايثون
كتلة كود {} الأقواس المتعرجة المسافة البادئة (4 مسافات)
إذا كانت الصيغة if (x > 0) { ... } if x > 0:
التعبير بشكل عام إذا كانت عبارة if/else تعبيرًا (قابلة للتعيين) إذا كانت عبارة if/else جملة (غير قابلة للتعيين)
العمليات الثلاثية ifelse() الدوال الخاصة x if x > 0 else -x
R
# R Special Usage of:ifelse It is an expression
result <- if (score >= 60) "Passing Grade" else "Fail"
result
# [1] "Passing Grade"
⚠️ ملاحظة: في لغة R، يجب أن تتضمن عبارة if/else else في نفس السطر (إذا تم التعامل معها كتعبير واحد). وإذا تم تقسيمها على سطرين، فستُبلغ لغة R بحدوث خطأ في بناء الجملة.



4. ifelse(): اتخاذ القرار باستخدام المعالجة المتجهة

(1) لماذا نحتاج إلى ifelse()؟

لا يمكن للمعيار if تقييم سوى قيمة واحدة، ولكن في لغة R، غالبًا ما تحتاج إلى تقييم متجه كامل. في هذه الحالة، استخدم ifelse():

100%
graph LR
    A["x = 1, 2, 3, 4, 5"] --> B["ifelse x > 3 yes no"]
    B --> C["no no no yes yes"]
    
    style A fill:#cce5ff
    style C fill:#d4edda
R
# Regular if It will throw an error(Only accept lengths 1)
x <- c(1, 2, 3, 4, 5)
if (x > 3) "L" else "S"   # Error: condition has length > 1

# Use ifelse() to resolve
ifelse(x > 3, "L", "S")
# [1] "S" "S" "S" "L" "L"

(2) بناء جملة ifelse()

R
ifelse(Conditions, The value when the condition is true, Value when the condition is false)

(3) ifelse() المتداخلة: التصنيف متعدد المستويات

R
ages <- c(15, 22, 35, 50, 65)

# 4 File Categories
labels <- ifelse(ages < 18, "Minor",
          ifelse(ages < 31, "Youth",
            ifelse(ages < 51, "Middle Age", "Old Age")))

print(data.frame(Age = ages, Category = labels))

الناتج:

TEXT 📖 للعرض فقط
  Age  Category
1   15 Minor
2   22   Youth
3   35   Middle Age
4   50   Middle Age
5   65   Old Age
💡 نصيحة: ifelse() إذا كان لديك أكثر من 3 مستويات من التداخل، نوصي باستخدام dplyr::case_when() (الذي تمت مناقشته في الدرس 10) لتحقيق مزيد من الوضوح.



5. حلقة for: التكرار عبر العناصر

(1) القواعد الأساسية لعبارة "for"

R
for (Variable in Vector) {
  Code executed in each iteration
}

(2) التكرار عبر متجه

R
# Iteration 1:5
for (i in 1:5) {
  cat("Iteration", i, "of the loop\n")
}
# Output:
# Iteration 1 of the loop
# Iteration 2 of the loop
# Iteration 3 of the loop
# Iteration 4 of the loop
# Iteration 5 of the loop

# Iterating Through a Character Vector
fruits <- c("Apple", "Banana", "Cherries")
for (fruit in fruits) {
  cat("I like to eat", fruit, "\n")
}

(3) المجموع التراكمي (مثال كلاسيكي)

R
# 1+2+3+...+100
total <- 0
for (i in 1:100) {
  total <- total + i
}
total
# [1] 5050

(4) ⚠️ أداء لغة R ضعيف في الحلقات

تكون حلقات R for أبطأ بـ 10 إلى 100 مرة من حلقات Python. تشجع لغة R على استخدام العمليات المتجهة بدلاً من الحلقات:

R
# Slow (Loop)
system.time({
  total <- 0
  for (i in 1:1e6) {
    total <- total + i
  }
})
# User  System  Passing 
# 0.40   0.00   0.40  ← 0.4 s

# Fast (Vectorization)
system.time({
  total <- sum(1:1e6)
})
# User  System  Passing 
# 0.01   0.00   0.01  <- 0.01 s (40x faster)
⚠️ ملاحظة: تشجع لغة R على اتباع مبدأ "التوجيه المتجه أولاً" — إذا كان بإمكانك حل مشكلة باستخدام sum() mean() ifelse()، فلا تكتب حلقة.



6. حلقة while: الحلقة الشرطية

(1) في حين أن قواعد النحو

R
while (Conditions) {
  Execute repeatedly when the condition is true
}

(2) مثال كلاسيكي: لعبة «تخمين الرقم»

R
# Target Number
target <- 42
guess <- 0
attempts <- 0

while (guess != target) {
  guess <- sample(1:100, 1)  # Guess at Random
  attempts <- attempts + 1
  if (attempts > 1000) break  # More than 1000 Second attempt
}
cat("Used", attempts, "Second guess\n")
▶ جرّب الكود

(3) الاختلافات عن for

ميزة لـ بينما
الغرض الحلقات ذات عدد التكرارات المعروف عدد التكرارات غير المعروف، التي يتم تشغيلها بناءً على شروط
الإنهاء نهاية مسار المتجه الإنهاء بسبب شرط غير صحيح
قابل للتطبيق التمرير عبر البيانات انتظار الأحداث، الاستقصاء


7. تكرار و«break»: الحلقات اللانهائية

(1) repeat قواعد النحو

R
repeat {
  Code
  if (Conditions) break  # Must have break,Otherwise, an infinite loop
}

(2) التدريب العملي: اختيار القائمة

R
choice <- 0
repeat {
  cat("\n=== Main Menu ===\n")
  cat("1. Check the weather\n")
  cat("2. Look up stocks\n")
  cat("0. Exit\n")
  choice <- as.integer(readline("Please select:"))
  
  if (choice == 0) {
    cat("Goodbye!\n")
    break
  } else if (choice == 1) {
    cat("It's sunny today,25°C\n")
  } else if (choice == 2) {
    cat("Shanghai Stock Exchange 3000 pt\n")
  } else {
    cat("Invalid input\n")
  }
}
⚠️ ملاحظة: يجب استخدام repeat بالاقتران مع break؛ وإلا فستحدث حلقة لا نهائية (سيتوقف البرنامج عن العمل).



8. next و break: التحكم في الحلقات

الكلمة المفتاحية الوظيفة السيناريو
next تخطي هذه الجولة والانتقال إلى التالية تخطي بعض العناصر
break الخروج من الحلقة بأكملها الخروج فور العثور على الهدف
R
# next:Skip even numbers
for (i in 1:10) {
  if (i %% 2 == 0) next
  cat(i, " ")
}
# Output:1 3 5 7 9

cat("\n")

# break:Find the first one 7 Just log out
for (i in 1:10) {
  if (i == 7) break
  cat(i, " ")
}
# Output:1 2 3 4 5 6


9. الأخطاء الشائعة

(1) مخاطر المقارنات ذات النقاط العائمة

R
# Seemingly equal,The actual values are not equal
0.1 + 0.2 == 0.3
# [1] FALSE  ← Actually, it is 0.30000000000000004

# The Correct Way to Do It:Comparison of Tolerances
abs(0.1 + 0.2 - 0.3) < 1e-9
# [1] TRUE

(2) يجب أن يكون البيان else في سطر جديد أو في نفس السطر

R
# ❌ Error:else Traveling Alone
if (TRUE) {
  cat("yes")
}
else {
  cat("no")
}
# Error: unexpected 'else' in "else"

# Correct: else must follow if block }
if (TRUE) {
  cat("yes")
} else {
  cat("no")
}
# Output:yes
💡 نصيحة: اكتب } else { في نفس السطر لتجنب أي غموض في التحليل.

(3) إذا لم تتم الطباعة تلقائيًا

R
# In R, if has no "Automatic Printing" (Not like a function call)
if (TRUE) "yes"
# No output  ← Do not print

# Resolve: Use cat() or print() for explicit output
if (TRUE) cat("yes\n")
# Output:yes


10. مثال كامل: إدارة فئات العملاء

فيما يلي مثال على مسار عمل كامل يربط بين جميع مسارات التحكم التي تم تناولها في هذا الدرس.

▶ مثال: تقسيم العملاء واستراتيجيات التسويق

R
# ============================================
# Customer Segmentation and Marketing Strategies
# Features:By age+Classify Customers by Spending Amount
# ============================================

# 1. Preparation 6 Customer Data
customers <- data.frame(
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"),
  age = c(15, 22, 35, 50, 65, 28),
  spend = c(100, 500, 2000, 5000, 10000, 800)
)

# 2. Use ifelse() Batch Grading (Vectorization)
customers$tier <- ifelse(customers$spend < 500, "Regular",
                  ifelse(customers$spend < 3000, "Silver Card",
                    ifelse(customers$spend < 8000, "Gold Card", "Diamond")))

# 3. Go through the customer list,Output Marketing Strategy(for Loop)
cat("=== Customer Segmentation and Marketing Strategies ===\n\n")
for (i in 1:nrow(customers)) {
  name <- customers$name[i]
  age <- customers$age[i]
  spend <- customers$spend[i]
  tier <- customers$tier[i]
  
  # Skip Diamond Members(Optimized)
  if (tier == "Diamond") {
    cat(name, "(", tier, "):", spend, "USD,Existing Customers,Priority Maintenance\n")
    next
  }
  
  # Exit Conditions(Demo break)
  if (spend > 5000) {
    cat(name, ": High-spending customers! Enter VIP Process\n")
  }
  
  # Age-Based Marketing Recommendations
  if (age < 18) {
    cat(name, "(", tier, "):Minor,Recommended Parent Card\n")
  } else if (age < 30) {
    cat(name, "(", tier, "):Youth,New Product Releases\n")
  } else if (age < 50) {
    cat(name, "(", tier, "):Middle Age,Promote Family Plans\n")
  } else {
    cat(name, "(", tier, "):Middle-Aged and Older Adults,Promote Health Products\n")
  }
}
▶ جرّب الكود

النتائج المتوقعة (مقتطف):

TEXT 📖 للعرض فقط
=== Customer Segmentation and Marketing Strategies ===

Alice( Regular ):Minor,Recommended Parent Card
Bob( Regular ):Youth,New Product Releases
Charlie( Silver Card ):Middle Age,Promote Family Plans
Diana( Gold Card ):Middle Age,Promote Family Plans
Eve( Diamond ):10000 USD,Existing Customers,Priority Maintenance
Frank( Silver Card ):Youth,New Product Releases


❓ أسئلة شائعة

س ماذا أفعل إذا كانت حلقة for بطيئة جدًّا؟
ج تشجع لغة R على اتباع مبدأ «التوجيه المتجه أولاً» — فإذا كان بإمكانك حل المشكلة باستخدام sum() mean() ifelse()، فلا تكتب حلقة for. تكون حلقات R أبطأ بـ 10 إلى 100 مرة من لغة Python، لذا استخدمها بحذر عند التعامل مع أكثر من 100,000 عنصر.
س متى يجب استخدام while بدلاً من for؟
ج استخدم while عندما يكون عدد التكرارات غير معروف (على سبيل المثال، انتظار حدث ما، أو لعبة تخمين الأرقام)، واستخدم for عندما يكون عدد التكرارات معروفًا (على سبيل المثال، التكرار على متجه). استخدم repeat + break لـ«الحلقات اللانهائية مع الإنهاء المبكر».

📖 ملخص


📝 تمارين

  1. المشكلة الأساسية: اكتب برنامجًا نصيًّا بلغة R باستخدام if/else if/else لتنفيذ ما يلي: عند إعطاء درجة score، قم بإخراج التقييم (90+: ممتاز، 80+: جيد، 60+: مقبول، بخلاف ذلك: راسب). اختبر البرنامج النصي باستخدام أربع درجات: 95، و75، و60، و40، واحفظ لقطة شاشة للنتيجة.

  2. المسألة الأساسية: استخدم ifelse() لتقسيم المتجه c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) إلى عناصر فردية وزوجية، ثم أخرج النتيجة.

  3. المسألة الأساسية: استخدم for لحساب 5! (مضاعف 5 = 5 × 4 × 3 × 2 × 1) في حلقة متكررة، واحفظ لقطات شاشة للعملية والنتيجة.

  4. تمرين متقدم: اكتب لعبة «تخمين الرقم»: ① استخدم sample(1:100, 1) لتوليد رقم عشوائي بين 1 و100 ليكون الرقم المستهدف؛ ② استخدم while للتكرار عبر مدخلات المستخدم (readline)؛ ③ اعرض التلميح «مرتفع جدًا» أو «منخفض جدًا»؛ ④ عندما يتم تخمين الرقم بشكل صحيح، اعرض «تهانينا! استغرق الأمر N محاولة». قم بتشغيل البرنامج واختباره.

  5. التحدي: اكتب برنامجًا يعالج الأعداد الصحيحة من 1 إلى 100 على النحو التالي: ① تخطي مضاعفات العدد 3 (next)؛ ② الخروج عند الوصول إلى 50 (break)؛ ③ جمع الأعداد المتبقية. تحقق من النتيجة (يجب أن تكون 1+2+4+5+7+8+...+49 = ؟). احفظ لقطة شاشة لبرنامجك والنتيجة.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%