الإحصاء التطبيقيتحليل البياناتلغة R

كيفية استخدام دالتي Min و Max في لغة R (مع أمثلة)

دليل شامل ومفصل حول كيفية استخدام دالتي min و max في لغة R لحساب القيم الصغرى والعظمى للمتجهات وإطارات البيانات مع أمثلة تطبيقية متقدمة.

تاريخ النشر

تُعد لغة البرمجة الإحصائية R Project for Statistical Computing البيئة البرمجية الأكثر رسوخاً ومرونة في ميدان تحليل البيانات والنمذجة الرياضية والقياس النفسي والسلوكي. وتعتمد قوة هذه اللغة في جوهرها على بنيتها المتجهية الفائقة، وتوفيرها لترسانة هائلة من الدوال الرياضية والإحصائية المبنية داخل نواتها التأسيسية، والتي تتيح للمحللين والباحثين استنطاق البيانات واختبار الفرضيات بدقة حوسبية متناهية. ومن بين هذه الدوال التأسيسية، تبرز دالتا حساب القيم الصغرى والقصوى كأداتين لا غنى عنهما في فحص التوزيعات واستكشاف خصائص العينات وضبط النطاقات القياسية للمتغيرات الكمية والنوعية.

إن التعامل مع المقاييس الإحصائية للحدود لا يقتصر فقط على استخراج أصغر رقم أو أكبر قيمة عددية مجردة، بل يمتد ليشمل فهم البنية الهيكلية الشاملة للبيانات المعقدة، والتحقق من موثوقية استجابات المفحوصين في الدراسات الميدانية، وتطهير مجموعات البيانات الضخمة من القيم المتطرفة وأخطاء الإدخال الرقمي. ومن هذا المنطلق، فإن الإحاطة التامة بكيفية استخدام دالتي min() و max()، إلى جانب الدوال الشقيقة المتوازية والفهرسية، تمثل الركيزة الأولى لأي باحث يسعى إلى بناء خوارزميات تحليلية محكمة وقابلة للتكرار العلمي.

يتناول هذا الدليل الأكاديمي الشامل استعراضاً معمقاً وتطبيقياً لآليات توظيف دالتي min() و max() في لغة R، بدءاً من الأسس الرياضية والنحوية لتنفيذهما على المتجهات البسيطة، مروراً بإدارة المشكلات الحوسبية المعقدة كالقيم المفقودة وتفاوت الأنماط البيانية، وصولاً إلى تطبيقاتهما المتقدمة في إطارات البيانات متعددة الأبعاد، والتحليلات التجميعية الفئوية، والتطبيع الرياضي للمتغيرات النفسية، مع استعراض شامل للأخطاء الشائعة وطرق تفاديها وفق أفضل الممارسات البرمجية المعتمدة دولياً.

1. مقدمة عامة حول الدوال الإحصائية الأساسية في لغة البرمجة R

1.1 أهمية مقاييس النطاق والحدود في التحليل الإحصائي

تشكل مقاييس النطاق والحدود القصوى والدنيا حجر الزاوية في الإحصاء الوصفي (Descriptive Statistics) والتحليل الاستكشافي للبيانات (Exploratory Data Analysis). فعند فحص أي ظاهرة كمية، لا تكفي مقاييس النزعة المركزية مثل المتوسط الحسابي والوسيط لتقديم صورة متكاملة عن طبيعة المتغير المدروس، بل يتعين على الباحث فحص حدود التشتت لمعرفة النطاق الحسابي الكلي الذي تتحرك ضمنه المشاهدات. إن معرفة أدنى قيمة وأعلى قيمة توفر فهماً أولياً وشاملاً لمدى انتشار البيانات ودرجة تباينها، مما يساعد في تكوين فرضيات دقيقة حول شكل التوزيع الاحتمالي للمتغيرات وما إذا كانت تقترب من التوزيع الطبيعي الاعتدالي أو تعاني من التواءات حادة نحو أحد الطرفين.

وتبرز الأهمية التشخيصية لهذه الدوال الاستكشافية في مراحل تنظيف البيانات والتحقق من جودتها؛ إذ تتيح الحدود الدنيا والقصوى الكشف الفوري عن الأخطاء المدخلة بشرياً أو برمجياً. فعلى سبيل المثال، إذا كان المقياس المستخدم في دراسة نفسية يتراوح نظرياً بين درجة 1 و 7، فإن تسجيل قيمة دنيا تساوي الصفر أو قيمة قصوى تصل إلى 77 يشير مباشرة إلى خلل في رقمنة الاستجابات. وعلاوة على ذلك، تلعب الدوال الحدية دوراً محورياً في الدراسات السلوكية والعلوم المعرفية، حيث يُستفاد منها في تحديد أزمنة الرجع الدنيا والقصوى للمهام الإدراكية، مما يسهم في فرز الأداء الحركي النمطي عن الاستجابات العشوائية أو فترات التشتت الذهني غير المرغوبة.

1.2 التعريف التقني لدالتي min() و max() في بيئة R

تُعرف دالتا min() و max() برمجياً في لغة R كدوال حسابية أساسية متضمنة داخل الحزمة القياسية base، وهي حزمة يتم تحميلها تلقائياً عند بدء كل جلسة عمل دون الحاجة إلى استدعاء مكتبات خارجية. تُصنف هاتان الدالتان ضمن دوال التجميع القياسي (Summary Functions)، حيث تستقبلان متجهات أو كائنات حسابية متعددة وتنتجان في المقابل قيمة قياسية مفردة (Scalar) تمثل القيمة المتطرفة المطلوبة. تم تصميم هذه الدوال بلغات منخفضة المستوى مثل C و Fortran لضمان سرعة التنفيذ الحوسبي واستهلاك الحد الأدنى من موارد الذاكرة العشوائية.

تتميز الدالتان بكفاءة خوارزمية عالية تعتمد على المرور الخطي الأحادي عبر عناصر المتجه (Time Complexity: O(n))، مما يجعلهما متفوقتين بشكل قاطع على الخوارزميات المكتوبة يدوياً باستخدام الحلقات التكرارية (Loops) مثل for أو while. إن الاعتماد على المعالجة البرمجية المتجهية الأصلية المضمنة في بيئة CRAN يضمن تقليص الزمن اللازم لمعالجة ملايين المشاهدات في التطبيقات الإحصائية الكبرى، مما يوفر بيئة حسابية قوية ومستقرة تلبي متطلبات الأبحاث الأكاديمية المعاصرة في تنقيب البيانات والنمذجة التنبؤية.

2. البنية النحوية والصياغة البرمجية لدالتي min() و max()

2.1 الصيغة التركيبية العامة (Syntax) والوسائط الأساسية

تتسم الصيغة التركيبية لدالتي min() و max() بالبساطة والمرونة العالية؛ إذ تأخذ كل دالة الصيغة العامة الموضحة في الكود التالي:

min(..., na.rm = FALSE)
max(..., na.rm = FALSE)

حيث يمثل الوسيط النمطي الأول ... إمكانية تمرير عدد غير محدد من الكائنات الحسابية، سواء كانت متجهات عددية فردية، أو قوائم من المتغيرات المتعددة، أو حتى مصفوفات وأطر بيانات رقمية. تقوم الدالة داخلياً بدمج كافة المدخلات في بنية موحدة متصلة قبل الشروع في تقييم عناصرها ومقارنتها لاستخراج النهاية المطلوبة.

أما الوسيط المنطقي الثاني na.rm (وهو اختصار للعبارة الإنجليزية NA remove)، فيمثل أحد أهم المعاملات الضابطة للوظيفة الإحصائية في لغة R. يأخذ هذا المعامل قيمة افتراضية هي FALSE، مما يعني أن الدالة ستتوقف عن استخراج القيمة العددية وتُرجع NA إذا صادفت أي خلية مفقودة داخل المتجه. وعند ضبط هذا المعامل إلى na.rm = TRUE، تصدر الدالة تعليمات لمعالج الحوسبة باستبعاد كافة القيم غير المعرفة قبل البدء في المقارنة الرياضية، مما يضمن تدفق التحليلات واستخراج الحدود الصغرى والعظمى دون توقف الخوارزميات.

2.2 الأنماط البيانية المتوافقة مع الدالتين

لا تنحصر قابلية تطبيق دالتي min() و max() في التعامل مع الأرقام الحقيقية المتصلة فحسب، بل تمتد لتشمل طيفاً واسعاً من الأنماط البيانية المعترف بها في لغة R. تتوافق الدالتان بصورة طبيعية مع المتجهات العددية العشرية (Numeric/Double) والأعداد الصحيحة (Integer)، حيث تطبقان المقارنات الرياضية المعيارية لترتيب الأعداد على خط الأعداد الحقيقي بدقة متناهية.

وعلاوة على ذلك، تتعامل الدالتان بكفاءة مع المتغيرات المنطقية (Logical vectors) المكونة من القيمتين TRUE و FALSE، حيث تعامل لغة R القيمة المنطقية TRUE على أنها تعادل الرقم 1، بينما تعامل FALSE على أنها تعادل الرقم 0، وبالتالي فإن تطبيق دالة min() على متجه منطقي يحتوي على قيمة سالبة واحدة على الأقل سيعيد FALSE. كما تدعم الدالتان سلاسل المحارف والنصوص (Character vectors)، والمتغيرات الزمنية والتواريخ (Date & POSIXct)، والمتغيرات الفئوية المرتبة (Ordered Factors)، مستندة في ذلك إلى قواعد الترتيب المعجمي والزمني كما سيتم تفصيله لاحقاً في هذا الدليل.

3. تطبيق دالتي min() و max() على المتجهات العددية البسيطة

3.1 حساب القيمة الدنيا باستخدام دالة min()

يمثل المتجه العددي الأحادي البنية الأساسية لتخزين البيانات في لغة R. لتطبيق دالة min()، يتم إنشاء متجه يحتوي على قياسات عددية ثم تمريره مباشرة كمعامل للدالة. على سبيل المثال، في دراسة تقيس درجات التوتر النفسي لدى مجموعة من المفحوصين باستخدام مقياس كمي تتراوح درجاته بين 10 و 100، يمكن تمثيل البيانات وتنفيذ العملية الحسابية كما يلي:

stress_scores <- c(45, 78, 23, 89, 12, 67, 34, 90, 15)
lowest_score <- min(stress_scores)
print(lowest_score)

عند تنفيذ هذه الشيفرة البرمجية، تُرجع الدالة القيمة 12 كأدنى درجة مسجلة في العينة. تقوم الآلية الداخلية للدالة بمسح المتجه تسلسلياً ومقارنة كل عنصر بالقيمة الصغرى المؤقتة المحفوظة في مسجل الذاكرة، فإذا كان العنصر الجديد أصغر، يتم استبدال القيمة السابقة به، حتى الوصول إلى نهاية المتجه. يُعد هذا الإجراء خطوة أولية جوهرية لتقييم الحد الأدنى من الأداء السلوكي أو الاستجابة العاطفية لدى المشاركين في الأبحاث النفسية والتجريبية.

3.2 حساب القيمة القصوى باستخدام دالة max()

بالمثل، تُستخدم دالة max() لاستخراج الحد الأقصى من القياسات العددية المتاحة. في السياق البحثي السلوكي، يُستخدم هذا الإجراء لمعرفة أعلى مستوى من الاستجابة أو الحد الأقصى للأداء العقلي المسجل خلال الاختبارات المعيارية. يمكن تطبيق الدالة على المتجه السابق نفسه لاستخراج أعلى درجة توتر مسجلة عبر الشيفرة الآتية:

highest_score <- max(stress_scores)
print(highest_score)

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

3.3 حساب المدى الإحصائي (Range) بالدمج بين الدالتين

يُعرف المدى الإحصائي (Range) بأنه الفارق المطلق بين النهايتين العظمى والصغرى للتوزيع، وهو أبسط مقاييس التشتت الرياضي. توفر لغة R دالة مدمجة باسم range() تُرجع متجهاً ثنائياً يتكون من القيمة الدنيا والقصوى معاً، كالتالي:

score_limits <- range(stress_scores)
print(score_limits)

حيث تنتج الدالة المتجه c(12, 90). ولحساب المدى كقيمة عددية مفردة تمثل الفارق الفعلي بين القطبين، يمكن للباحث الجمع بين دالتي max() و min() في معادلة حسابية مباشرة، أو استخدام دالة diff() على مخرجات دالة المدى:

statistical_range <- max(stress_scores) - min(stress_scores)
alternative_range <- diff(range(stress_scores))
print(statistical_range)

يُظهر الناتج الحسابي القيمة 78، وهي تشير إلى اتساع الفجوة بين أدنى المفحوصين توتراً وأعلاهم، مما يعطي مؤشراً سريعاً للتباين الداخلي للمجموعة قبل المضي قدماً في حساب الانحراف المعياري (Standard Deviation) والتباين الإحصائي.

4. إدارة القيم المفقودة (NA) والمعالجة المتقدمة للبيانات

4.1 تأثير القيم المفقودة على مخرجات الدوال الحسابية

تُعد مشكلة البيانات المفقودة (Missing Data)، والتي يُرمز لها في لغة R بالرمز NA (اختصاراً لـ Not Available)، من أكثر التحديات شيوعاً في البحوث التجريبية والميدانية؛ حيث يمتنع بعض المشاركين عن الإجابة على بعض البنود، أو يحدث خلل تقني أثناء تسجيل القياسات الآلية. تتبع لغة R فلسفة صارمة في الحفاظ على النزاهة الإحصائية؛ فإذا احتوى المتجه على أي قيمة مفقودة، فإن نتيجة min() أو max() ستكون تلقائياً NA:

incomplete_data <- c(14, 28, NA, 45, 19, NA, 33)
res_min <- min(incomplete_data)
print(res_min)

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

4.2 استخدام المعامل na.rm = TRUE لتجاوز الفقد البياني

عندما يقرر الباحث الإحصائي أن القيم المفقودة تحدث بصورة عشوائية تماماً (Missing Completely at Random – MCAR) وأن استبعادها لا يخل بالتمثيل الإحصائي للعينة، يمكنه تفعيل المعامل المنطقي na.rm = TRUE لإلغاء تأثير الخلايا الفارغة وإجراء المقارنة على المشاهدات المتوفرة فقط:

valid_min <- min(incomplete_data, na.rm = TRUE)
valid_max <- max(incomplete_data, na.rm = TRUE)
print(valid_min)
print(valid_max)

تُرجع هذه الأوامر القيمتين 14 و 45 على التوالي. ومع ذلك، يجب توخي الحذر الشديد عند التعامل مع متجهات تتكون بالكامل من قيم مفقودة؛ فإذا طُبقت الدالة مع الوسيط na.rm = TRUE على متجه لا يحتوي سوى على NA، فإن لغة R ستُرجع تحذيراً مفاده غياب المدخلات غير المفقودة، وستكون النتيجة الحسابية Inf (اللانهاية الإيجابية) في حالة min()، و -Inf (اللانهاية السلبية) في حالة max()، وهو سلوك رياضي اصطلاحي يتطلب معالجة دفاعية مسبقة في الشيفرات البرمجية لتجنب تداعياته في المعادلات اللاحقة.

4.3 استراتيجيات المعالجة المسبقة للبيانات قبل حساب الحدود

بدلاً من الاعتماد الحصري على وسيط التجاوز na.rm = TRUE، يُفضل في الممارسات البرمجية المتقدمة تنقية البيانات وفحص جودتها مسبقاً باستخدام الدوال الاستكشافية المساعدة. توفر دالة is.na() القدرة على تحديد مواقع الفقد وعزلها كمياً، بينما تتيح دالة complete.cases() تصفية المتجهات والمصفوفات من السجلات غير المكتملة:

clean_data <- incomplete_data[!is.na(incomplete_data)]
filtered_min <- min(clean_data)
filtered_max <- max(clean_data)

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

5. استخراج القيم الدنيا والقصوى من إطارات البيانات (Data Frames)

5.1 تطبيق الدوال على كامل إطار البيانات الحسابي

في التطبيقات الواقعية، تُخزن معظم البيانات في هياكل جدولية تُعرف بإطارات البيانات (Data Frames)، حيث تمثل الأعمدة المتغيرات وتمثل الصفوف الحالات أو المشاركين. إذا كان إطار البيانات متجانساً ويحتوي حصراً على متغيرات رقمية (Numerical Data Frame)، يمكن تمرير الجدول كاملاً إلى دالتي min() و max() لاستخراج القيمة المطلقة عبر كامل المصفوفة:

exam_results <- data.frame(Math = c(85, 92, 78), Physics = c(88, 79, 95), Chemistry = c(90, 84, 82))
absolute_min <- min(exam_results)
absolute_max <- max(exam_results)

يُرجع هذا التطبيق أدنى درجة وأعلى درجة مسجلة في كافة الاختبارات والمشاركين (وهما 78 و 95). ومع ذلك، إذا احتوى إطار البيانات على عمود غير رقمي (مثل أسماء الطلاب أو معرفات المشاركين الفئوية)، فإن محاولة تطبيق الدوال على الجدول كاملاً ستؤدي إما إلى خطأ نحوي أو إلى تطبيق الترتيب الأبجدي على الأعمدة، مما يستوجب قصر الحسابات على الأعمدة الرقمية الفرعية عبر التحديد الشرطي للأعمدة.

