الإحصاء الوصفيتحليل البياناتلغة R

كيفية حساب المشاهدات حسب المجموعة في R

دليل أكاديمي شامل يشرح كيفية حساب عدد المشاهدات وتوزيع التكرارات حسب المجموعات في لغة R باستخدام حزمة dplyr والوظائف الإحصائية المتقدمة.

تاريخ النشر

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

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

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

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

1.1 المفهوم الإحصائي لتوزيع التكرارات وحساب المشاهدات

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

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

1.2 تطبيقات عد المجموعات في معالجة البيانات النفسية والسلوكية

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

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

1.3 نظرة عامة على أدوات لغة R في جدولة وتلخيص البيانات

توفر لغة R بيئة حوسبية ثرية تتسم بتعدد المدارس البرمجية لمعالجة البيانات وتلخيصها. تقليدياً، اعتمد الإحصائيون على أدوات لغة R الأساسية (Base R) التي تتضمن دوالاً مثل table() و aggregate() و tapply()، وهي دوال متينة ومستقرة ولا تتطلب أي اعتماديات خارجية، إلا أنها قد تصبح معقدة وصعبة القراءة عند التعامل مع البيانات متعددة المستويات والتقاطعات التصنيفية المركبة.

ومع تطور منظومة tidyverse، حدث تحول منهجي وفكري عميق في هندسة البيانات عبر تبني مفهوم البيانات المرتبة (Tidy Data) واستخدام خطوط الأنابيب (Pipelines) التي تتيح كتابة شيفرات برمجية شبيهة بالجمل المقروءة تسلسلياً. أدى هذا التحول إلى إكساب دوال مثل count() و group_by() في حزمة dplyr شعبية هائلة، نظراً لقدرتها الفائقة على اختصار خطوات التحليل، ورفع كفاءة المعالجة الذهنية للمحلل، وتوفير نتائج مهيكلة في هيئة أطر بيانات متطورة تندمج بسلاسة مع أدوات النمذجة والتمثيل البصري الحديثة.

2. تهيئة بيئة العمل وإعداد أطر البيانات النموذجية للتحليل

2.1 تثبيت وتحميل حزمة dplyr ومنظومة tidyverse

للانطلاق في تنفيذ عمليات عد المشاهدات المتقدمة، يتطلب الأمر تهيئة بيئة العمل في R بتثبيت الحزم الأساسية المخصصة لمعالجة البيانات. يتم تثبيت منظومة tidyverse المتكاملة، التي تشمل حزمة dplyr المسؤولة عن معالجة الجداول، عبر استدعاء الأمر القياسي install.packages("tidyverse") أو تثبيت حزمة dplyr بشكل مستقل عبر install.packages("dplyr") لترشيد استهلاك مساحة التثبيت والاعتماديات.

عقب اكتمال التثبيت، يتم تحميل المكتبة إلى جلسة العمل البرمجية باستخدام الأمر library(dplyr). ومن الضروري للباحث الإحصائي الانتباه إلى مسألة تضارب أسماء الدوال (Namespace Conflicts)؛ حيث تتضمن مكتبات أخرى دوالاً تشترك في الأسماء نفسها مثل دالتي filter أو count. لمعالجة هذا التضارب بصرامة برمجية، يمكن استخدام المعامل المحدد للنطاق dplyr::count() لضمان استدعاء الدالة الصحيحة دون أي التباس في التنفيذ البرمجي.

2.2 بناء إطار بيانات تجريبي متعدد المتغيرات

لضمان محاكاة واقعية للتطبيقات الإحصائية والنفسية، يتم بناء إطار بيانات تجريبي (Data Frame) يتضمن تنوعاً منهجياً في المتغيرات التصنيفية والرقمية. يفترض هذا السيناريو محاكاة دراسة سلوكية تفحص درجات القلق النفسي، والأداء المعرفي، واستجابات الأفراد عبر مجموعات تجريبية وضابطة متعددة الفئات الديموغرافية والطبية.

