التحليل الإحصائيبرمجة Rعلم البيانات

كيفية التعامل مع قيم NaN في لغة R (مع أمثلة)

دليل أكاديمي شامل يشرح كيفية تحديد وحساب وإزالة واستبدال قيم NaN في لغة البرمجة الإحصائية R مع أمثلة برمجية وتطبيقات عملية متقدمة.

تاريخ النشر

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

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

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

1. مقدمة ومفهوم قيم NaN في بيئة لغة R الإحصائية

1.1 التعريف الرياضي والبرمجي لقيم NaN

تُعرف القيمة NaN برمجياً واختصاراً لمصطلح Not a Number، وهي تمثيل رمزي ورقمي معتمد عالمياً ضمن معيار الحوسبة الرقمية والنقطة العائمة IEEE 754. يُستخدم هذا الرمز الحسابي المتخصص للدلالة على النتائج الرقمية الناتجة عن عمليات جبرية غير محددة أو غير معرفة في الحقل الرياضي للأعداد الحقيقية. في بيئة R، تنتمي القيمة NaN من الناحية البرمجية إلى النمط البياني العددي (Numeric) وتحديداً الأعداد الحقيقية ذات الدقة المزدوجة (Double)، مما يعني أنها تحتل حيزاً تخزينياً مخصصاً للأرقام لكنها تحمل قيمة إشارية توضح استحالة التفسير العددي للنتيجة.

تنشأ قيم NaN بصورة حتمية عندما يُطلب من المحرك الحسابي للغة R تقييم تعبير رياضي يفتقر إلى معنى جبري محدد ضمن نطاق الأعداد الحقيقية. ويبرز هنا فارق جوهري ودقيق للغاية بين الخطأ البرمجي في الصياغة (Syntax Error) أو استدعاء المتغيرات غير المعرفة، وبين ظهور NaN. فعند وقوع خطأ في الصياغة البرمجية، تتوقف بيئة R عن تنفيذ الشيفرة تماماً وتُصدر رسالة خطأ صريحة توقف تدفق المعالجة. أما في حالة توليد قيمة NaN، فإن المحرك البرمجي يستمر في العمل دون توقف، ممرراً هذه القيمة الحسابية الشاذة عبر المتجه أو المصفوفة، ومصدراً في بعض الحالات تحذيراً تشغيلياً (Warning) ينبه المستخدم إلى حدوث عملية حسابية غير صالحة، مما يستدعي يقظة تحليلية مستمرة من قِبل الباحث.

1.2 أهمية معالجة القيم غير المعرّفة في تحليل البيانات الإحصائية

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

علاوة على ذلك، فإن تجاهل معالجة هذه القيم يلقي بظلال سلبية قاتمة على النماذج الاستدلالية المتقدمة واختبارات الفروض الإحصائية؛ إذ قد يؤدي إلى تقليص درجات الحرية بشكل عشوائي، أو إفساد حسابات القيم الاحتمالية (P-values)، أو انهيار خوارزميات التحسين العددي (Numerical Optimization) المستخدمة في تقدير معالم النماذج عبر دالة الإمكان الأعظم (Maximum Likelihood Estimation). من هذا المنطلق، تشكل عمليات الرصد المبكر والتنظيف المسبق للقيم غير المعرفة خط الدفاع الأول لضمان موثوقية الاستنتاجات العلمية وحماية سلاسل المعالجة الرقمية من الانهيار غير المتوقع.

2. التمييز الدلالي بين قيم NaN و NA و NULL في لغة R

2.1 الفروق الجوهرية بين NaN (غير معرّف) و NA (مفقود)

تعد التفرقة بين المفهومين الدلاليين NaN و NA (المشتقة من Not Available) واحدة من أدق المسائل التي تواجه المبرمجين في لغة R. تشير القيمة NA إلى حالة غياب فعلي للمعلومة الإحصائية أو عدم تسجيلها في سياق جمع البيانات الميدانية، كأن يمتنع مستجيب عن الإجابة على سؤال في استبيان، مع بقاء القيمة محتملة الوجود رياضياً لو جرى رصدها. في المقابل، فإن NaN لا تعبر عن نقص في التوثيق أو غياب للبيانات، بل تعبر عن استحالة حسابية مطلقة تجعل القيمة غير موجودة في الأصل من المنظور الرياضي الصرف.