5.2 حساب القيم الدنيا والقصوى لأعمدة محددة (Specific Columns)

تتمثل الممارسة القياسية في تحليل البيانات في استخراج القيم الحدية لمتغير محدد ومستقل بذاته داخل إطار البيانات. تتيح لغة R عدة طرق للإشارة المرجعية إلى الأعمدة، وأشهرها استخدام عامل الدولار $ أو استخدام الأقواس المربعة المفهرسة [[]]:

min_math <- min(exam_results$Math, na.rm = TRUE)
max_physics <- max(exam_results[["Physics"]], na.rm = TRUE)

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

5.3 حساب القيم عبر الصفوف والأعمدة باستخدام دوال apply

عند الرغبة في حساب القيمة الدنيا أو القصوى لكل مشارك على حدة عبر مجموعة من البنود (الحساب عبر الصفوف – Row-wise)، أو حساب الحدود لكل متغير على حدة دفعة واحدة (الحساب عبر الأعمدة – Column-wise)، تُعد عائلة دوال apply الأداة الأكثر فاعلية في البيئة الأساسية لـ R:

row_minimums <- apply(exam_results, 1, min)
column_maximums <- apply(exam_results, 2, max)

في دالة apply، يمثل المعامل 1 توجيهاً للدالة لتنفيذ العملية الحسابية عبر الصفوف الأفقية، مما ينتج متجهاً يحتوي على أدنى درجة حققها كل طالب في اختباراته المختلفة. بينما يوجه المعامل 2 الدالة للتنفيذ عبر الأعمدة الرأسية، مما يعيد أعلى درجة مسجلة في كل مادة دراسية على حدة. يختزل هذا الأسلوب البرمجي عشرات الأسطر من الحلقات التكرارية المعقدة، ويقدم حلاً متجهياً أنيقاً وسريعاً لمعالجة المصفوفات والاستجابات الاستبيانية المتعددة.

6. التحليل الإحصائي المقسم حسب المجموعات (Grouped Aggregation)

6.1 استخدام دالة aggregate() لحساب القيم الحدية حسب الفئات

في التصاميم التجريبية والبحوث المقارنة، غالباً ما يحتاج الباحث إلى استخراج القيم الدنيا والقصوى لمتغير تابع مقسمة حسب مستويات متغير تصنيفي مستقل (مثل المقارنة بين المجموعة التجريبية والمجموعة الضابطة، أو بين الذكور والإناث). توفر الدالة المدمجة aggregate() صياغة تركيبية تعتمد على المعادلات الرياضية (Formula syntax) لتحقيق هذا الغرض:

clinical_trial <- data.frame(Group = c("Control", "Control", "Treatment", "Treatment", "Control", "Treatment"), ReactionTime = c(250, 310, 180, 210, 290, 195))
group_min <- aggregate(ReactionTime ~ Group, data = clinical_trial, FUN = min)
group_max <- aggregate(ReactionTime ~ Group, data = clinical_trial, FUN = max)

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

6.2 توظيف حزمة dplyr وحزم tidyverse في الحساب التجميعي

تُعد منظومة Tidyverse، وخاصة حزمة dplyr، المعيار الحديث الأكثر استخداماً في تنظيف وهيكلة البيانات في لغة R. توفر الحزمة نهجاً انسيابياً قائماً على خطوط الأنابيب البرمجية (Pipes %>% أو |>) يجمع بين دالتي group_by() و summarize():

library(dplyr)
summary_table <- clinical_trial %>%
  group_by(Group) %>%
  summarize(Min_Time = min(ReactionTime, na.rm = TRUE), Max_Time = max(ReactionTime, na.rm = TRUE), Range_Time = max(ReactionTime, na.rm = TRUE) - min(ReactionTime, na.rm = TRUE))

يتميز هذا الأسلوب بقابليته العالية للقراءة والفهم، ويتيح بناء جداول تلخيصية متعددة المؤشرات في خطوة برمجية واحدة، حيث يتم دمج القيم الدنيا والقصوى والمدى الإحصائي والانحرافات المعيارية معاً، مما يسهل تصدير هذه المخرجات مباشرة إلى تقارير النشر العلمي وجداول صيغة APA القياسية.

6.3 استخدام دالة tapply() لعمليات التقسيم السريع

تُمثل دالة tapply() الخيار الأسرع والأنسب في لغة R الأساسية لتطبيق الدوال الإحصائية على متجهات متصلة مقسمة بعوامل فئوية دون الحاجة إلى إنشاء هياكل بيانات جديدة. تأخذ الدالة الصيغة البسيطة الآتية:

min_by_group <- tapply(clinical_trial$ReactionTime, clinical_trial$Group, min)
max_by_group <- tapply(clinical_trial$ReactionTime, clinical_trial$Group, max)

تُرجع دالة tapply() مصفوفة أو متجهاً مسمى (Named Vector) يحتوي على النتائج المحسوبة لكل فئة بشكل مباشر. تتفوق هذه الدالة على الدوال الهيكلية الأخرى في سرعتها الفائقة عند التعامل مع مجموعات البيانات الكبيرة جداً، وتوفر للمبرمج مرونة عالية في إدراج العمليات الحسابية السريعة ضمن الدوال المخصصة والنماذج الرياضية المعقدة.

7. المقارنة التفصيلية بين الدوال المجمعة min/max والدوال المتوازية pmin/pmax

7.1 المفهوم الرياضي والبرمجي للدوال المتوازية (Parallel Min/Max)

يقع الكثير من مبرمجي لغة R المبتدئين في خلط منهجي بين الدوال التجميعية min() و max() وبين الدوال المتوازية pmin() و pmax() (Parallel Minimum / Maximum). تكمن النقطة الجوهرية في أن الدالتين التجميعيتين تقومان بدمج كافة المدخلات واستخراج قيمة قياسية وحيدة تمثل الحد المطلق لجميع البيانات الممررة، بينما تقوم الدوال المتوازية بإجراء مقارنة عنصر بخطوة (Element-wise comparison) عبر عدة متجهات متساوية الطول لتوليد متجه جديد يحمل القيم المتطرفة المقابلة لكل موضع ترتيبي.