يشمل إطار البيانات محاكاة لمتغيرات اسمية (Nominal) كالنوع الاجتماعي (ذكر، أنثى)، ومتغيرات رتبية (Ordinal) كمستوى القلق (منخفض، متوسط، مرتفع)، ومتغيرات فئوية تجريبية (مجموعة العلاج السلوكي، مجموعة الدواء الوهمي، مجموعة العلاج المعرفي)، إلى جانب متغيرات رقمية مستمرة (Continuous) كدرجة الأداء المعرفي وزمن الرجع بالمللي ثانية. بعد توليد البيانات باستخدام دوال مثل data.frame() أو tibble()، يتم فحص البنية التحتية للمصفوفة باستخدام دوال الفحص الأساسية مثل str() و glimpse() للتأكد من سلامة تعريف الأنواع البيانية، وتطبيق دالة head() لمعاينة الصفوف الأولى من المشاهدات المولدة.

2.3 فهم معمارية الـ Tibble وتنسيق المخرجات الإحصائية

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

توفر كائنات الـ Tibble مزايا استثنائية عند عرض المخرجات الإحصائية في سطر الأوامر (Console)؛ إذ تقوم بطباعة أبعاد المصفوفة بوضوح، وتعرض الأنواع البيانية الدقيقة أسفل كل اسم عمود (مثل <chr> للنصوص و <fct> للعوامل و <int> للأعداد الصحيحة)، مع اقتصار العرض على أول عشرة صفوف تلقائياً لتجنب إغراق شاشة المخرجات بآلاف السجلات. تضمن هذه المعمارية انضباطاً عالياً وتوافقاً تاماً مع معايير القياس النفسي الحديث وحزم التحليل المتقدمة التي تتطلب هياكل بيانات صارمة التنسيق.

3. استخدام دالة count() الأساسية لحساب المشاهدات حسب متغير أحادي

3.1 البنية التركيبية لدالة count() وتطبيقها الأولي

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

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

3.2 استخدام عامل الربط Pipeline (%>%) لتبسيط الشيفرة البرمجية

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

بالمقارنة مع الصيغة المتداخلة التقليدية (Nested Functions) التي تتطلب قراءة الكود من الداخل إلى الخارج وتزيد من تعقيد الأقواس، تتيح الشيفرة المتسلسلة (Piped) قراءة منطق المعالجة من الأعلى إلى الأسفل ومن اليسار إلى اليمين كالنص المكتوب. فعند كتابة df %>% count(treatment_group)، يتضح فوراً للمراجع الإحصائي أننا نأخذ إطار البيانات ثم نطبق عليه عملية عد المشاهدات للمجموعة التجريبية، مما يرفع من جودة التوثيق البرمجي وقابلية إعادة الإنتاج للتحليلات الإحصائية.

3.3 تخصيص اسم عمود التكرار الناتج

في كثير من السياقات الأكاديمية والتقارير البحثية، قد لا يكون الاسم الافتراضي n لعمود التكرار كافياً أو معبراً بالشكل المطلوب، خاصة عند الرغبة في تمييز التكرارات وفق مصطلحات إحصائية دقيقة مثل “عدد_المشاركين” أو “حجم_العينة_الفرعية”. توفر دالة count() معاملًا داخلياً مرناً يدعى name يتيح تخصيص اسم العمود الناتج مباشرة أثناء الاستدعاء.

من خلال تحديد القيمة النصية للمعامل مثل count(group_var, name = "Sample_Size")، يتم استبدال n بالاسم المختار فوراً. تبرز أهمية هذه الميزة المنهجية في تجنب حدوث تعارض في أسماء الأعمدة إذا كان إطار البيانات الأصلي يحتوي بالفعل على عمود يسمى n يمثل متغيراً آخر (كالدرجات المعيارية أو ترقيم الأسئلة)، مما يضمن إنتاج جداول إحصائية خالية من الغموض ومهيأة للنشر المباشر في الجداول الوصفية للبحوث العلمية.

4. العد التقاطعي ومتعدد المتغيرات للمجموعات المتداخلة

4.1 تمرير متغيرات تصنيفية متعددة لدالة count()

في البحوث الميدانية والتجارب السلوكية المعقدة، نادراً ما يقتصر التحليل على فحص متغير تصنيفي واحد؛ إذ يتطلب الفهم المعمق دراسة التوزيعات التقاطعية لعدة متغيرات معاً. تتيح دالة count() تمرير عدد غير محدود من المتغيرات التصنيفية مفصولة بفواصل، مثل df %>% count(gender, education_level, treatment) لحساب المشاهدات عند تقاطع كافة المستويات لهذه المتغيرات.