ينعكس هذا التمايز الدلالي بشكل مباشر على سلوك الدوال المنطقية داخل R؛ حيث تعتبر اللغة قيمة NaN حالة خاصة وفرعية من حالات الفقد العام NA. وبالتالي، إذا قمنا بتطبيق الدالة المنطقية is.na() على متجه يحتوي على القيمة NaN، فإنها ستُرجع القيمة المنطقية TRUE معتبرة إياها قيمة مفقودة ضمن المفهوم الإحصائي الشامل. على النقيض من ذلك، فإن الدالة التخصصية is.nan() تعمل بحساسية نوعية دقيقة، إذ تُرجع TRUE فقط إذا كانت الخلية تحتوي حصراً على NaN الناتجة عن خطأ حسابي، في حين تُرجع FALSE إذا كانت الخلية تحتوي على القيمة المفقودة العادية NA.

2.2 مقارنة مفهوم NULL مع القيم غير المعرفة

يحتل الكائن NULL مكانة بنيوية فريدة في نظام الكائنات الخاص بلغة R، إذ يمثل الكائن الفارغ تماماً أو العدم البرمجي (Empty Entity). يختلف NULL جذرياً عن كل من NaN و NA في عدة خصائص تخزينية ومنطقية؛ فالقيمة NaN تحتفظ بموقع تخزيني داخل المتجه العددي وتمنحه طولاً حسابياً (Length = 1) ونمطاً عددياً محدداً، في حين أن الكائن NULL يمتلك طولاً يساوي صفراً (Length = 0) وينتمي إلى الصنف الخاص NULL class.

إذا حاول المحلل دمج الكائن NULL داخل متجه عددي، فإن R تتجاهله تلقائياً ولا تخصص له أي مؤشر فهرسي (Index)، مما يعني أنه لا يستهلك حيزاً في أبعاد المتجه ولا يؤثر على تعداده الإجمالي. يُستخدم NULL أساساً في البناء الهيكلي للدوال لتحديد المعاملات الافتراضية غير المفعلة، أو لإفراغ عناصر القوائم (Lists)، بينما تُستخدم NaN و NA كعناصر تشغل مواقع فعلية داخل المصفوفات وإطارات البيانات وتتطلب تدخلاً تنظيفياً متخصصاً أثناء إعداد البيانات للتحليل.

3. العمليات الرياضية الشائعة المولدة لقيم NaN

3.1 عمليات القسمة غير المحددة رياضياً

تعد عمليات القسمة ذات البنى غير المحددة رياضياً السبب الأكثر شيوعاً لتوليد قيم NaN في لغة R الحسابية. تأتي في مقدمة هذه العمليات محاولة قسمة الصفر الحسابي على الصفر الحسابي 0 / 0. ففي الجبر الكلاسيكي ونظرية التحليل الحقيقي، يعتبر حاصل قسمة الصفر على الصفر صيغة غير معينة (Indeterminate Form) يستحيل إسناد قيمة حقيقية منفردة لها دون دراسة مسارات النهايات وحساب التفاضل والتكامل.

من الضروري التمييز بدقة بين ناتج قسمة الصفر على الصفر وناتج قسمة عدد حقيقي غير صفري على الصفر؛ فعند تنفيذ قسمة قيمة موجبة على الصفر مثل 10 / 0، تُرجع لغة R القيمة Inf (اللانهاية الموجبة Positive Infinity)، بينما تُرجع -Inf في حالة قسمة قيمة سالبة. أما NaN فتظهر حصراً عند التقاء الصفر بالصفر. تبرز هذه المشكلة عملياً في حساب المؤشرات النسبية، ومعدلات التغير الزمني (Growth Rates)، وحساب أوزان الترجيح عندما تنعدم قيم البسط والمقام في وقت واحد لبعض المشاهدات.

3.2 الدوال اللوغاريتمية والجذور التربيعية للقيم السالبة

تعتبر الدوال غير الخطية مصدراً رئيسياً آخر لإنتاج القيم غير المعرفة عندما تُطبق على مدخلات تقع خارج مجالها التعريفي في الحقل الحقيقي (Real Domain). فعند استدعاء دالة اللوغاريتم الطبيعي log() وتمرير قيمة عددية سالبة كمدخل، مثل log(-12)، يفشل المحرك الحقيقي في إيجاد حل في نطاق الأعداد الحقيقية، فيصدر النظام تحذيراً برمجياً نصه NaNs produced ويُسند فوراً القيمة NaN لتلك الخلية.

ينطبق الأمر ذاته تماماً على دوال الجذور التربيعية sqrt() عند تمرير أرقام سالبة، كأن يُطلب حساب sqrt(-1) أو sqrt(-100) دون تفعيل بيئة الأعداد المركبة (Complex Numbers). تقع هذه الأخطاء بكثرة أثناء إجراء التحويلات القياسية للمتغيرات الاقتصادية والديموغرافية، مثل تحويلات “بوكس-كوكس” (Box-Cox) أو التحويلات اللوغاريتمية الهادفة إلى معالجة الالتواء الإحصائي وتثبيت التباين، حيث تحتوي السلاسل الخام على قيم سالبة ناتجة عن خسائر مالية أو انخفاضات حادة دون معالجة مسبقة للإزاحة الخطية.

3.3 العمليات اللانهائية المتعارضة

يتعامل المعيار الحسابي IEEE 754 ولغة R مع مقادير اللانهاية وفق قواعد جبرية صارمة، إلا أن التقاء هذه الكميات في بعض العمليات الحسابية المتعارضة يؤدي حتماً إلى إنتاج قيم NaN. من أبرز هذه العمليات عملية طرح اللانهاية من اللانهاية Inf - Inf، وهي صيغة رياضية غير معينة؛ نظراً لأن اللانهاية تمثل مفهوماً للتباعد الرياضي وليست عدداً ثابتاً يمكن قياس الفرق بينه وبين كمية مكافئة له بالدقة ذاتها.

كذلك، فإن عملية ضرب الصفر المطلق في اللانهاية 0 * Inf أو ضرب اللانهاية السالبة في الصفر 0 * -Inf تُسفر مباشرة عن توليد القيمة NaN؛ نظراً لتناقض الخصائص الصفرية مع خصائص التباعد اللانهائي. تواجه خوارزميات الاستمثال والتقارب التكراري (Iterative Convergence) في سلاسل ماركوف ومحاكاة مونت كارلو هذه الحالات عندما تنحرف المتغيرات الوسيطة نحو التباعد العددي السريع مسببة تفاعلات حسابية غير محددة تفسد استقرار النموذج.

4. منهجية رصد وتحديد مواقع قيم NaN في المتجهات

4.1 استخدام الدالة is.nan() في الاختبار المنطقي

تمثل الدالة المدمجة is.nan() الأداة المعيارية والأساسية في لغة R لإجراء الاختبارات المنطقية المتجهة (Vectorized Logical Tests) للكشف عن القيم غير المعرفة حسابياً. تقبل هذه الدالة كائناً حسابياً، كالمتجه أو المصفوفة، وتقوم بفحص كل عنصر على حدة، ثم تُرجع متجهاً منطقياً موازياً له في الطول والأبعاد يتكون بالكامل من القيم البولينية TRUE و FALSE.

تتجلى قوة الدالة is.nan() في قدرتها الفائقة على عزل الحالات الحسابية الشاذة بدقة دون الخلط بينها وبين حالات الفقد العام؛ فإذا طبقنا الدالة على متجه يحتوي على المزيج c(10, NaN, NA, 5, 0/0)، فإن الدالة ستنتج المتجه المنطقي c(FALSE, TRUE, FALSE, FALSE, TRUE). تبرز هذه النتيجة أن الدالة تجاهلت القيمة NA العادية في الموقع الثالث وركزت حصراً على رصد القيم غير المعرفة حسابياً في الموقعين الثاني والخامس، مما يوفر للمحلل أداة دقيقة للفحص المجهري لسلامة العمليات الحسابية.

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

على الرغم من فائدة المتجهات المنطقية الناتجة عن is.nan()، إلا أن التعامل مع مجموعات البيانات الضخمة التي تحتوي على مئات الآلاف من المشاهدات يتطلب معرفة العناوين الفهرسية الدقيقة للمواقع التي وقعت فيها الأخطاء الحسابية. هنا يأتي الدور المحوري للدمج الوظيفي بين الدالتين which() و is.nan() عبر التعبير البرمجي which(is.nan(x)).

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

5. تعداد وحساب حجم قيم NaN في الهياكل البيانية

5.1 حساب التكرار الكلي باستخدام الدالة sum()

تعتمد لغة R على آلية برمجية ضمنية تُعرف بالتحويل القسري للأنماط البيانية (Type Coercion)، حيث يتم تحويل القيم المنطقية تلقائياً إلى قيم عددية صحيحة بمجرد إخضاعها لعمليات حسابية؛ إذ تتحول القيمة المنطقية TRUE إلى الرقم 1، في حين تتحول FALSE إلى الرقم 0. يستغل المبرمجون المحترفون هذه الميزة بكفاءة لحساب التكرار الكلي لقيم NaN داخل أي هيكل بياني عبر الصيغة sum(is.nan(x)).

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

5.2 حساب النسبة المئوية لقيم NaN

لا يوفر التعداد المطلق لقيم NaN وحده رؤية تحليلية كاملة ما لم يُنسب إلى الحجم الكلي للمشاهدات، خاصة عند مقارنة جودة البيانات عبر مجموعات تجريبية متفاوتة الأحجام. ولتحقيق ذلك، يُستخدم التعبير البرمجي mean(is.nan(x))، والذي يستند إلى الخاصية ذاتها للتحويل المنطقي إلى أرقام، حيث يقوم بحساب المجموع الكلي للقيم 1 مقسوماً على الطول الإجمالي للمتجه، مما ينتج مباشرة النسبة العشرية للقيم غير المعرفة.

بضرب هذه النتيجة في 100، يحصل المحلل على النسبة المئوية الدقيقة للقيم الحسابية المشوهة. وتُبنى على هذه النسبة القرارات المنهجية الحاسمة؛ ففي الأعراف الإحصائية، إذا تجاوزت نسبة البيانات التالفة في متغير معين عتبة حرجة (مثل 20% أو 30% اعتماداً على طبيعة الحقل العلمي)، فإن التوجه المنهجي السليم قد يميل إلى استبعاد المتغير بأكمله من النمذجة بدلاً من محاولة استيفائه، لتجنب تشويه البنية التوزيعية للمتغيرات.

6. تقنيات استبعاد وحذف قيم NaN من المتجهات

6.1 التصفية المباشرة باستخدام المعامل المنطقي للنفي (!)

تعتبر تقنية الفهرسة المنطقية المدعومة بمعامل النفي البوليني ! (Logical NOT Operator) المنهجية الأكثر نقاءً وكفاءة لحذف واستبعاد قيم NaN من المتجهات في بيئة R الأساسية. تتم صياغة هذا الإجراء عبر التعبير clean_x <- x[!is.nan(x)]. في هذا السياق، تقوم الدالة is.nan(x) بإنشاء القناع المنطقي الأولي، ثم يقوم المعامل ! بقلب جميع قيم TRUE إلى FALSE والعكس، مما يجبر محرك الفهرسة على الاحتفاظ بالأرقام الحقيقية الصالحة فقط وتجريد المتجه من كافة الشوائب الحسابية.

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

6.2 استخدام الدالة na.omit() والمقارنة السلوكية

تقدم بيئة R دالة عامة موجهة لمعالجة كافة أشكال البيانات المفقودة وغير المعرفة وهي الدالة na.omit(). نظراً لأن لغة R تعامل قيم NaN كحالة فرعية ضمن التصنيف الأوسع للقيم المفقودة NA، فإن تمرير متجه يحتوي على قيم غير معرفة إلى na.omit(x) يؤدي تلقائياً إلى تطهير المتجه وإسقاط تلك القيم بكفاءة تامة ودون الحاجة لتحديدها بالاسم الحسابي المباشر.

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

7. استراتيجيات استبدال وتعويض قيم NaN بقيم عددية بديلة

7.1 الاستبدال بقيمة ثابتة باستخدام الفهرسة الشرطية

في العديد من التطبيقات الهندسية والحسابية، يكون من غير المرغوب فيه تقليص طول المتجهات عبر الحذف، بل يُفضل تعديل القيم الشاذة واستبدالها بقيمة عددية حيادية أو ثابتة محددة مسبقاً. يتحقق ذلك في R بأعلى درجات المرونة من خلال الجمع بين الفهرسة المنطقية ومعامل الإسناد الشرطي عبر الصيغة البرمجية x[is.nan(x)] <- 0، والتي تستهدف حصراً المواقع غير المعرفة وتضع بدلاً منها القيمة صفر.

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

7.2 التعويض بالمتوسط الحسابي أو الوسيط (Imputation)

يعد الاستيفاء الإحصائي أو التعويض بمقاييس النزعة المركزية (Mean/Median Imputation) استراتيجية بديلة تهدف إلى ملء الفجوات الحسابية الناتجة عن NaN بقيم تحافظ قدر الإمكان على مركز التوزيع الاحتمالي للبيانات. يتم تطبيق هذه التقنية من خلال خطوتين متكاملتين؛ الأولى تتضمن حساب المتوسط الحسابي للعناصر الصالحة فقط مع استبعاد القيم التالفة عبر تفعيل المعامل na.rm = TRUE، تليها خطوة الإسناد المباشر كما يوضح التعبير x[is.nan(x)] <- mean(x, na.rm = TRUE).

إذا كانت البيانات تعاني من التواء شديد أو تحتوي على قيم متطرفة شاذة (Outliers)، فإن التعويض باستخدام الوسيط الحسابي median(x, na.rm = TRUE) يكون أكثر متانة ومقاومة للتأثيرات المنحازة. ومع ذلك، ينبغي على الباحثين إدراك أن التعويض الفردي بمقاييس النزعة المركزية يؤدي نظرياً إلى تقليص مصطنع في تباين العينة (Underestimation of Variance) وتضخيم الارتباطات الوهمية، مما يفرض استخدام تقنيات التعويض المتعدد (Multiple Imputation) عند التعامل مع الدراسات الحساسة.

8. معالجة قيم NaN داخل إطارات البيانات (Data Frames)

8.1 رصد وتحديد قيم NaN عبر أعمدة متعددة

تتعقد عملية إدارة البيانات عند الانتقال من المتجهات الأحادية إلى إطارات البيانات متعددة المتغيرات Data Frames، حيث تتداخل المتغيرات العددية مع المتغيرات النصية والفئوية. لرصد وتحديد انتشار قيم NaN عبر كافة أعمدة إطار البيانات، تُستخدم دوال المعالجة التكرارية عالية الكفاءة من عائلة Apply، وتحديداً الدالة sapply()، وذلك عبر استدعاء تعبيرات مثل sapply(df, function(col) sum(is.nan(col))).

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

8.2 إزالة الصفوف أو الأعمدة الحاوية على قيم غير معرفة

بناءً على نتائج التشخيص الهيكلي، قد يتخذ المحلل قراراً بتنقية إطار البيانات من خلال التخلص التام من الصفوف التي تعاني من تشوهات حسابية في متغيرات حرجة ومستهدفة في التحليل. يُنفذ ذلك برمجياً عبر الفهرسة البسيطة clean_df <- df[!is.nan(df$target_variable), ]، مما يضمن الحفاظ على سلامة بنية السجلات الأخرى وتوافق القياسات بين المتغيرات داخل نفس الصف.

