R: R الإحصاء الوصفي
آخر تحديث: 2026-08-26
في الدروس الـ22 السابقة، تعرفنا على «أدوات» لغة R — المتجهات، وإطارات البيانات، وggplot2. والآن سننتقل إلى «القيمة» الحقيقية للغة R — التحليل الإحصائي. في هذا الدرس، سنبدأ بالمفهوم الأساسي: «الإحصاء الوصفي». سنستخدم لغة R لحساب المقاييس الرئيسية مثل المتوسط والوسيط والانحراف المعياري، و«تلخيص» البيانات في بضعة أرقام.
بعد الانتهاء من هذا الدرس، ستتمكن من إنشاء «تقرير إحصائي» لأي مجموعة بيانات باستخدام ثلاثة أسطر فقط من كود لغة R.
1. ما ستتعلمه
- الإحصاء الوصفي: 3 فئات رئيسية — قياس الميل المركزي، وقياس التشتت، وشكل التوزيع
- مقاييس التوجه المركزي: المتوسط/الوسيط/المنوال
- التشتت: الانحراف المعياري/التباين/المدى الربيعي/النطاق/المتوسط المطلق
- الشرائح المئوية: الشريحة المئوية/الوسيط/Q1/Q3
- summary() / skimr: إحصائيات سريعة
- dplyr + group_by: دليل للتجميع
- تجربة عملية: تقرير درجات الطلاب المكون من 1,000 سطر
2. قصة شهادة درجات أحد الطلاب
(1) التحدي: كيف يمكنك «تلخيص» 1,000 طالب؟
في نهاية الفصل الدراسي، يتعين على الأستاذ بوب إعداد تقارير الدرجات لـ 1,000 طالب. يدرس كل طالب 5 مقررات دراسية، وبالنسبة لكل مقرر، يتعين عليه حساب:
- المتوسط، الوسيط (مقاييس التوجه المركزي)
- الانحراف المعياري، الأرباع (مقاييس التشتت)
- أعلى درجة، أدنى درجة (القيم المتطرفة)
- الانحراف، التفرطح (شكل التوزيع)
الحسابات اليدوية؟ صيغ إكسل؟ هذا يستغرق ساعتين؛ أما باستخدام لغة R summary()——
(2) الحل باستخدام لغة R
# 1. One line summary shows 5 key metrics
summary(scores$math)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 45.0 72.0 82.0 81.5 92.0 99.0
# 2. One line skimr View the full report
library(skimr)
skim(scores$math)
# ── Variable type: numeric ──
# min max mean sd p25 p50 p75 hist
# 45 99 81.5 12 72 82 92 ▇▇▇▇▇
# 3. One line dplyr Grouped Statistics
scores |> group_by(class) |> summarise(
Average Score = mean(math),
Median = median(math),
Standard Deviation = sd(math),
Highest = max(math),
Lowest = min(math),
Number of people = n()
)
3 أسطر من التعليمات البرمجية → تقرير درجات كامل.
3. الفئات الثلاث الرئيسية للإحصاء الوصفي
(1) نظرة عامة على الفئات الثلاث الرئيسية
graph TB
A[Descriptive Statistics] --> B[Central Tendency<br/>Central Tendency]
A --> C[Degree of dispersion<br/>Dispersion]
A --> D[Distribution Patterns<br/>Shape]
B --> E[mean Median mode]
C --> F[sd var range IQR]
D --> G[Skewness skewness<br/>Fengdu kurtosis]
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#cce5ff
style D fill:#f8d7da
(2) جدول مرجعي سريع
| الفئة | الوظيفة | المعنى |
|---|---|---|
| الميل المركزي | mean() |
المتوسط الحسابي |
| الميل المركزي | median() |
الوسيط (الشريحة المئوية 50) |
| مركزي | mode() |
الوضع (يتطلب حزمة DescTools) |
| متفرقة | sd() |
الانحراف المعياري |
| منفصل | var() |
التباين |
| متفرقة | range() |
القيم المتطرفة (الحد الأدنى/الحد الأقصى) |
| متفرقة | IQR() |
المدى الربيعي (Q3-Q1) |
| متفرقة | mad() |
الانحراف المطلق الوسيط |
| التوزيع | skewness() |
الانحراف (يتطلب e1071) |
| التوزيع | kurtosis() |
التفرط (يتطلب e1071) |
4. الميل المركزي
(1) mean() المتوسط
x <- c(85, 90, 78, 92, 88)
mean(x) # [1] 86.6
mean(x, na.rm = TRUE) # Skip NA
mean(x, trim = 0.1) # Truncated Mean (Remove the top and bottom 10%)
(2) median() الوسيط
median(c(85, 90, 78, 92, 88)) # [1] 88
median(c(85, 90, 78, 92, 10000)) # [1] 90 ← Not affected by 10000 Impact
(3) الوضع (الوظائف الخاصة)
# R does not have a built-in mode(), use the DescTools package
install.packages("DescTools")
library(DescTools)
Mode(c(1, 2, 2, 3, 3, 3, 4)) # [1] 3
5. درجة التشتت
(1) sd() / var() الانحراف المعياري / التباين
x <- c(85, 90, 78, 92, 88)
sd(x) # [1] 5.32 ← Standard Deviation
var(x) # [1] 28.3 <- Variance (sd^2)
الانحراف المعياري = «المسافة المتوسطة» لنقاط البيانات عن المتوسط. كلما زادت القيمة، زاد تشتت البيانات.
(2) القيم المتطرفة لـ range()
x <- c(85, 90, 78, 92, 88)
range(x) # [1] 78 92 ← Minimum and Maximum
diff(range(x)) # [1] 14 ← Range
(3) IQR() النطاق الربيعي
x <- c(85, 90, 78, 92, 88, 70, 95, 65, 88, 92)
IQR(x) # [1] 11.5 ← Q3 - Q1
quantile(x, c(0.25, 0.5, 0.75))
# 25% 50% 75%
# 78.25 88.0 89.75
Q1 - 1.5*IQR ~ Q3 + 1.5*IQR).
(4) الانحراف المطلق للوسيط في mad()
mad(c(85, 90, 78, 92, 10000)) # Extremely Robust Discrete Measures
# [1] 4.45
6. الشرائح المئوية
(1) quantile() الشريحة
x <- 1:100
# Default 0%, 25%, 50%, 75%, 100%
quantile(x)
# 0% 25% 50% 75% 100%
# 1.0 25.75 50.5 75.25 100.0
# Custom Percentiles
quantile(x, probs = c(0.1, 0.5, 0.9))
# 10% 50% 90%
# 10.9 50.5 90.1
(2) المئويات الشائعة
| المئوية | الدالة | المعنى |
|---|---|---|
| Q0 (0٪) | min(x) |
الحد الأدنى |
| الربع الأول (25٪) | quantile(x, 0.25) |
الربع السفلي |
| الربع الثاني (50٪) | median(x) |
الوسيط |
| الربع الثالث (75٪) | quantile(x, 0.75) |
الربع العلوي |
| الربع الرابع (100٪) | max(x) |
الحد الأقصى |
7. summary() — سطر واحد من الإحصاءات الموجزة
x <- c(85, 90, 78, 92, 88, NA, 75, 95)
summary(x)
# Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
# 75.00 81.50 88.00 87.62 90.50 95.00 1
6 مؤشرات رئيسية + عدد «غير متاح» — كل ذلك في سطر واحد!
# Data Frame
df <- data.frame(
age = c(20, 25, 30, 35),
score = c(85, 90, 78, 92)
)
summary(df)
# age score
# Min. :20.00 Min. :78.00
# 1st Qu.:23.75 1st Qu.:83.25
# Median :27.50 Median :87.50
# Mean :27.50 Mean :86.25
# 3rd Qu.:31.25 3rd Qu.:90.50
# Max. :35.00 Max. :92.00
8. skimr: إحصاءات متقدمة وشاملة
install.packages("skimr")
library(skimr)
x <- c(85, 90, 78, 92, 88, 70, 95, 65, 88, 92)
skim(x)
# ── Data Summary ────────────────────────
# Values x
# Number of rows 10
# Number of distinct 8
# Mean 84.2
# Standard deviation 10.13
# Min 65
# Max 95
# Median 87.5
# ... (More Metrics)
skim() يوفر أكثر من 20 مؤشرًا — وهي أكثر تفصيلًا بعشر مرات من summary().
9. الإحصاء الوصفي حسب المجموعة
(1) dplyr + group_by + summarise
library(dplyr)
# Simulation 3 Cls × 5 Student Grades
scores <- tibble(
class = rep(c("1Cls", "2Cls", "3Cls"), each = 5),
student = paste0("S", 1:15),
math = c(85, 78, 92, 65, 88, # 1 Cls
90, 75, 80, 95, 70, # 2 Cls
82, 88, 76, 91, 85), # 3 Cls
english = c(78, 85, 88, 70, 92,
82, 80, 90, 88, 75,
88, 90, 78, 92, 85)
)
# Class Statistics
class_stats <- scores |>
group_by(class) |>
summarise(
Number of people = n(),
Mathematical Average = mean(math),
Median in Mathematics = median(math),
Mathematical Standard Deviation = sd(math),
Top in Math = max(math),
Lowest in Math = min(math),
MathematicsIQR = IQR(math),
Average English Score = mean(english)
)
print(class_stats)
# A tibble: 3 × 9
# class Number of people Mathematical Average Median in Mathematics Mathematical Standard Deviation Top in Math Lowest in Math MathematicsIQR Average English Score
# <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1Cls 5 81.6 85 11.4 92 65 17 82.6
# 2 2Cls 5 82 80 10.5 95 70 20 83
# 3 3Cls 5 84.4 85 6.02 91 76 12 86.6
(2) تفصيل متعدد المؤشرات (across)
# Calculate statistics for all numeric columns at once
scores |>
group_by(class) |>
summarise(across(where(is.numeric), list(
mean = mean,
sd = sd,
median = median
)))
(3) الصيغة القديمة لـ tapply (للإشارة)
# Use tapply
tapply(scores$math, scores$class, mean)
# 1Cls 2Cls 3Cls
# 81.6 82.0 84.4
10. تمرين عملي: تقرير شامل عن الدرجات لـ 1,000 طالب
فيما يلي مثال على مسار عمل كامل يربط بين جميع الإحصاءات الوصفية التي تمت تغطيتها في هذا الدرس.
▶ مثال: تقرير شامل عن 1,000 طالب و5 مقررات دراسية
# ============================================
# 1000 Student 5 Course Comprehensive Grade Report
# Features: Complete Descriptive Statistics + Grouping + Ranking
# ============================================
library(dplyr)
library(tidyr)
library(ggplot2)
# 1. Prepare data
set.seed(42)
n <- 1000
students <- tibble(
id = 1:n,
class = sample(c("1Cls", "2Cls", "3Cls", "4Cls", "5Cls"), n, replace = TRUE),
gender = sample(c("M", "F"), n, replace = TRUE),
math = round(rnorm(n, 80, 12)),
english = round(rnorm(n, 78, 15)),
physics = round(rnorm(n, 75, 14)),
chemistry = round(rnorm(n, 76, 13)),
biology = round(rnorm(n, 80, 10))
)
cat("=== Data Volume:", nrow(students), "rows ===\n")
# 2. University-wide Comprehensive Statistics
cat("\n=== University-wide Comprehensive Statistics ===\n")
overall <- students |>
summarise(across(c(math, english, physics, chemistry, biology),
list(mean = mean, sd = sd, median = median),
.names = "{.col}_{.fn}"))
print(overall)
# 3. Statistics by Class
cat("\n=== Math Statistics for Each Class ===\n")
class_stats <- students |>
group_by(class) |>
summarise(
Number of people = n(),
Average = round(mean(math), 2),
Median = median(math),
Standard Deviation = round(sd(math), 2),
Highest = max(math),
Lowest = min(math),
Q1 = quantile(math, 0.25),
Q3 = quantile(math, 0.75),
IQR = round(IQR(math), 2)
) |>
arrange(desc(Average))
print(class_stats)
# 4. Grouped by gender
cat("\n=== All genders 5 Class Average ===\n")
gender_stats <- students |>
group_by(gender) |>
summarise(across(c(math, english, physics, chemistry, biology),
mean, .names = "{.col}_Average"))
print(gender_stats)
# 5. Each Student's Total Score and Rank
cat("\n=== Top 10 Students (Total Score) ===\n")
students <- students |>
mutate(total = math + english + physics + chemistry + biology,
average = round(total / 5, 2))
top10 <- students |>
arrange(desc(total)) |>
head(10) |>
select(id, class, gender, total, average)
print(top10)
# 6. Identify the outliers (IQR method)
cat("\n=== Students with Outliers in Math Scores ====\n")
math_q1 <- quantile(students$math, 0.25)
math_q3 <- quantile(students$math, 0.75)
math_iqr <- IQR(students$math)
lower <- math_q1 - 1.5 * math_iqr
upper <- math_q3 + 1.5 * math_iqr
outliers <- students |>
filter(math < lower | math > upper) |>
select(id, class, math)
cat("Normal Range:", lower, "-", upper, "\n")
cat("Number of outliers:", nrow(outliers), "\n")
print(head(outliers, 5))
# 7. Use summary() to view by subject
cat("\n=== Mathematics summary ===\n")
print(summary(students$math))
# 8. Use skimr for advanced report
library(skimr)
cat("\n=== skimr Report ===\n")
print(skim(students |> select(math, english, physics)))
# 9. Write a report
write_csv(students, "student_report.csv")
write_csv(class_stats, "class_stats.csv")
cat("\n=== The report has been generated ===\n")
الناتج المتوقع (مقتطف):
=== Math Statistics for Each Class ===
# A tibble: 5 × 9
class Number of people Average Median Standard Deviation Highest Lowest Q1 Q3 IQR
<chr> <int> <dbl> <dbl> <dbl> <int> <int> <dbl> <dbl> <dbl>
1 5Cls 201 81.0 81 12.0 114 44 72 90 18
2 1Cls 195 80.6 81 11.6 115 47 73 88 15
3 3Cls 203 79.8 80 11.8 110 49 71 88 17
4 2Cls 201 79.4 80 12.1 109 44 70 88 18
5 4Cls 200 79.1 79 12.4 116 45 70 89 19
❓ أسئلة شائعة
summary() أم skim()؟summary موجز (6 مؤشرات)، بينما skim مفصل (أكثر من 20 مؤشرًا).na.rm = TRUE إلى جميع الدوال لتخطي القيمة NA. وإلا، فستكون نتائج المتجهات التي تحتوي على القيمة NA هي NA بالكامل.e1071::skewness() وe1071::kurtosis(). إذا كان الانحراف > 0، فإن التوزيع يكون منحرفًا إلى اليمين؛ وإذا كان < 0، فإنه يكون منحرفًا إلى اليسار. وإذا كان التفرطح > 0، فإن التوزيع يكون أكثر حدة من التوزيع الطبيعي؛ وإذا كان < 0، فإنه يكون أكثر استواءً.📖 ملخص
- تنقسم الإحصاءات الوصفية إلى ثلاث فئات رئيسية: الاتجاه المركزي (المتوسط/الوسيط/المنوال)، مقاييس التشتت (الانحراف المعياري/التباين/المدى الربيعي)، وشكل التوزيع (الانحراف/الذروة)
- يتأثر المتوسط بالقيم المتطرفة، في حين أن الوسيط أكثر ثباتًا — في حالة التوزيعات غير المتماثلة، استخدم الوسيط أولاً
- sd هو الانحراف المعياري بنفس وحدات القياس المستخدمة في البيانات الأصلية، و var يساوي sd²
- IQR = Q3 - Q1، وهو مقياس قوي للتشتت يُستخدم عادةً للكشف عن القيم المتطرفة
summary(x)6 مؤشرات في كل صف، الأكثر استخدامًا؛skim(x)أكثر من 20 مؤشرًا، تقرير مفصل- وصف المجموعة:
dplyr::group_by() |> summarise(across(where(is.numeric), mean)) - معالجة NA: إضافة
na.rm = TRUEإلى جميع الوظائف - القيم المتطرفة: < Q1 - 1.5×IQR أو > Q3 + 1.5×IQR (طريقة قوية)
📝 تمارين
-
المشكلة الأساسية: قم بإنشاء متجه
x <- c(85, 90, 78, 92, 88, NA, 75, 95)، واحسب القيم باستخدامmean()وmedian()وsd()وvar()(لاحظna.rm = TRUE)، وتحقق من صحة النتائج الثماني. -
تمرين أساسي: استخدم
summary()وquantile(x, c(0, 0.25, 0.5, 0.75, 1))لحساب المقاييس الإحصائية لنفس المتجه، وقارن بين النتيجتين. -
المشكلة الأساسية: أنشئ إطار بيانات (3 فصول × 5 طلاب × مادتين: الرياضيات واللغة الإنجليزية)، واستخدم
dplyr::group_by + summarise + acrossلحساب المتوسط والانحراف المعياري لجميع المواد في جميع الفصول في عملية واحدة. -
تمرين متقدم: قم بمحاكاة درجات 1,000 طالب في 5 مقررات دراسية، واستخدم
skimr::skim()لإنشاء تقرير كامل، وحدد القيم المتطرفة في درجات الرياضيات (باستخدام طريقة IQR)، واحسب النسبة المئوية للطلاب الذين حصلوا على درجات متطرفة. -
التحدي: إكمال سير العمل — قم بمحاكاة درجات 1,000 طالب في 5 مقررات دراسية: ① وصف عام ② وصف مجمَّع حسب الفصل الدراسي ③ وصف مجمَّع حسب الجنس ④ الترتيب ⑤ الكشف عن القيم الشاذة ⑥ إنشاء تقرير بتنسيق CSV + تقرير نصي بتنسيق Markdown (استخدم
knitr::kable()لعرض الجداول). احفظ لقطات شاشة للعملية.