Menu
flag Ar iconالعربيةdown icon

المخطط الشريطي في R: ‏barplot() من الأعداد والجداول

كيفية إنشاء مخطط شريطي في R بدالة barplot(): من متجه مسمّى أو من table()، والأشرطة المجمّعة والمكدّسة من مصفوفة، والتنسيق، وgeom_col مقابل geom_bar.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

المخططات الشريطية تقارن الفئات

يجيب المخطط الشريطي عن سؤال "كم من كل نوع؟" بشريط لكل فئة، ويبيّن طول الشريط قيمة تلك الفئة. والدالة في base R هي barplot()، ومدخلها ببساطة متجه من الارتفاعات. أعطِ المتجه أسماءً فتصبح الأسماء التسميات تحت الأشرطة:

visits <- c(Mon = 42, Tue = 51, Wed = 47, Thu = 60, Fri = 78)

barplot(visits,
        main = "Store visits by day",
        ylab = "Visits")

خمسة أشرطة رمادية مسمّاة بالأيام، تتسلق من يوم اثنين متواضع إلى ذروة يوم الجمعة التي تكاد تبلغ ضعف ارتفاعه. لا شيء يُثبَّت ولا شيء يُضبط، فإن استطعت بناء متجه مسمّى استطعت رسمه.

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

سير العمل الحقيقي: ‏table() أولًا ثم barplot()

نادرًا ما تملك عمليًا ارتفاعات مرتبة ومعدودة مسبقًا. بل لديك عمود خام من تسميات الفئات، بصف لكل استجابة استبيان أو طلب أو مستخدم، والعدّ هو العمل الفعلي. وتفعله table() في استدعاء واحد، ومخرجاتها متجه أعداد مسمّى، وهو بالضبط ما تريده barplot():

ثم يكون الرسم سطرًا إضافيًا واحدًا:

barplot(sort(t, decreasing = TRUE),
        main = "Survey responses",
        ylab = "Count")

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

التسميات والتنسيق

تأتي التسميات عادةً من أسماء المتجه، لكن names.arg يتجاوزها، وهو مفيد حين لا تصلح رموز البيانات للعرض على جمهور:

barplot(visits,
        names.arg = c("Monday", "Tuesday", "Wednesday",
                      "Thursday", "Friday"),
        col    = "steelblue",
        border = NA,
        main   = "Store visits by day",
        las    = 2)
  • يملأ col الأشرطة، ومرّر متجهًا لتلوين كل شريط على حدة، لكن قاوم اعتماد ألوان قوس قزح افتراضيًا، فينبغي أن يعني اللون شيئًا، كإبراز الشريط الوحيد الذي تتحدث عنه.
  • يزيل border = NA حدود الأشرطة لمظهر أنظف.
  • يدير las = 2 تسميات المحور لتصبح عمودية عليه، وهو الحل لأسماء الفئات الطويلة المتداخلة. وادمجه مع هامش سفلي أكبر (par(mar = c(8, 4, 4, 2))) إن كانت الأسماء طويلة فعلًا.

الأشرطة المجمّعة والمكدّسة من مصفوفة

لعرض بُعدين فئويين دفعة واحدة، كالمبيعات لكل قناة ولكل ربع، مرّر مصفوفة إلى barplot(). فيصبح كل عمود موضعًا واحدًا على محور الفئات، وتصبح الصفوف الأشرطة الفرعية:

sales <- matrix(c(12, 18,   15, 22,   20, 19,   24, 27),
                nrow = 2,
                dimnames = list(c("Online", "Retail"),
                                c("Q1", "Q2", "Q3", "Q4")))

# Grouped: rows stand next to each other within each quarter
barplot(sales, beside = TRUE,
        col = c("steelblue", "orange"),
        legend.text = rownames(sales),
        main = "Sales by channel and quarter")

# Stacked: rows pile up into one total bar per quarter (the default)
barplot(sales, beside = FALSE,
        col = c("steelblue", "orange"),
        legend.text = rownames(sales))

يضع beside = TRUE القناتين كتفًا إلى كتف داخل كل ربع، وهو الأفضل حين تريد مقارنة القناتين مباشرة. أما التكديس الافتراضي فيبرز الإجمالي لكل ربع مع عرض التقسيم داخل كل شريط، وهو صادق بشأن المجاميع لكنه يصعّب مقارنة القطاعات الداخلية عبر الأشرطة لأن خطوط أساسها تتزحزح. ويضيف legend.text = rownames(sales) مفتاح الإيضاح الذي يجعل أيًّا من النسختين مقروءًا.