إن الوظيفة الرياضية لـ pmin(v1, v2) هي مقارنة العنصر الأول من v1 بالعنصر الأول من v2 واختيار الأصغر بينهما، ثم مقارنة العنصر الثاني بالثاني، وهكذا حتى نهاية المتجهات. يُعد هذا النمط الحوسبي ضرورياً عند بناء متغيرات مركبة أو تقييم التغير الفردي للمفحوصين عبر مراحل القياس المختلفة دون دمج الدرجات في رقم وحيد يفقد البيانات تفاصيلها الفردية.

7.2 أمثلة تطبيقية للمقارنة المتوازية بين المتغيرات

لتوضيح الفارق العملي، نفترض تجربة قياس نفسي تتضمن تقييم أداء المشاركين في اختبار قبلي (Pre-test) واختبار بعدي (Post-test)، حيث يرغب الباحث في تحديد أعلى درجة حققها كل مفحوص بغض النظر عن توقيت الاختبار، أو إنشاء متغير يمثل أسوأ أداء لكل فرد:

pre_test <- c(65, 82, 90, 45, 70)
post_test <- c(72, 80, 95, 50, 68)
best_performance <- pmax(pre_test, post_test)
worst_performance <- pmin(pre_test, post_test)
print(best_performance)
print(worst_performance)

تنتج دالة best_performance المتجه c(72, 82, 95, 50, 70)، والذي يمثل الدرجة العظمى لكل مشارك على حدة. وتجدر الإشارة إلى أن دوال pmin و pmax تخضع لقاعدة إعادة التدوير (Recycling Rule) في لغة R؛ فإذا تم تمرير متجهين غير متساويين في الطول، سيتم تكرار عناصر المتجه الأقصر تلقائياً حتى يكتمل طول المتجه الأطول، وهو سلوك مفيد للغاية في عمليات المعايرة الرياضية ومقارنة المتجهات بقيم ثابتة محددة.

8. تحديد مواقع ومؤشرات القيم الحدية باستخدام which.min() و which.max()

8.1 الفرق الوظيفي بين استخراج القيمة واستخراج موقعها (Index)

في العديد من التحليلات الإحصائية المتقدمة، لا يكتفي الباحث بمعرفة القيمة الرقمية للحد الأدنى أو الأقصى، بل يحتاج إلى معرفة هوية أو موقع السجل (Index) الذي يحتوي على هذه القيمة داخل مصفوفة البيانات. هنا تبرز الوظيفة المتقدمة لدالتي which.min() و which.max()، حيث تقومان بالبحث داخل المتجه وإرجاع الفهرس العددي (Integer index) لأول عنصر يحقق الشرط الحدي بدلاً من إرجاع القيمة ذاتها:

response_times <- c(450, 320, 190, 600, 190, 410)
fastest_index <- which.min(response_times)
slowest_index <- which.max(response_times)
print(fastest_index)
print(slowest_index)

يُرجع الفحص الموقع 3 للحد الأدنى والموقع 4 للحد الأقصى. ومن الخصائص الحوسبية الهامة لهاتين الدالتين أنهما تتجاهلان القيم المفقودة NA تلقائياً دون الحاجة إلى تمرير وسائط إضافية، وفي حال تكرار القيمة المتطرفة في أكثر من موضع (كما في القيمة 190 المتكررة في الموضعين 3 و 5)، فإن الدالة تُرجع موقع الظهور الأول فقط؛ وإذا رغب الباحث في استخراج كافة المواقع المتكررة، يمكنه اللجوء إلى التصفية الشرطية القياسية باستخدام دالة which(response_times == min(response_times)).

8.2 استرجاع السجلات الكاملة للمفحوصين بناءً على المواقع الحدية

تتجلى الفائدة التطبيقية الكبرى لمعرفة المؤشرات الرقمية عند استخدامها لفهرسة وتصفية إطارات البيانات متعددة الأعمدة؛ حيث يمكن استرجاع السجل الديموغرافي والسلوكي الكامل للشخص صاحب أعلى أو أدنى أداء في العينة البحثية:

participants <- data.frame(ID = 101:105, Age = c(22, 25, 30, 21, 28), Score = c(78, 95, 62, 88, 95))
top_student_index <- which.max(participants$Score)
top_participant_profile <- participants[top_student_index, ]
print(top_participant_profile)

يُعيد هذا الأمر الصف الثاني كاملاً، متضمناً رقم هوية المشارك وعمره ودرجته المحققة. تُمكّن هذه المنهجية الباحثين من إجراء الفحوصات العيادية والتحليلات النوعية للحالات المتطرفة (Extreme Case Analysis)، ودراسة الخصائص الفريدة للأفراد الذين يمثلون الحدود القصوى أو الدنيا في الظواهر السلوكية قيد الدراسة بدقة إجرائية متناهية.

9. تطبيق دالتي min() و max() على البيانات غير العددية

9.1 التعامل مع التواريخ والفترات الزمنية (Date & Time)

تمتلك لغة R نظاماً مدمجاً فائق التطور للتعامل مع المتغيرات الزمنية مثل كائنات Date وصيغ POSIXct / POSIXlt. عند تطبيق دالتي min() و max() على هذه المتغيرات، يتم تفسير الحدود بالمعنى الزمني؛ حيث تعبر القيمة الصغرى عن التاريخ الأقدم (أول حدث)، بينما تعبر القيمة القصوى عن التاريخ الأحدث (آخر حدث مسجل):