في المقابل، إذا أظهر المسح أن عموداً معيناً يحتوي على نسبة فساد حسابي كاسحة تتجاوز المعايير المنهجية المقبولة نتيجة فشل كامل في المعادلة المولدة له، فإن القرار التحليلي الأمثل يتمثل في إسقاط العمود بالكامل لحماية النموذج من التحيز. يمكن إتمام عملية إسقاط الأعمدة بإسناد القيمة NULL للعمود المستهدف مثل df$corrupted_column <- NULL، أو عبر استخدام الفهرسة السلبية للأعمدة، مع ضمان بقاء الهيكل العام للجدول متزناً ومتماسكاً.

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

في بعض المشاريع البرمجية ومعالجة البيانات واسعة النطاق، يتطلب البروتوكول استبدال كافة القيم الحسابية غير المعرفة في إطار البيانات دفعة واحدة بقيمة محددة مثل الصفر. ونظراً للخاصية الهيكلية التي تدمج NaN ضمن NA، فإن استخدام التعبير البرمجي المباشر df[is.na(df)] <- 0 يمثل الطريقة الأسرع والأشمل لتنفيذ هذا الاستبدال المتجهي على كافة الخلايا المتأثرة دون الحاجة لكتابة حلقات تكرارية معقدة.

مع ذلك، تنطوي هذه المعالجة الشاملة على مخاطرة تقنية محتملة؛ إذ إن تطبيق هذا التعبير على إطار بيانات يحتوي على أعمدة فئوية أو عوامل (Factors) وسلاسل نصية قد يولد أخطاء في توافق الأنماط (Type Incompatibility Errors) أو يفسد ترميز الفئات. لذلك، فإن الممارسة البرمجية الفضلى تقتضي حصر الاستبدال في الأعمدة ذات الطبيعة العددية فقط باستخدام دوال التحقق الشرطي، كما هو موضح في البناء التالي:

  • تحديد الأعمدة العددية باستخدام is.numeric.
  • تطبيق استبدال القيم داخل حلقة مخصصة أو دالة تحويلية تضمن سلامة الأعمدة النصية والفئوية.
  • إعادة تقييم مصفوفة البيانات للتأكد من عدم حدوث تحويلات قسرية مشوهة للأصناف البيانية.

9. إدارة قيم NaN باستخدام منظومة Tidyverse الحديثة

9.1 التنظيف والتحويل باستخدام حزمة dplyr

أحدثت منظومة حزم dplyr ثورة في أسلوب كتابة الشيفرات البرمجية في R عبر تبني مفهوم خطوط الأنابيب البرمجية (Pipes) باستخدام المعاملين %>% و |>، مما جعل عمليات تنقية وتطهير البيانات من قيم NaN أكثر وضوحاً وقابلية للقراءة والمراجعة المنهجية. تتيح الدالة filter() إمكانية عزل المشاهدات الصالحة وحذف الخلايا التالفة بسلاسة فائقة عبر التعبير df %>% filter(!is.nan(measurement)).

وعند الرغبة في إعادة تشكيل المتغيرات والتعويض المشروط داخل جداول البيانات التابعة لـ Tidyverse، تبرز الدالة التحويلية mutate() بالاشتراك مع الدالة الشرطية الصارمة if_else() أو الدالة متعددة الشروط case_when(). يتيح هذا الدمج إمكانية كتابة تحويلات برمجية غاية في الدقة، مثل استبدال NaN بمتوسط المجموعة التصنيفية التي تنتمي إليها المشاهدة، مع الحفاظ الكامل على سلامة البنية الجدولية وتدفق العمل التحليلي بصورة موثقة وشفافة.

9.2 التعويض المتقدم عبر حزمة tidyr

تتكامل حزمة tidyr مع أدوات معالجة البيانات لتوفير وظائف متخصصة في ضبط وتعديل القيم غير المكتملة. ومن أبرز هذه الأدوات تأتي الدالة replace_na()، والتي تسمح للمحلل بتمرير قائمة محددة تتضمن أزواجاً من (اسم العمود: القيمة التعويضية)، مما يتيح تعويض قيم الفقد وقيم NaN بقيم مختلفة ومخصصة لكل عمود على حدة وبأمر برمجي موحد وعالي الكفاءة.

إضافة إلى ذلك، توفر الحزمة الدالة الحركية fill()، والتي تستخدم خوارزميات الملء الاتجاهي اعتماداً على أحدث قيمة صالحة تم تسجيلها في السلسلة الزمنية أو الترتيب المكاني (Directional Filling: Down/Up). ورغم أن هذه الدوال صُممت أساساً للتعامل مع NA، إلا أن شمولية الفقد تجعلها تعالج قيم NaN بسلاسة ضمن خطط التحليل الزمنية، مما يمنح الباحثين مرونة هائلة تتفوق في وضوحها وتماسكها على دوال R الأساسية التقليدية.

10. تأثير قيم NaN على التحليلات والدوال الإحصائية المتقدمة

10.1 سلوك المعامل na.rm في الدوال الإحصائية الأساسية

تتبنى الدوال الإحصائية الأساسية في R مثل mean() و sd() و var() و median() مبدأ الحيطة الحسابية الصارمة؛ فعند تمرير متجه يحتوي على أدنى قيمة NaN إلى أي من هذه الدوال دون تعليمات إضافية، فإنها تُرجع فوراً NaN كنتيجة نهائية للمؤشر الإحصائي المستهدف. يهدف هذا السلوك الافتراضي إلى منع الباحث من تمرير نتائج إحصائية مشوهة دون علمه بوجود فساد حسابي في بياناته الخام.

لتجاوز هذه المشكلة وحساب المؤشرات بناءً على المشاهدات الصالحة عددياً فقط، تتضمن معظم هذه الدوال معاملاً تحكمياً مدمجاً هو na.rm (وهو اختصار لـ NA Remove). عند ضبط هذا المعامل ليصبح na.rm = TRUE، تقوم الدالة آلياً وبصورة داخلية بإسقاط كافة قيم NA وحالات NaN المرتبطة بها قبل الشروع في حساب المجاميع والبنى الإحصائية، مما يتيح إتمام العمليات الحسابية بنجاح مع تعديل درجات الحرية في المقام الحسابي وفق عدد القيم الصالحة فعلياً.

10.2 تداعيات NaN على نماذج الانحدار الخطي والتحليل المتعدد

عند الانتقال إلى بناء النماذج الإحصائية القياسية ونماذج التعلّم الإحصائي عبر دوال مثل lm() الخاصة بنماذج الانحدار الخطي العام أو glm() الخاصة بالنماذج الخطية المعممة، يكون لوجود قيم NaN تداعيات جوهرية على آلية التقدير. تعتمد هذه الدوال على معالج داخلي مخصص للتعامل مع القيم المفقودة يُدار عبر المعامل na.action، والذي يُضبط افتراضياً في R على الخيار na.omit.

يقوم هذا الخيار باستبعاد أي صف (سجل) يحتوي على قيمة NaN في المتغير التابع أو في أي متغير من المتغيرات المستقلة الداخلة في معادلة الانحدار استبعاداً تاماً وفق مبدأ الحذف القائم على القوائم (Listwise Deletion). يؤدي هذا الاستبعاد التلقائي إلى انخفاض حجم العينة الفعلي (Effective Sample Size)، مما يترتب عليه تقليص القوة الإحصائية (Statistical Power) للاختبارات وربما إحداث تحيز انتقائي (Selection Bias) إذا كان نمط ظهور الأخطاء الحسابية غير عشوائي، وهو ما يتطلب من المحلل فحص وتفسير بواقي النموذج (Residuals) ومطابقتها مع حجم البيانات الأصلي بعناية تامة.

11. أمثلة تطبيقية وحالات دراسية برمجية متكاملة

11.1 معالجة بيانات مقاييس وتجارب رقمية تحتوي على 0/0

لتجسيد كيفية التعامل الميداني مع قيم NaN المتولدة في التجارب الرقمية، سنفترض سيناريو معملياً واقعياً في دراسة لقياس زمن الاستجابة العصبية ومعدل دقة الأداء لدى مجموعة من الأفراد الخاضعين لمهام معرفية محوسبة. يحتوي المتجه التجريبي على عدد المحاولات الناجحة وعدد المحاولات الإجمالية، وعندما يعجز بعض الأفراد عن تنفيذ أي محاولة (المحاولات الإجمالية = 0 والناجحة = 0)، فإن حساب معدل النجاح عبر القسمة يولد حتماً قيماً غير معرفة 0 / 0.

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

11.2 خط أنابيب شامل لمعالجة إطار بيانات متعدد المتغيرات

في التطبيقات المتقدمة لعلم البيانات، تُنظم عمليات الفحص والتنظيف ضمن خط أنابيب برمجي متكامل ومحكم (End-to-End Pipeline). يبدأ هذا الخط باستيراد مصفوفة البيانات الخام متعددة المتغيرات، والتي تحتوي عادة على تشوهات حسابية مختلفة كاللوغاريتمات السالبة والقسمة على الصفر في أعمدة القياس المتعددة.

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

12. أفضل الممارسات البرمجية والوقاية من أخطاء NaN

12.1 كتابة شيفرات برمجية دفاعية (Defensive Programming)

تعد البرمجة الدفاعية المنهجية الأرقى للحد من ظهور قيم NaN بدلاً من الانتظار حتى توليدها ومعالجتها بأثر رجعي. تعتمد هذه المنهجية على تضمين شروط تحقق استباقية (Sanity Checks) وفحوصات منطقية داخل الدوال المخصصة قبل الشروع في تنفيذ العمليات الحسابية المعرضة للفشل الرياضي.

يشمل ذلك التحقق من أن قيم المقامات الحسابية لا تساوي صفراً قبل تنفيذ عمليات القسمة، واستخدام دالة pmax() أو الإزاحة الحسابية (Epsilon Shifts) لضمان بقاء مدخلات الدوال اللوغاريتمية موجبة قطعاً (مثل log(pmax(x, 1e-8)))، بالإضافة إلى بناء دوال تغليفية مخصصة تصدر تحذيرات استباقية دقيقة وموجهة فور اقتراب المتغيرات من الحدود العددية الحرجة، مما يضمن تدفقاً برمجياً آمناً ومحمياً ضد الانحرافات العددية.

12.2 التوثيق والتتبع وضمان قابلية إعادة الإنتاج (Reproducibility)

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

ولتحقيق ذلك على الصعيد التقني، يُنصح دائماً بالاحتفاظ بنسخ القراءة الأصلية للبيانات (Raw Immutable Data) دون تعديل مباشر، واستخدام أدوات ضبط الإصدارات مثل Git بالتوازي مع بيئات التقارير الديناميكية مثل Quarto و R Markdown. كما يُستحسن بناء اختبارات تحقق برمجية آلية (Unit Tests) باستخدام مكتبات متخصصة مثل testthat للتأكد المستمر من خلو مخرجات التحليلات والتحويلات الحسابية من أي قيم NaN شاذة قد تؤثر سلباً على النتائج والتوصيات النهائية.

خاتمة

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

إن التمييز الدلالي الصارم بين NaN و NA و NULL، وإتقان أدوات الرصد والعد والتنظيف، سواء عبر بيئة R الأساسية أو منظومة Tidyverse الحديثة، إلى جانب تبني مبادئ البرمجة الدفاعية والتوثيق المنهجي، يوفر للباحثين والمهندسين أرضية صلبة لبناء تحليلات تتسم بأعلى درجات الدقة والنزاهة الإحصائية والموثوقية العلمية.

المصادر والمراجع (References)

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

looti, M. (2026, سبتمبر 1). كيفية التعامل مع قيم NaN في لغة R (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/statistics/how-to-handle-nan-values-in-r-with-examples/
looti, Mohammed. “كيفية التعامل مع قيم NaN في لغة R (مع أمثلة).” عرب سايكلوجي, 1 سبتمبر 2026, https://arabpsychology.com/statistics/how-to-handle-nan-values-in-r-with-examples/.
looti, Mohammed. “كيفية التعامل مع قيم NaN في لغة R (مع أمثلة).” عرب سايكلوجي. سبتمبر 1, 2026. https://arabpsychology.com/statistics/how-to-handle-nan-values-in-r-with-examples/.