ومفتاح إضافي: يمدّ horiz = TRUE الأشرطة على امتداد المحور الأفقي. وهو أرحم تخطيط لفئات كثيرة ذات أسماء طويلة، إذ تقع كل تسمية على سطرها الخاص بجوار شريطها بلا حاجة إلى تدوير.

مخطط شريطي أم مدرج تكراري؟

يخلط الباحثون بينهما باستمرار، والتمييز يستحق ثلاثين ثانية: يقارن المخطط الشريطي فئات منفصلة، فالمحور مجموعة تسميات، والأشرطة متباعدة، وإعادة ترتيبها مشروعة. أما المدرج التكراري فيقسّم متغيرًا عدديًا واحدًا إلى سلال، فالمحور مقياس متصل، وتتلامس الأشرطة لأن السلال فترات متتالية، وإعادة ترتيبها ستكون عبثًا. فإذا كان عمودك يحوي كلمات ("Yes" أو "Chrome" أو "Q3") فأنت تريد barplot(table(x))، وإذا كان يحوي قياسات (أطوالًا أو أسعارًا أو أزمنة استجابة) فأنت تريد المدرج التكراري وhist(x).

ggplot2: ‏geom_col مقابل geom_bar

تأتي نسخة ggplot2 في شكلين هندسيين، يفصل بينهما ما إذا كان العدّ قد أُنجز أصلًا:

library(ggplot2)

# geom_bar(): raw observations in, counting done for you
ggplot(survey, aes(x = response)) +
    geom_bar(fill = "steelblue")

# geom_col(): heights already computed, one row per bar
totals <- data.frame(day = c("Mon", "Tue", "Wed", "Thu", "Fri"),
                     visits = c(42, 51, 47, 60, 78))

ggplot(totals, aes(x = day, y = visits)) +
    geom_col(fill = "steelblue")

geom_bar() هي table() مدمجة داخل الرسم: تأخذ صفًا لكل ملاحظة وتحصيها. أما geom_col() فتأخذ بيانات مجمّعة مسبقًا وتربط عمود y بارتفاع الشريط، وهي مكافئة barplot() الكلاسيكية. وتمرير بيانات معدودة مسبقًا إلى geom_bar() هو الفخ المعتاد للمبتدئين: إذ تعدّ الصفوف (صفًا لكل فئة) فتخرج كل الأشرطة بالارتفاع نفسه.

الخلاصة

  • ترسم barplot(heights) متجهًا مسمّى، وتنتج table(x) هذا الشكل بالضبط من بيانات فئوية خام، لذا فإن barplot(table(x)) هي الصيغة الجوهرية.
  • رتّب الجدول (أو اضبط مستويات العامل) قبل الرسم، فترتيب الأشرطة جزء من الرسالة.
  • تعطي المصفوفة أشرطة مجمّعة (beside = TRUE) أو مكدّسة (افتراضيًا)، فأضف legend.text = rownames(m).
  • يتولى names.arg وcol وlas = 2 وhoriz = TRUE أمر التسمية، والأشرطة الأفقية أفضل للأسماء الطويلة.
  • الفئات ← مخطط شريطي، والسلال العددية ← مدرج تكراري. وفي ggplot2: الصفوف الخام ← geom_bar()، والارتفاعات المحسوبة ← geom_col().

في المستند التالي: ggplot2 نفسها، أي القواعد التي تبني كل هذه المخططات وأكثر منها بكثير من البضع القطع القابلة للتركيب ذاتها.

الأسئلة الشائعة

كيف تنشئ مخططًا شريطيًا في R؟

استدعِ barplot() على متجه من الارتفاعات. أعطِ المتجه أسماءً، أو ابنِه بـ table() التي تكون مخرجاتها مسمّاة أصلًا، فيصبح كل عنصر شريطًا مسمّى واحدًا: barplot(table(df$category)).

كيف تنشئ مخططًا شريطيًا مجمّعًا أو مكدّسًا في R؟

مرّر مصفوفة. يصبح كل عمود موضعًا واحدًا على محور الفئات، ويرسم beside = TRUE الصفوف أشرطة متجاورة (مجمّعة)، بينما تكدّسها القيمة الافتراضية beside = FALSE. أضف legend.text = rownames(m) ليميّز القراء الصفوف بعضها عن بعض.

ما الفرق بين barplot() وhist() في R؟

تقارن barplot() فئات منفصلة، بشريط لكل فئة وأشرطة متباعدة. أما hist() فتقسّم متغيرًا عدديًا واحدًا إلى فترات متتالية، وتتلامس الأشرطة لأن المحور مقياس متصل. فإذا كان متغيرك كلمات فأنت تريد barplot(table(x))، وإذا كان أرقامًا فأنت تريد hist(x).

هل أستخدم geom_bar أم geom_col في ggplot2؟

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

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن