R: إطارات البيانات والعوامل في R

آخر تحديث: 2026-08-26

في الدروس التسعة السابقة، تعرفنا على المتجهات والمصفوفات والقوائم — ولكل منها حدودها. إطارات البيانات (data.frame) تحل كل هذه المشكلات: فهي سهلة القراءة مثل جدول بيانات Excel وفعالة مثل المصفوفة. في هذا الدرس، سنتعرف على «النجم» الحقيقي في لغة R — إطار البيانات.

تُعد إطارات البيانات ومكتبة «tidyverse» جوهر علم البيانات في لغة R. وابتداءً من هذا الدرس، سنبدأ رسميًّا في الغوص في عالم «تحليل البيانات باستخدام لغة R».

1. ما ستتعلمه



2. قصة تحويل ملف Excel إلى لغة R

(1) المشكلة: برنامج Excel غير قادر على التعامل مع ذلك

تحتوي جدول بيانات أبحاث السوق الخاص بـ «تشين» على 10,000 صف × 8 أعمدة:

TEXT 📖 للعرض فقط
EmployeesID  Name  Department    Salary   Years Performance Gender Start Date
2024001 Alice  Data Department  15000  3    A   M  2021-03-15
2024002 Bob  Engineering Department  18000  5    A+  M  2019-08-20
...

حساب متوسط الرواتب حسب «القسم»، والفرز حسب «الأداء»، وتحديد الموظفين ذوي الرواتب المرتفعة... يستغرق ذلك 30 دقيقة في برنامج Excel، مع صيغ متداخلة لدرجة أن البرنامج قد يتعطل.

(2) الحل باستخدام لغة R

R
library(dplyr)

# 5 Code execution complete 5 An Analysis
df |>
  group_by(Department) |>
  summarise(Average Wage = mean(Salary), Number of people = n()) |>
  arrange(desc(Average Wage)) |>
  filter(Average Wage > 15000)

5 أسطر من التعليمات البرمجية بدلاً من 30 دقيقة في Excel. هذه هي قوة DataFrame + dplyr.



3. data.frame: «الشخصية الرئيسية» في لغة R

(1) ما هو إطار البيانات؟

100%
graph TB
    A["Data Frame data.frame"] --> B["Each column = 1 equal-length vectors"]
    A --> C["Each line = 1 records"]
    A --> D["Mixed Types(Each column is independent)"]
    A --> E["The bottom layer is'A list of vectors of equal length'"]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda
    style D fill:#f8d7da
    style E fill:#e1d4ff

إطار البيانات هو "قائمة من المتجهات ذات الطول المتساوي":

(2) إنشاء إطار بيانات

R
# Methods 1:data.frame()(Basics R)
df <- data.frame(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92),
  passed = c(TRUE, TRUE, TRUE)
)
print(df)
#       name age score passed
# 1    Alice  25    95   TRUE
# 2      Bob  30    88   TRUE
# 3 Charlie  35    92   TRUE

# Methods 2:tibble(tidyverse Version,Recommendations)
# install.packages("tibble")
library(tibble)
df2 <- tibble(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92)
)
print(df2)

(3) data.frame مقابل tibble

Feature data.frame tibble
طباعة طباعة جميع الصفوف افتراضيًّا (قد يتسبب ذلك في تجميد النظام عند التعامل مع مجموعات بيانات كبيرة) طباعة أول 10 صفوف + أنواع الأعمدة افتراضيًّا
اسم العمود يدعم الأحرف الخاصة فرض الصحة
مجموعة فرعية من مجموعة فرعية df[, "col"] تُرجع متجهًا تُرجع دائمًا جدولًا (tibble)
الأداء أبطأ أسرع
سلسلة التحويل إلى عامل بشكل افتراضي الاحتفاظ بها كسلسلة
R
# View Structure
str(df)
# 'data.frame':	3 obs. of  4 variables:
#  $ name  : chr  "Alice" "Bob" "Charlie"
#  $ age   : num  25 30 35
#  $ score : num  95 88 92
#  $ passed: logi  TRUE TRUE TRUE

# Summary Statistics
summary(df)
#      name                age        score          passed
#  Length:3           Min.   :25   Min.   :88   Mode :logical
#  Class :character   1st Qu.:27   Median :92   TRUE:3
#  Mode  :character   Mean   :30   Mean   :91   NA's :0
#                     3rd Qu.:32   3rd Qu.:93
#                     Max.   :35   Max.   :95


4. الوصول إلى DataFrames

(1) 4 طرق للوصول

الطريقة الصيغة القيمة المرجعة الغرض
df[i, j] الصف i، العمود j قيمة عددية/متجه/إطار بيانات تركيبة الصف والعمود
df[i, ] الصف i DataFrame الحصول على الصف
df[, j] العمود j متجه (R الأساسي) / إطار البيانات استخراج العمود
df$name حسب اسم العمود متجه الحصول على العمود
df[["name"]] حسب اسم العمود متجه الحصول على العمود
R
df <- data.frame(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92)
)

# Retrieve a single element
df[2, 3]              # [1] 88
df[2, "score"]        # [1] 88

# Select the entire row
df[1, ]               # Entire row (Data Frame)
#     name age score
# 1 Alice  25    95

# Round an entire column
df[, "age"]           # Digital Vectors [1] 25 30 35
df$age                # Ibid.
df[["age"]]           # Ibid.

(2) الفهرس المنطقي (التصفية)

R
# Find the Fraction > 90 line
df[df$score > 90, ]
#       name age score
# 1    Alice  25    95
# 3 Charlie  35    92

# Multiple conditions
df[df$age > 25 & df$score > 85, ]

(3) ⚠️ هام: استرجاع الأعمدة في لغة R الأساسية مقارنةً بـ tibble

R
# base R:Retrieve the column return vector
df[, "age"]           # [1] 25 30 35  ← Digital Vectors

# tibble:Retrieve and return the column tibble
library(tibble)
tb <- as_tibble(df)
tb[, "age"]           # ← tibble(1 row 1 col)

# Want to extract a vector from tibble: Use [[ ]] or $
tb[["age"]]           # [1] 25 30 35  ← Digital Vectors
⚠️ ملاحظة: لا يتم تحويل [, "col"] في tibble تلقائيًا إلى متجه. وهذه ميزة تصميمية «أمانية» — فهي تمنع النظام من تفسير إطارات البيانات الكبيرة خطأً على أنها متجهات، مما قد يتسبب في تجميد عملية الطباعة بأكملها.



5. تعديل إطار البيانات

(1) إضافة عمود

R
# Use $ to add
df$city <- c("Beijing", "Shanghai", "Guangzhou")

# Use transform()
df <- transform(df, bonus = score * 100)

# Use within() to reference column names
df <- within(df, level <- ifelse(score >= 90, "A", "B"))

print(df)
#       name age score   city bonus level
# 1    Alice  25    95   Beijing  9500     A
# 2      Bob  30    88   Shanghai  8800     B
# 3 Charlie  35    92   Guangzhou  9200     A

(2) تعديل الأعمدة

R
# Array Assignment
df$age <- df$age + 1

# Condition Modification
df$score[df$name == "Bob"] <- 90

(3) حذف عمود

R
# Assign NULL
df$bonus <- NULL
df$level <- NULL

(4) إضافة/حذف الصفوف

R
# Add a row: Use rbind
new_row <- data.frame(name = "Diana", age = 28, score = 85, city = "Shenzhen")
df <- rbind(df, new_row)

# Delete Row:Using Negative Indexes
df <- df[-1, ]  # Delete 1st row


6. العامل: المتغير الفئوي

(1) لماذا نحتاج إلى العوامل؟

في لغة R، يُعد استخدام العوامل لتمثيل المتغيرات الفئوية (مثل «منخفض/متوسط/مرتفع») أكثر فعالية من استخدام متجهات الأحرف:

R
# Character vector(Disorder)
gender_char <- c("M", "F", "M", "F", "M")

# factor(Orderly + Finite values)
gender_factor <- factor(gender_char, levels = c("M", "F"))
gender_factor
# [1] M F M F M
# Levels: M F

(2) مزايا العوامل

100%
graph TB
    A["Character vector 'Low' 'Mid' 'High'"] --> B["factor factor<br/>+ levels Order<br/>+ Finite values<br/>+ Save memory"]
    A --> C["Disadvantages: Cannot sort and compare"]
    B --> D["Advantages: Can be compared for size<br/>Can be grouped in order<br/>Statistics/Knowing the Number of Categories in Modeling"]
    
    style A fill:#f8d7da
    style B fill:#d4edda
    style D fill:#cce5ff
R
# Compare Sizes(Characters cannot,Factors can)
sizes <- factor(c("S", "L", "Mid", "L", "S"),
                levels = c("S", "Mid", "L"),
                ordered = TRUE)

sizes[1] < sizes[2]   # TRUE  <- Characters can't do that!

(3) العمليات الشائعة على العوامل

R
# View levels
levels(sizes)
# [1] "S" "Mid" "L"

# Frequency Count
table(sizes)
# sizes
# S Mid L
#  2  1  2

# Reorder
sizes <- factor(sizes, levels = c("L", "Mid", "S"))  # Reverse the order
levels(sizes)
# [1] "L" "Mid" "S"
⚠️ ملاحظة: في عصر tidyverse، يُنصح باستخدام حزمة forcats (التي تمت مناقشتها في الدرس 11) للتعامل مع العوامل، لأنها أكثر أناقة من لغة R الأساسية.

(4) العوامل في إطار البيانات

R
# data.frame() Convert character strings to factors by default (This is a trap!)
df <- data.frame(
  name = c("Alice", "Bob"),  # Character vector
  stringsAsFactors = FALSE   # Disable Auto-Conversion(Recommendations)
)
str(df)
# $ name: chr "Alice" "Bob"  ← Preserve characters
💡 نصيحة: يستخدم الإصدار الجديد من R (4.x) stringsAsFactors = FALSE بشكل افتراضي، لكن قد تستخدم الأكواد القديمة قيمة مختلفة. يُنصح بكتابة stringsAsFactors = FALSE صراحةً.



7. البدء في استخدام dplyr: العناصر الخمسة الأساسية لمعالجة البيانات

يُعد dplyr جوهر «tidyverse»؛ تغطي خمس دوال 80% من سيناريوهات معالجة البيانات:

(1) التركيب والتحميل

R
install.packages("dplyr")
library(dplyr)

(2) الدالة المكونة من خمسة أجزاء

الوظيفة الغرض المكافئ في لغة SQL
filter() تصفية الصفوف WHERE
select() تحديد العمود SELECT
mutate() إضافة/تعديل عمود
arrange() فرز ORDER BY
summarise() إحصائيات إجمالية GROUP BY

(3) عامل التسلسل |>

R
# |> is R 4.1+'s "pipe symbol", Pass the result from the previous step to the next step
df |> filter(age > 25) |> select(name, age)

(4) تدريب عملي: معالجة بيانات الموظفين

R
# Prepare the data
employees <- tibble(
  id = 2024001:2024010,
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve",
           "Frank", "Grace", "Henry", "Ivy", "Jack"),
  department = c("Data Department", "Engineering Department", "Data Department", "Product Department", "Engineering Department",
                "Data Department", "Engineering Department", "Product Department", "Data Department", "Engineering Department"),
  salary = c(15000, 18000, 16000, 20000, 17000,
            15500, 19000, 21000, 16500, 17500),
  years = c(3, 5, 4, 7, 4, 2, 6, 8, 3, 5),
  performance = factor(
    c("A", "A+", "B", "A+", "A", "B", "A", "A+", "B", "A"),
    levels = c("B", "A", "A+"),
    ordered = TRUE
  )
)

# 1. filter:Screening Data Department Employees
data_dept <- employees |> filter(department == "Data Department")

# 2. select:Select a subset of columns
basic_info <- employees |> select(name, department, salary)

# 3. mutate:Add an "Annual Salary" column
employees <- employees |> mutate(annual_salary = salary * 12)

# 4. arrange:Sort by salary in descending order
ranked <- employees |> arrange(desc(salary))

# 5. summarise:By Department
dept_stats <- employees |>
  group_by(department) |>
  summarise(
    Number of people = n(),
    Average Wage = mean(salary),
    Highest Salary = max(salary),
    Total Annual Salary = sum(annual_salary)
  ) |>
  arrange(desc(Average Wage))

print(dept_stats)
# # A tibble: 3 × 5
#   department Number of people Average Wage Highest Salary Total Annual Salary
#   <chr>    <int>    <dbl>    <dbl>  <dbl>
# 1 Product Department       2   20500    21000 492000
# 2 Engineering Department       4   17875    19000 858000
# 3 Data Department       4   15750    16500 756000

(5) مثال على تركيبة من 5 خطوات

R
# Comprehensive Example:Identify High-Performing, High-Earning Employees
top_talent <- employees |>
  filter(performance %in% c("A+", "A")) |>     # Performance Screening A+ or A
  filter(salary > 16000) |>                     # ② Filter by High Salary
  mutate(salary_level = ifelse(salary > 18000, "High", "Upper-middle")) |>  # ③ Add Category
  arrange(desc(salary)) |>                      # ④ Sort
  select(name, department, salary, performance, salary_level)  # ⑤ Select Column

print(top_talent)
# # A tibble: 3 × 5
#   name   department salary performance salary_level
#   <chr>  <chr>       <dbl> <ord>       <chr>       
# 1 Henry  Product Department      21000 A+          High          
# 2 Diana  Product Department      20000 A+          High          
# 3 Bob    Engineering Department      18000 A+          Upper-middle
▶ جرّب الكود

8. مثال كامل: تحليل شامل لبيانات الموظفين

فيما يلي مثال على مسار عمل كامل يربط بين جميع المفاهيم التي تم تناولها في هذا الدرس.

▶ مثال: تحليل شامل لبيانات موظفي الشركة

R 📖 للعرض فقط
# ============================================
# Comprehensive Analysis of Company Employee Data
# Features:Using a DataFrame + dplyr Comprehensive Analysis 10 employees
# ============================================

library(dplyr)

# 1. Prepare data
employees <- tibble(
  id = 2024001:2024010,
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve",
           "Frank", "Grace", "Henry", "Ivy", "Jack"),
  department = c("Data Department", "Engineering Department", "Data Department", "Product Department", "Engineering Department",
                "Data Department", "Engineering Department", "Product Department", "Data Department", "Engineering Department"),
  salary = c(15000, 18000, 16000, 20000, 17000,
            15500, 19000, 21000, 16500, 17500),
  years = c(3, 5, 4, 7, 4, 2, 6, 8, 3, 5),
  performance = factor(
    c("A", "A+", "B", "A+", "A", "B", "A", "A+", "B", "A"),
    levels = c("B", "A", "A+"),
    ordered = TRUE
  )
)

cat("=== Raw Data ===\n")
print(employees)

# 2. View Structure
cat("\n=== Data Structures ===\n")
str(employees)

# 3. Summary Statistics
cat("\n=== Abstract ===\n")
summary(employees)

# 4. By Department
cat("\n=== By Department ===\n")
dept_summary <- employees |>
  group_by(department) |>
  summarise(
    Number of people = n(),
    Average Wage = mean(salary),
    Median Wage = median(salary),
    Highest Salary = max(salary),
    Minimum Wage = min(salary),
    Average Length of Service = round(mean(years), 1)
  ) |>
  arrange(desc(Average Wage))
print(dept_summary)

# 5. Identify High-Performing Employees (A+ or A)
cat("\n=== Employees with Outstanding Performance ===\n")
top_perf <- employees |>
  filter(performance %in% c("A+", "A")) |>
  arrange(desc(salary)) |>
  select(name, department, salary, performance, years)
print(top_perf)

# 6. Add"Pay Grade"col
cat("\n=== Salary Grade Classification ===\n")
employees <- employees |>
  mutate(
    salary_level = factor(
      ifelse(salary >= 18000, "High",
      ifelse(salary >= 16000, "Mid", "Low")),
      levels = c("Low", "Mid", "High"),
      ordered = TRUE
    ),
    annual_salary = salary * 12
  )

# By Pay Grade
level_summary <- employees |>
  group_by(salary_level) |>
  summarise(Number of people = n(), Average Wage = mean(salary))
print(level_summary)

# 7. Identify the Best Employees (High Salary + High Performance + Senior)
cat("\n=== Top Employee (High Salary + Outstanding Performance + Senior) ===\n")
top_talent <- employees |>
  filter(salary >= 17000, performance == "A+", years >= 5) |>
  select(name, department, salary, years, performance, annual_salary)
print(top_talent)
61 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

النتائج المتوقعة (مقتطف):

TEXT 📖 للعرض فقط
=== By Department ===
# A tibble: 3 × 7
  department  Number of people Average Wage Median Wage Highest Salary Minimum Wage Average Length of Service
  <chr>     <int>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1 Product Department        2   20500    20500    21000    20000      7.5
2 Engineering Department        4   17875    17750    19000    17000      4.5
3 Data Department        4   15750    15750    16500    15000      3  

=== Employees with Outstanding Performance ===
# A tibble: 6 × 5
  name   department salary performance years
  <chr>  <chr>       <dbl> <ord>       <dbl>
1 Henry  Product Department      21000 A+              8
2 Diana  Product Department      20000 A+              7
3 Bob    Engineering Department      18000 A+              5
4 Grace  Engineering Department      19000 A                6
5 Eve    Engineering Department      17000 A                4
6 Jack   Engineering Department      17500 A                5


❓ أسئلة شائعة

س ما هي مزايا العوامل؟
ج ثلاث مزايا رئيسية: ① يمكن مقارنة قيمها (ordered = TRUE) ② توفر مساحة الذاكرة (تخزن الترميزات الصحيحة فقط) ③ تتيح إجراء التحليل الإحصائي والنمذجة عندما يكون عدد الفئات معروفًا (مما يتجنب مشكلة «القيمة المجهولة»).

📖 ملخص


📝 تمارين

  1. تمرين أساسي: استخدم data.frame() لإنشاء إطار بيانات students (6 طلاب × 4 أعمدة: الاسم/العمر/الدرجة/النجاح). اطبع إطاري البيانات str() وsummary()، واطلع على جميع الأعمدة في الصف الثالث.

  2. المسألة الأساسية: حوّل العمود name من المسألة السابقة إلى factor (3 مستويات)، وقارن الفروق بين as.character() وas.numeric(). تحقق من أن العامل يدعم مقارنة القيم المطلقة (>).

  3. المسألة الأساسية: قم بتثبيت وتحميل dplyr، ثم استخدم filter() لتصفية الطلاب من score > 85 بناءً على students من المسألة السابقة، وقم بفرزهم بترتيب تنازلي حسب الدرجات باستخدام arrange().

  4. تمرين متقدم: استخدم tibble لإنشاء إطار بيانات sales (10 صفوف × 4 أعمدة: المنتج/المنطقة/المبلغ/التاريخ). ① استخدم mutate() لحساب مجموع discount = amount * 0.1؛ ② استخدم group_by(region) + summarise() لحساب إجمالي المبيعات لكل منطقة؛ ③ استخدم arrange(desc()) لترتيب المناطق.

  5. التحدي: باستخدام بيانات محاكاة للموظفين (10 موظفين، 3 أقسام، الراتب/سنوات الخدمة/الأداء)، أكمل التحليل المكون من 7 خطوات: ① قم بتحميل dplyr ② احسب عدد الموظفين ومتوسط الراتب حسب القسم ③ حدد الموظفين ذوي الرواتب المرتفعة الذين تبلغ مدة خدمتهم 5 سنوات أو أكثر ④ استخدم mutate لإضافة عمود للراتب السنوي ⑤ استخدم case_when (أو ifelse) للتصنيف حسب شرائح الرواتب ⑥ قم بالفرز حسب الأداء ⑦ اكتب في إطار بيانات جديد top_employees واحفظه كملف CSV (write.csv()).

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%