ينتج عن هذه العملية مصفوفة توافقية متكاملة توضح حجم كل خلية تجريبية فرعية. ومن الناحية السيكومترية والمنهجية، يسهم هذا العد متعدد المتغيرات في كشف المشكلات الحرجة مثل وجود خلايا فارغة (Zero-count cells) أو مجموعات فرعية تعاني من نقص حاد في التمثيل، وهو ما يعد مؤشراً جوهرياً لعدم إمكانية تقدير بعض تفاعلات النماذج الإحصائية المعقدة (Interaction Effects) بدقة قبل البدء في التحليل الاستدلالي.

4.2 التعامل مع التفاعلات الهرمية والتصنيفات المركبة

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

يكتسب هذا البناء الهرمي أهمية بالغة في التصاميم متعددة المستويات (Multilevel Designs)، مثل دراسة أداء الطلاب المتداخلين داخل الفصول الدراسية، والفصول المتداخلة داخل المدارس، والمدارس المتداخلة داخل المحافظات التعليمية. يتيح العد المتسلسل استكشاف التوزيعات الشرطية للمتغيرات السلوكية بدقة عبر الطبقات الجغرافية والديموغرافية، مما يساعد على تشخيص التفاوت في أوزان الخلايا الفرعية وضبط أثر المعاينة العنقودية بدقة قبل تطبيق النماذج الخطية المختلطة (Hierarchical Linear Models).

4.3 إعادة تشكيل مخرجات العد المتعدد باستخدام pivot_wider()

غالباً ما تنتج دالة count() متعددة المتغيرات جداول تكرار في الهيئة الطويلة (Long Format)، حيث تخصص صفوف مستقلة لكل توليفة من الفئات. ومع أن هذا النسق مثالي للتحليلات الخوارزمية، إلا أن القراءة البشرية والتقارير الأكاديمية تفضل عادة جداول التقاطع الثنائي (Contingency Tables) في الهيئة العريضة (Wide Format) التي تماثل جداول اختبارات كاي تربيع (Chi-Square Test).

لتحقيق هذا التحويل بسلاسة داخل بيئة tidyverse، يتم دمج مخرجات العد مع دالة pivot_wider() من حزمة tidyr. يتم تحديد عمود الفئات الذي ستتحول قيمه إلى رؤوس أعمدة جديدة عبر المعامل names_from، وتحديد عمود التكرار n عبر المعامل values_from. ومن الاعتبارات الإحصائية الحيوية هنا استخدام المعامل values_fill = list(n = 0) لملء الخلايا الناتجة عن التقاطعات التي لا تتضمن أي مشاهدات فعلية بالقيمة صفر بدلاً من تركها كقيم مفقودة (NA)، مما يجعل الجدول جاهزاً للاختبارات الإحصائية غير المعلمية والتحليل الإحصائي المباشر.

5. ترتيب وتنظيم مخرجات التكرارات تصاعدياً وتنازلياً

5.1 تفعيل المعامل الإحصائي sort = TRUE

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

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

5.2 التحكم المتقدم في الفرز باستخدام دالة arrange()

في حين يوفر المعامل sort = TRUE ترتيباً تنازلياً بسيطاً لعمود n، فإن التحليلات المتقدمة تتطلب غالباً فرزاً مركباً يجمع بين معايير متعددة. تتيح حزمة dplyr دمج مخرجات العد مع دالة arrange() لتنفيذ فرز متعدد المستويات بدقة متناهية.

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

5.3 استخراج أعلى وأدنى الفئات تكراراً (Top-N Analysis)

تتطلب بعض المسائل البحثية عزل واقتطاع مجموعة فرعية محددة من الفئات تمثل الفئات المهيمنة أو الحالات النادرة في العينة المدروسة. يتم إنجاز هذا التحليل بدقة فائقة من خلال ربط مخرجات التكرارات بدالتي slice_max() و slice_min().

تسمح دالة slice_max(order_by = n, n = 5) باستخراج أعلى خمس فئات تكراراً في البيانات، وهو ما يفيد في رصد أكثر الاضطرابات النفسية شيوعاً في عينة سريرية معينة. وفي المقابل، تتيح دالة slice_min() استخراج الفئات النادرة أو الحالات الحدية (Edge Cases) التي قد تعكس أخطاء في إدخال البيانات أو ظواهر سلوكية استثنائية تستوجب دراسة كيفية مستقلة. كما يتيح المعامل with_ties = TRUE/FALSE التحكم الدقيق في كيفية معالجة الفئات التي تتساوى في التكرار عند حدود الاقتطاع الإحصائي.

6. حساب المشاهدات المرجحة وتطبيق الأوزان الإحصائية (Weighted Counts)

6.1 أهمية الأوزان الإحصائية في أبحاث القياس النفسي والمسوح الميدانية

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

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

6.2 تطبيق المعامل wt داخل دالة count()

صممت دالة count() في R لتدعم الحسابات المرجحة بمرونة فائقة من خلال المعامل الداخلي wt (اختصاراً لـ Weight). بدلاً من قيام الدالة بحساب كل صف كوحدة واحدة (1)، تقوم عند تمرير عمود الأوزان للمعامل wt = weight_variable بجمع القيم الرقمية للأوزان المناظرة لكل صف داخل كل فئة.

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

6.3 التعامل مع التكرارات النسبية والنسب المئوية المرجحة

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

عبر كتابة التعبير الرياضي mutate(percentage = (n / sum(n)) * 100)، يتم حساب الوزن النسبي المئوي لكل فئة فرعية منسوباً إلى إجمالي الأوزان التراكمية للعينة. يتيح توثيق الفروق بين النسب المئوية الخام والنسب المرجحة في الجداول الإحصائية تقييم دقة أوزان المعاينة، ورصد مدى نجاح الأوزان في تقليل خطأ المعاينة وتحسين تمثيل الفئات المهمشة أو ناقصة التمثيل في الدراسات السلوكية الواسعة.

7. استخدام ثنائية group_by() و summarise() كبديل تفصيلي متقدم

7.1 العلاقة الوظيفية بين دالة count() وثنائية التجميع والتلخيص

تعتمد فلسفة حزمة dplyr على مبادئ تقسيم البيانات وتطبيق العمليات وإعادة التجميع (Split-Apply-Combine Strategy). من الضروري للمحلل الإحصائي المتقدم إدراك أن دالة count() ليست في حقيقتها سوى اختصار برمجي أنيق وعالي التجريد للنمط البرمجي الشامل المتمثل في استدعاء دالة group_by() لتجميع البيانات، متبوعة بدالة summarise(n = n()) لحساب التكرارات، ثم تطبيق ungroup().

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

7.2 استخدام دالة العد n() وتوابع التلخيص المتزامنة

تتجلى القوة الحقيقية لثنائية group_by() و summarise() عند الرغبة في حساب حجم المجموعة بالتزامن مع حساب معالم النزعة المركزية ومؤشرات التشتت للمتغيرات السلوكية والنفسية المقاسة. يتم استخدام الدالة المساعدة n() لحساب عدد المشاهدات، والدالة mean() لحساب المتوسط، والدالة sd() لحساب الانحراف المعياري، والدالة median() لحساب الوسيط ضمن نفس الاستدعاء البرمجي.

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

7.3 تفكيك التجميع باستخدام دالة ungroup()

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

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

8. التعامل مع القيم المفقودة (NA) والمشاهدات الفريدة (Distinct Counts)

8.1 إدارة وحساب القيم المفقودة (NA) داخل المجموعات

تشكل البيانات المفقودة (Missing Data)، المعرفة في R بالرمز NA (Not Available)، تحدياً منهجياً متكرراً في الأبحاث السلوكية واستطلاعات الرأي. يتميز سلوك دالة count() بالشفافية الإحصائية التامة؛ حيث لا تقوم بإسقاط القيم المفقودة تلقائياً، بل تعتبر NA فئة قائمة بذاتها وتدرجها في جدول التكرارات مع حصر دقيق لعدد المشاهدات التابعة لها.

يتيح هذا السلوك الافتراضي للباحث تشخيص أنماط الفقدان (Missingness Patterns) ورصد ما إذا كان الفقدان عشوائياً تماماً أم مرتبطاً بفئات تجريبية محددة، وهو ما ينعكس مباشرة على مصداقية أدوات القياس النفسي. وإذا قرر الباحث استبعاد القيم المفقودة بعد توثيقها، يمكنه دمج دالة drop_na(variable_name) من حزمة tidyr أو filter(!is.na(variable_name)) قبل تمرير البيانات لدالة العد، مما يحصر الجدول في المشاهدات المكتملة فقط وفق المتطلبات المنهجية للتحليل.

8.2 حساب عدد المشاهدات الفريدة باستخدام n_distinct()

في العديد من التصاميم البحثية، خاصة التصاميم ذات القياسات المتكررة (Repeated Measures) أو الدراسات الطولية (Longitudinal Studies)، قد يسجل المشارك الواحد استجابات متعددة عبر نقاط زمنية مختلفة، مما يجعل إجمالي عدد المشاهدات (الصفوف) في المجموعة غير معبر عن العدد الحقيقي للأفراد المستقلين المشاركين في التجربة.

للتمييز الإحصائي الصارم بين عدد المشاهدات وعدد الحالات المستقلة، توفر حزمة dplyr الدالة المتخصصة n_distinct(). عند تطبيق هذه الدالة داخل summarise() على متغير معرف المشارك (Participant ID)، كأن يكتب summarise(total_obs = n(), unique_subjects = n_distinct(subject_id))، يستطيع الباحث بدقة متناهية مقارنة إجمالي نقاط البيانات المسجلة بالعدد الفعلي للأفراد، وهو ما يعد مدخلاً حاسماً لتحديد درجات الحرية الصحيحة في النماذج الإحصائية وتجنب تضخيم حجم العينة الاسمي في الاستدلال العلمي.

8.3 إظهار الفئات ذات التكرار الصفري باستخدام complete()

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

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

9. الطرق البديلة لحساب المشاهدات في لغة R الأساسية (Base R)

9.1 استخدام دالة table() لبناء جداول التكرار البسيطة والمتقاطعة

تمثل دالة table() الأداة الكلاسيكية الأكثر استخداماً في لغة R الأساسية (Base R) لحساب التكرارات دون الحاجة لتحميل أي مكتبات خارجية. تتميز الدالة بسرعة استدعائها للتحقق السريع من التوزيعات الفئوية لمتغير مفرد عبر table(df$group)، أو لبناء جداول تقاطع ثنائية ومتعددة الأبعاد بتمرير متجهين أو أكثر مثل table(df$gender, df$condition).

تتيح دالة table() التحكم في معالجة القيم المفقودة عبر المعامل useNA = "ifany" أو useNA = "always" لإدراج خانة خاصة بالمفقودات في الجدول المولد. ولتضمين هذه المخرجات في خطوط التحليل الآلية، يمكن تحويل كائن table الناتج إلى إطار بيانات قياسي عبر الدالة as.data.frame()، مما يعيد هيكلة التكرارات في صيغة أعمدة نظامية تتضمن الفئات وعمود التكرار Freq، مما يسهل معالجتها برمجياً لاحقاً.

9.2 تطبيق دالتي aggregate() و tapply() في التلخيص العددي

تعد دالتا aggregate() و tapply() من أدوات التلخيص القوية المدمجة في Base R، والتي تسمح بتطبيق دوال إحصائية عبر مستويات المتغيرات الفئوية. لحساب عدد المشاهدات باستخدام aggregate()، يتم استخدام صيغة المعادلات الرياضية (Formula Notation) مثل aggregate(id ~ group, data = df, FUN = length)، حيث تقوم الدالة بتجميع المشاهدات وحساب طول المتجه في كل فئة.

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

9.3 التقييم المقارن بين Base R و Tidyverse

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

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

10. التعامل مع البيانات الضخمة وتسريع الحوسبة باستخدام data.table

10.1 مقدمة لحزمة data.table ومعمارية الحوسبة فائقة السرعة

عند انتقال الباحث إلى معالجة مصفوفات البيانات الضخمة (Big Data)—مثل قواعد البيانات الناتجة عن تتبع السجلات السلوكية الرقمية، أو بيانات المستشعرات العصبية والفسيولوجية المتسلسلة زمنياً التي تتضمن ملايين الصفوف—قد تواجه حزمة dplyr القياسية قيوداً في سرعة المعالجة واستهلاك الذاكرة. هنا تبرز حزمة data.table كأقوى الحلول الحوسبية عالية الأداء في لغة R.

تعتمد معمارية data.table على مبدأ المعالجة الموضعية في الذاكرة (In-Memory Processing by Reference) دون إنشاء نسخ مكررة من الكائنات في الذاكرة العشوائية. تتمحور بنية الأوامر في الحزمة حول البناء الثلاثي المحكم DT[i, j, by]؛ حيث يخصص الموضع i لفلترة الصفوف، والموضع j لتنفيذ العمليات والحسابات على الأعمدة، والموضع by لتحديد متغيرات التجميع، مما يمنحها سرعة استثنائية تفوق معظم الأدوات المنافسة.

10.2 حساب التكرارات السريعة باستخدام الرمز الخاص .N

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

يتم حساب التكرارات المجمعة ببساطة متناهية من خلال كتابة التعبير DT[, .N, by = group_var]. تسمح هذه الصياغة المختصرة بحساب تكرارات ملايين المشاهدات المقسمة على مئات الآلاف من المجموعات الفرعية في أجزاء من الثانية الواحدة. تظهر اختبارات كفاءة الأداء (Benchmarking) أن استخدام .N في data.table يتفوق بمراحل زمنية ملحوظة على كافة الطرق الأخرى، مما يجعله الخيار المعياري بلا منازع عند التعامل مع السجلات النفسية والبيانات الحيوية فائقة الضخامة.

10.3 التحويل السلس بين بيئات data.table و tidyverse

لا يضطر المحلل الإحصائي إلى التضحية بسلاسة بناء جمل dplyr للاستفادة من سرعة data.table الخارقة؛ إذ توفر بيئة R حزمة جسرية متطورة تدعى dtplyr. تتيح هذه الحزمة كتابة أكواد برمجية قياسية باستخدام أسلوب dplyr (مثل df %>% count(group))، بينما تتولى في الخلفية ترجمة هذه الأوامر تلقائياً إلى صياغة data.table عالية السرعة وتنفيذها بكفاءة بالغة على كائنات lazy_dt.

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

11. التمثيل البصري لنتائج العد وحجم المجموعات باستخدام ggplot2

11.1 رسم التكرارات مباشرة باستخدام geom_bar() و geom_col()

يمثل العرض البياني للنتائج الإحصائية وسيلة لا غنى عنها لنقل الأفكار العلمية بوضوح وإبراز الفروق التوزيعية بين المجموعات. توفر حزمة ggplot2 التابعة لمنظومة tidyverse طريقتين أساسيتين لرسم التكرارات الفئوية عبر أعمدة المخططات البيانية (Bar Charts).

تعتمد الدالة الأولى geom_bar() على الحساب الإحصائي التلقائي الداخلي؛ حيث تأخذ المتغير الفئوي الخام وتقوم بحساب تكراراته ذاتياً ورسمها دون الحاجة لخطوة عد مسبقة. في المقابل، تستخدم الدالة الثانية geom_col() للرسم المباشر للقيم المحسوبة مسبقاً، وهي الطريقة المفضلة عند ربط مخرجات دالة count() مباشرة بمخطط الرسم عبر عامل الربط %>%، كأن يتم تمرير df %>% count(group) %>% ggplot(aes(x = group, y = n)) + geom_col()، مما يمنح المحلل تحكماً كاملاً في مخرجات البيانات الرقمية قبل تصييرها بيانياً في التقارير العلمية.

11.2 إضافة تسميات التكرارات والنسب المئوية فوق الأعمدة

لتعزيز القيمة الإخبارية للمخططات البيانية وتسهيل قراءتها الدقيقة دون إجهاد القارئ في تقدير الأرقام من المحاور، تتيح حزمة ggplot2 دمج التسميات الرقمية المباشرة فوق أو داخل الأعمدة البيانية باستخدام دالتي geom_text() أو geom_label().

من خلال تحديد المعامل الجمالي aes(label = n)، يتم رسم القيمة الدقيقة للتكرار لكل عمود. يتطلب التنسيق الاحترافي ضبط محاذاة النص عمودياً وأفقياً عبر المعاملين vjust و hjust لتجنب تداخل الأرقام مع حدود الأعمدة. كما يمكن دمج النسب المئوية المحسوبة إلى جانب التكرارات المطلقة في نص وصفي مركب مثل paste0(n, " (", round(percentage, 1), "%)")، مما ينتج مخططات بيانية متكاملة تجمع بين الدقة الوصفية والجاذبية البصرية للتقارير الأكاديمية.

11.3 تقسيم المخططات البيانية حسب المتغيرات الفرعية (Faceting)

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

يتيح هذا التقسيم مقارنة تكرارات الاستجابات السلوكية بدقة عبر مختلف المجموعات التجريبية أو الفئات العمرية بشكل مستقل ومتناسق. ولضمان عدم الوقوع في فخ المقارنات المضللة، يجب الانتباه لضبط مقاييس المحاور (Axes Scales)؛ حيث يفضل تثبيت المقاييس عبر كافة اللوحات لتسهيل المقارنة المباشرة، مع تطبيق المعايير التنسيقية الصارمة الخاصة بـ دليل النشر التابع لجمعية علم النفس الأمريكية (APA Style) في إخراج وتنسيق العناوين والمحاور وشبكات الرسوم البيانية للنشر العلمي الرصين.

12. أفضل الممارسات الإحصائية ومعالجة المشكلات الشائعة في عد المجموعات

12.1 فحص التوازن التجريبي وقوة الاختبار الإحصائي

لا تنتهي مهمة الباحث بمجرد استخراج جدول التكرارات، بل تمتد لتفسير الدلالات المنهجية لتلك الأرقام وتقييم أثرها على صحة التحليلات اللاحقة. إن وجود تفاوت حاد وغير متوقع في أعداد المشاهدات بين المجموعات التجريبية يثير مخاوف جدية تتعلق بانتهاك فرضية تجانس التباين (Homogeneity of Variance)، مما يتطلب استخدام اختبارات تصحيحية مثل اختبار ويلش (Welch’s ANOVA) بدلاً من الاختبار الكلاسيكي.

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

12.2 استكشاف الأخطاء الشائعة وحلها (Troubleshooting)

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

ومن المشكلات المتكررة أيضاً ظهور فئات مكررة ظاهرياً ولكنها منفصلة في الجدول، ويكون سبب ذلك وجود مسافات بيضاء زائدة (Trailing/Leading Whitespaces) أو عدم اتساق في حالة الأحرف والهمزات في النصوص المدخلة؛ ويتم حل ذلك بتنظيف النصوص مسبقاً باستخدام حزمة stringr عبر دالة str_trim() و str_squish(). بالإضافة إلى ذلك، يجب الانتباه لمعالجة العوامل التي تحتوي على مستويات غير مستخدمة (Unused Factor Levels) باستخدام دالة droplevels() أو forcats::fct_drop() لضمان عدم ظهور تصنيفات فارغة تشوش القراءة الإحصائية للمخرجات.

12.3 ضمان قابلية إعادة الإنتاج والتوثيق الأكاديمي للشيفرات

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

يفضل دمج كافة الأكواد وجداول المخرجات التحليلية والرسوم البيانية داخل بيئات التوثيق الديناميكي التفاعلية مثل R Markdown أو Quarto. تتيح هذه الأدوات إعادة توليد التقارير العلمية بنقرة واحدة عند تحديث البيانات الأصلية، مع توفير خيارات تصدير مباشرة لجداول التكرار بتنسيقات أكاديمية رفيعة المستوى مثل LaTeX و HTML و Word باستخدام حزم الجدولة المتقدمة مثل knitr::kable() و gt و modelsummary، مما يضمن أقصى درجات الشفافية والمصداقية للبحث الأكاديمي.

الخلاصة والخاتمة المنهجية

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

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

المراجع الأكاديمية (References)

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

looti, M. (2026, أغسطس 28). كيفية حساب المشاهدات حسب المجموعة في R. عرب سايكلوجي. https://arabpsychology.com/statistics/how-to-count-observations-by-group-in-r/
looti, Mohammed. “كيفية حساب المشاهدات حسب المجموعة في R.” عرب سايكلوجي, 28 أغسطس 2026, https://arabpsychology.com/statistics/how-to-count-observations-by-group-in-r/.
looti, Mohammed. “كيفية حساب المشاهدات حسب المجموعة في R.” عرب سايكلوجي. أغسطس 28, 2026. https://arabpsychology.com/statistics/how-to-count-observations-by-group-in-r/.