session_dates <- as.Date(c("2023-01-15", "2023-06-20", "2022-11-05", "2023-09-12"))
earliest_session <- min(session_dates)
latest_session <- max(session_dates)
total_duration <- max(session_dates) - min(session_dates)
print(earliest_session)
print(latest_session)
print(total_duration)

يُظهر المتغير total_duration الفارق الزمني الكلي للمشروع البحثي بالأيام. يُعد هذا الاستخدام بالغ الأهمية في الدراسات الطولية (Longitudinal Studies) لمتابعة فترات انقطاع المشاركين وحساب المدى الزمني الدقيق لجمع البيانات الميدانية.

9.2 تطبيق الدوال على النصوص والسلاسل المحرفية (Alphabetical Order)

عند تمرير متجهات نصية (Character vectors) إلى دالتي min() و max()، لا تقوم لغة R بحساب طول الكلمات، بل تعتمد بدلاً من ذلك على الترتيب المعجمي والأبجدي (Lexicographical Ordering) المشتق من الترميز العالمي للغة المستخدمة (ASCII / Unicode Locale Settings):

words <- c("Banana", "Apple", "Cherry", "Date")
first_alphabetical <- min(words)
last_alphabetical <- max(words)
print(first_alphabetical)
print(last_alphabetical)

تنتج دالة min() الكلمة “Apple” لأنها تبدأ بأول حرف في الترتيب الأبجدي اللاتيني، بينما تُنتج دالة max() الكلمة “Date”. وفي السياق التطبيقي لتحليل البيانات، يُستفاد من هذا السلوك في التحقق من صحة الترميزات النصية للفئات، والتأكد من عدم وجود سلاسل محرفية غير مألوفة أو رموز غريبة تم إدخالها بالخطأ في قواعد البيانات النصية.

9.3 التعامل مع المتغيرات الترتيبية والعوامل (Ordered Factors)

تُمثل العوامل (Factors) في لغة R الأسلوب البرمجي القياسي لتخزين المتغيرات الفئوية. وتجدر الإشارة إلى أن تطبيق دالتي min() و max() على العوامل الاسمية غير المرتبة (Unordered Factors) سيؤدي إلى ظهور رسالة خطأ صريحة تشير إلى أن المقارنة غير معرفة لهذه العوامل. ولكن عند تحويل المتغير إلى عامل رتبي محدد المستويات عبر دالة ordered()، تكتسب الدالتان القدرة على تحديد أدنى وأعلى مستوى رتبي مسجل:

likert_raw <- c("Medium", "High", "Low", "High", "Very_High")
likert_ordered <- ordered(likert_raw, levels = c("Low", "Medium", "High", "Very_High"))
lowest_level <- min(likert_ordered)
highest_level <- max(likert_ordered)
print(lowest_level)
print(highest_level)

يُعد هذا التطبيق أساسياً في معالجة استبيانات مقياس ليكرت (Likert Scale)، حيث يتيح للباحث التأكد من أن المشاهدات تغطي كافة المستويات السلوكية المخطط لها، واستخراج القيم الحدية الرتبية دون الحاجة لتحويل الفئات إلى أرقام وسيطة قد تؤثر على التفسير المفاهيمي للاستجابات.

10. تطبيقات ونماذج عملية في البحوث النفسية والتحليل السلوكي

10.1 تقييس ومعايرة درجات الاختبارات (Min-Max Feature Scaling)

في بناء النماذج التنبؤية وخوارزميات التعلم الآلي والقياس النفسي متعدد الأبعاد، تبرز الحاجة الماسة إلى توحيد المقاييس المختلفة على مقياس معياري موحد محصور بين [0, 1] لتفادي هيمنة المتغيرات ذات المدى العددي الضخم على المتغيرات ذات المدى الصغير. تُعرف هذه العملية بالمعايرة الحدية (Min-Max Normalization) وتعتمد على الصيغة الرياضية التالية:

X_scaled = (X - min(X)) / (max(X) - min(X))

يمكن بناء دالة برمجية مخصصة وقابلة لإعادة الاستخدام في لغة R لحساب هذه المعايرة لبيانات درجات القلق والأداء الإدراكي كما يلي:

min_max_scale <- function(x) {
  valid_min <- min(x, na.rm = TRUE)
  valid_max <- max(x, na.rm = TRUE)
  if (valid_min == valid_max) {
    return(rep(0, length(x)))
  }
  return((x - valid_min) / (valid_max - valid_min))
}
raw_scores <- c(120, 150, 110, 190, 135)
standardized_scores <- min_max_scale(raw_scores)
print(standardized_scores)

تضمن هذه الدالة تحويل كافة القياسات النفسية الخام إلى نسب كسرية دقيقة تبدأ من 0 لأدنى مشارك وتصل إلى 1 لأعلى مشارك، مما يمهد لدمج هذه المقاييس في مؤشرات تركيبية مركبة أو إدخالها في نماذج الشبكات العصبية والتحليل العنقودي بكفاءة رياضية متكاملة.

10.2 كشف القيم المتطرفة والحدود الحرجة في أزمنة الاستجابة

في أبحاث علم النفس التجريبي والمعرفي، يخضع قياس أزمنة رد الفعل (Reaction Times) لضوابط صارمة لاستبعاد المحاولات غير الصالحة. فإذا كان زمن الرجع أقل من 150 ملي ثانية، يُصنف الأداء غالباً كاستجابة استباقية وتخمين عشوائي (Anticipation Error)، وإذا تجاوز 2000 ملي ثانية، فإنه يعكس شروداً ذهنياً للمشارك. يمكن توظيف دالتي min() و max() لفحص الحدود الميدانية وتطبيق التصفية المنهجية:

rt_trials <- c(120, 245, 310, 450, 2150, 290, 340)
trial_min <- min(rt_trials)
trial_max <- max(rt_trials)
valid_trials <- rt_trials[rt_trials >= 150 & rt_trials <= 2000]
cat("الأصل:", trial_min, "إلى", trial_max, "n")
cat("المنقى:", min(valid_trials), "إلى", max(valid_trials), "n")

يضمن هذا الإجراء الاستكشافي المزدوج حماية النموذج الإحصائي من التلوث بالقيم المتطرفة (Outliers)، ويساعد الباحث على توثيق المعايير الإجرائية لاستبعاد البيانات في منهجية البحث وفق أعلى معايير الشفافية العلمية المتبعة في المجلات الأكاديمية المحكمة.

10.3 التحقق من صحة مدخلات المقاييس والاستبيانات النفسية

يمثل التدقيق الآلي للبيانات (Data Validation) خطوة حيوية لضمان سلامة الاستبيانات الرقمية والورقية. فإذا كان الباحث يطبق مقياس الاكتئاب المكون من بنود تقع درجاتها بين 0 و 3، فإن أي رصد خارج هذا النطاق يمثل خطأ فادحاً يجب عزله قبل الشروع في حساب الدرجات الكلية. يمكن برمجة دالة فحص الجودة بالاعتماد على دالتي الحدود:

survey_items <- data.frame(item1 = c(1, 2, 0, 3, 2), item2 = c(2, 3, 1, 0, 4), item3 = c(0, 1, 2, -1, 3))
check_validity <- function(df, min_allowed = 0, max_allowed = 3) {
  observed_min <- min(df, na.rm = TRUE)
  observed_max <- max(df, na.rm = TRUE)
  is_valid <- (observed_min >= min_allowed) && (observed_max <= max_allowed)
  return(list(Valid = is_valid, Min = observed_min, Max = observed_max))
}
quality_report <- check_validity(survey_items)
print(quality_report)

تكشف الدالة مباشرة أن البيانات تحتوي على أخطاء إدخال (القيمة 4 في البند الثاني والقيمة -1 في البند الثالث)، مما يوفر أداة تشخيصية سريعة تسمح لمدير البيانات بمراجعة استمارات الاستجابة الأصلية وتصحيحها قبل إجراء تحليلات الصدق والثبات الإحصائي للمقياس.

11. الأخطاء الشائعة واستكشاف المشكلات البرمجية وإصلاحها

11.1 معالجة خطأ التحذير: no non-missing arguments to min/max

من أكثر رسائل التحذير إرباكاً للمحللين في لغة R ظهور الرسالة الشهيرة: Warning: no non-missing arguments to min; returning Inf. يظهر هذا التحذير عندما يتم تمرير متجه فارغ تماماً (مثل numeric(0)) إلى الدالة، أو عند تفعيل وسيط na.rm = TRUE على متجه لا يحتوي سوى على قيم مفقودة NA:

empty_vector <- c(NA, NA)
bad_min <- min(empty_vector, na.rm = TRUE)
print(bad_min)

تُرجع الدالة القيمة Inf، وهو السلوك الرياضي الافتراضي للغة R المستند إلى نظرية المجموعات، حيث يُعرف أصغر عنصر في المجموعة الفارغة رياضياً بأنه اللانهاية الإيجابية. ولتجنب هذه المشكلة البرمجية، يتعين على الباحث كتابة شروط حماية مسبقة (Defensive Programming) تفحص طول البيانات الصالحة قبل تشغيل الدوال الحدية:

safe_min <- function(x) {
  valid_data <- x[!is.na(x)]
  if (length(valid_data) == 0) return(NA)
  return(min(valid_data))
}
print(safe_min(empty_vector))

يعيد هذا التعديل البرمجي القيمة NA بأمان تام ودون إطلاق أي تحذيرات حسابية قد تعطل خطوط المعالجة الأوتوماتيكية في المشروعات البرمجية الكبرى.

11.2 أخطاء التباين في أنواع البيانات (Data Type Mismatches)

تنشأ أخطاء التباين في الأنماط البيانية عند استيراد البيانات من ملفات خارجية مثل CSV أو Excel، حيث قد تتسلل بعض الرموز النصية أو المسافات البيضاء المخفية داخل الأعمدة الرقمية، مما يؤدي إلى تحويل العمود بأكمله إلى نمط نصي (Character). عند تطبيق دالة min() أو max() على هذا العمود، سيتم التقييم وفق الترتيب الأبجدي بدلاً من الحسابي، مما ينتج استنتاجات خاطئة تماماً (على سبيل المثال، تصبح القيمة النصية “100” أصغر من “20” أبجدياً):

corrupted_data <- c("100", "20", "5", "300")
wrong_min <- min(corrupted_data)
correct_min <- min(as.numeric(corrupted_data))
cat("الحد الأدنى الخاطئ (أبجدي):", wrong_min, "n")
cat("الحد الأدنى الصحيح (عددي):", correct_min, "n")

يبرز هذا المثال أهمية الفحص المسبق لهياكل البيانات باستخدام دالتي str() و is.numeric() قبل البدء في الحسابات الإحصائية، مع اللجوء إلى التحويل الآمن عبر دالة as.numeric() لضمان استقرار التحليلات ودقة مخرجاتها.

11.3 الخلط بين الدوال الحسابية والدوال الإحصائية المقاربة

يقع الخلط المنطقي المتكرر بين دالة min() ودالة which.min()، أو بين دالة min() ودالة pmin(). إن استخدام دالة min() داخل جمل التصفية الشرطية المخصصة للمقارنة بين عمودين متوازيين داخل جدول بيانات يؤدي إلى مقارنة كل صف بالحد الأدنى الكلي للجدول بدلاً من مقارنة القيمتين المقابلتين في الصف نفسه، مما يفرغ التصفية من مغزاها الإحصائي.

لتفادي هذه الأخطاء الهيكلية، يجب تطبيق الاختبارات الأحادية (Unit Testing) على الشيفرات البرمجية وفحص أبعاد المخرجات المتوقعة؛ فإذا كان المطلوب متجراً بطول البيانات نفسها، يجب استخدام الدوال المتوازية pmin/pmax، وإذا كان المطلوب مؤشراً رقمياً للصف يجب استخدام which.min/which.max، بينما تقتصر الدوال التجميعية min/max على توليد القيم القياسية المفردة.

12. أفضل الممارسات البرمجية وتحسين كفاءة الحوسبة في R

12.1 كتابة دوال مخصصة قوية قابلة لإعادة الاستخدام

في المشاريع الإحصائية واسعة النطاق والبحوث القابلة للتكرار العلمي (Reproducible Research)، يُنصح بتضمين دوال استخراج الحدود داخل دوال مخصصة قوية ومغلفة بآليات معالجة الأخطاء الاستباقية عبر استخدام بنية tryCatch()، مع إدراج توثيق معياري يحدد طبيعة المدخلات والمخرجات المتوقعة:

robust_boundary_analyzer <- function(data_vector, remove_na = TRUE) {
  if (!is.numeric(data_vector) && !is.Date(data_vector)) {
    stop("خطأ نوعي: يجب أن يكون المتجه المدخل رقمياً أو كائناً زمنياً.")
  }
  if (all(is.na(data_vector))) {
    warning("تحذير: كافة قيم المتجه مفقودة.")
    return(list(Minimum = NA, Maximum = NA, Range = NA))
  }
  min_val <- min(data_vector, na.rm = remove_na)
  max_val <- max(data_vector, na.rm = remove_na)
  return(list(Minimum = min_val, Maximum = max_val, Range = max_val - min_val))
}

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

12.2 تحسين الأداء مع مجموعات البيانات الضخمة (Big Data)

عند معالجة مجموعات البيانات الضخمة التي تتجاوز ملايين المشاهدات، يصبح الاختيار بين حزم لغة R عاملاً حاسماً في سرعة المعالجة واستهلاك الذاكرة العشوائية. في هذه السيناريوهات، تتفوق حزمة data.table بشكل ملحوظ على البنى الأساسية وحزم التلخيص التقليدية بفضل استخدامها لتقنيات المعالجة بالمرجع (Update by Reference) وتوازي الحوسبة المتقدم:

library(data.table)
large_dt <- data.table(ID = 1:10000000, Group = sample(c("A", "B", "C"), 10000000, replace = TRUE), Metric = rnorm(10000000))
summary_performance <- large_dt[, .(Min_Val = min(Metric), Max_Val = max(Metric)), by = Group]
print(summary_performance)

تنفذ حزمة data.table عمليات التجميع والفرز الحدي لعشرة ملايين سجل في أجزاء من الثانية، مما يؤكد ضرورة الابتعاد التام عن الحلقات التكرارية والاعتماد على الخوارزميات المتجهية المحسنة عند التعامل مع التدفقات البيانية الكبرى.

12.3 التكامل مع أدوات العرض البياني ولوحات البيانات

ترتبط الدوال الحدية ارتباطاً وثيقاً بتمثيل البيانات بيانياً؛ حيث تُستخدم دالتا min() و max() لتحديد وضبط نطاقات المحاور في مكتبة ggplot2، وتحديد مواقع الوسوم التوضيحية للنقاط القصوى والدنيا في الرسوم التشتتية والصندوقية:

library(ggplot2)
df_plot <- data.frame(X = 1:50, Y = rnorm(50, mean = 100, sd = 15))
y_min <- min(df_plot$Y)
y_max <- max(df_plot$Y)
plot_obj <- ggplot(df_plot, aes(x = X, y = Y)) +
  geom_line(color = "steelblue") +
  geom_point() +
  ylim(y_min - 5, y_max + 5) +
  annotate("point", x = which.min(df_plot$Y), y = y_min, color = "red", size = 3) +
  annotate("point", x = which.max(df_plot$Y), y = y_max, color = "darkgreen", size = 3) +
  theme_minimal()

تُسهم هذه الرسوم التفاعلية الموجهة بالحدود الرياضية في إبراز النقاط الحرجة في التقارير الإحصائية التفاعلية المبنية عبر R Markdown و Quarto، مما يمنح متخذي القرار والباحثين فهماً بصرياً مباشراً لمدى التشتت والنهايات الحسابية للظاهرة المدروسة.

خاتمة

تمثل دالتا min() و max() في لغة البرمجة الإحصائية R أداتين جوهريتين تتجاوزان وظيفتهما الحسابية البسيطة لتشكلا جزءاً لا يتجزأ من منظومة التحليل الإحصائي الاستكشافي وضبط جودة البيانات والنمذجة المعيارية. ومن خلال استيعاب البنية النحوية لهاتين الدالتين، وإتقان إدارة القيم المفقودة، والتفريق الواعي بينهما وبين الدوال المتوازية كـ pmin/pmax والدوال الفهرسية كـ which.min/which.max، يكتسب الباحث والمحلل قدرة فائقة على بناء خوارزميات برمجية رصينة تتسم بالدقة الرياضية والسرعة الحوسبية العالية، مما يرتقي بجودة البحوث العلمية والتحليلات التطبيقية في مختلف مجالات العلوم النفسية والبيانات الكمية.

References

اقتباس هذا المقال

looti, M. (2026, أغسطس 28). كيفية استخدام دالتي Min و Max في لغة R (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/statistics/how-to-use-min-and-max-functions-in-r-with-examples/
looti, Mohammed. “كيفية استخدام دالتي Min و Max في لغة R (مع أمثلة).” عرب سايكلوجي, 28 أغسطس 2026, https://arabpsychology.com/statistics/how-to-use-min-and-max-functions-in-r-with-examples/.
looti, Mohammed. “كيفية استخدام دالتي Min و Max في لغة R (مع أمثلة).” عرب سايكلوجي. أغسطس 28, 2026. https://arabpsychology.com/statistics/how-to-use-min-and-max-functions-in-r-with-examples/.