R: قراءة وكتابة ملفات CSV: دليل شامل لمكتبة readr

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

في الدروس العشر الأولى، ركزنا على البيانات داخل لغة R، ولكن في المشاريع الواقعية، يتم تخزين 99% من البيانات في ملفات خارجية. في هذا الدرس، سنتعرف على تنسيق البيانات الأكثر استخدامًا — ملفات CSV. يوفر لغة R طريقتين لقراءة وكتابة ملفات CSV: الطريقة القياسية في R read.csv وطريقة tidyverse readr، وتعتبر الطريقة الأخيرة أكثر ذكاءً وسرعةً.

بعد الانتهاء من هذا الدرس، ستتمكن من تحميل 1,000 صف من بيانات المبيعات إلى برنامج R في غضون 5 ثوانٍ وإنشاء تقارير منظمة.

1. ما ستتعلمه



2. إحدى المشكلات في استيراد البيانات

(1) المشكلة: يؤدي تحويل ملفات Excel إلى R إلى تجميد النظام

تشين محلل، وقد أرسل له مديره ملف CSV بحجم 100 ميغابايت يحتوي على بيانات المبيعات:

TEXT 📖 للعرض فقط
id,date,product,region,amount
1,2024-01-15,Cell Phone,Beijing,2999
2,2024-01-15,Computer,Shanghai,5999
3,2024-01-16,Cell Phone,Guangzhou,2899
...
(@,000 rows of)

قام بقراءة البيانات باستخدام read.csv()، وانتظر 30 ثانية، واستغرق الأمر 10 ثوانٍ أخرى لطباعة @,000 صفًا. كما اكتشف أن الأعمدة الخمسة جميعها كانت من النوع chr (الأرقام تُعامل كسلاسل نصية).

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

R
# 1. Use readr Smart Reading(5 s)
library(readr)
sales <- read_csv("sales.csv")

# 2. Automatic Type Inference
# id → integer, date → date, product → character,
# region → character, amount → double

# 3. Read only the rows you need(Speed Up 3x)
sales_sample <- read_csv("sales.csv", n_max = 10000)

# 4. Write clean reports
write_csv(sales_sample, "sales_clean.csv")

سطر واحد من التعليمات البرمجية = 30 ثانية → 5 ثوانٍ. هذه هي قوة readr.



3. ما هو CSV؟

(1) CSV = قيم مفصولة بفواصل

TEXT 📖 للعرض فقط
Name,Age,City
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou

(2) لماذا يُستخدم تنسيق CSV على نطاق واسع في علم البيانات؟

المزايا الوصف
عام متوافق مع Excel وPython وR وقواعد البيانات
نص قابل للقراءة يمكن عرضه مباشرة في برنامج «Notepad»
حجم ملف صغير أصغر بـ 5–10 مرات من Excel
متعدد المنصات لا تظهر أحرف مشوهة بسبب اختلاف إصدارات Excel
سهل الاستخدام خالٍ من التنسيقات أو الصيغ المعقدة في Excel
100%
graph LR
    A[CSV Documents<br/>name,age,city] --> B[read_csv Smart Reading]
    B --> C[tibble Clean DataFrame]
    C --> D[write_csv Reports]
    C --> E[dplyr Analysis]
    C --> F[ggplot2 Visualization]

    style A fill:#cce5ff
    style B fill:#d4edda
    style C fill:#fff3cd
    style D fill:#f8d7da
    style E fill:#e1d4ff
    style F fill:#ffe1d4


4. لغة R الأساسية مقابل tidyverse: نهجان للتعامل مع ملفات CSV

100%
mindmap
    root((CSV Read/write<br/>Two Options))
        Basics R
            read.csv
            write.csv
            Slow
            String Conversion factor
        tidyverse
            readr
                read_csv
                write_csv
                read_tsv
            Advantages
                Intelligent Type Inference
                Fast 5-10x
                Large File Progress Bar
                Strings are not converted factor
        Selection Recommendations
            New Project: tidyverse
            Legacy code: read.csv + stringsAsFactors = FALSE
            GB Level data: data.table::fread

(1) مقارنة بين النهجين

مقال خاص Base R read.csv tidyverse read_csv
السرعة بطيئة (متوافقة مع R) أسرع بـ 5–10 مرات (خلفية C++)
استدلال النوع ضعيف (الافتراضي: chr) الاستدلال الذكي (int/dbl/date/lgl)
شريط التقدم ✅ (يعمل بشكل جيد مع الملفات الكبيرة)
سلسلة التحويل إلى عامل بشكل افتراضي الاحتفاظ بها كسلسلة
نوع القيمة المرجعة data.frame tibble (أكثر سهولة في الاستخدام)
معالجة القوائم مقاومة للأخطاء التنظيف التلقائي (المسافات، الأحرف الخاصة)
قيمة مفقودة NA NA + سلسلة مخصصة
سلسلة stringsAsFactors = TRUE دائمًا FALSE

(2) المقارنة الفعلية

R
# Basics R(Common Issues with Legacy Code)
df_old <- read.csv("data.csv")
# Default behavior:Convert all string arrays factor(Pitfall!)

# tidyverse(Recommendations)
library(readr)
df_new <- read_csv("data.csv")
# Intelligent Inference Types,Character retains character
💡 نصيحة: استخدم readr لجميع المشاريع الجديدة؛ أما بالنسبة للرمز القديم، فاستخدم read.csv followed by stringsAsFactors = FALSE.

(3) متى ينبغي استخدام لغة R الأساسية؟

السيناريو التوصية
مشروع جديد / كتابة كود جديد read_csv (readr)
معالجة مجموعات البيانات الضخمة التي تبلغ حجمها غيغابايت data.table::fread (أسرع)
صيانة الكود القديم read.csv و stringsAsFactors = FALSE
درس تعليمي / برنامج نصي بسيط أي منهما


5. 8 معلمات شائعة لوظيفة read_csv()

(1) قواعد النحو الأساسية

R
read_csv(file, col_types = TRUE, col_names = TRUE, na = "NA",
         skip = 0, n_max = Inf, locale = default_locale(),
         progress = TRUE)

(2) جدول مرجعي سريع للمعلمات

المعلمة الوظيفة القيمة الافتراضية
file مسار الملف أو عنوان URL مطلوب
col_types مواصفات نوع العمود TRUE (يُستنتج تلقائيًا)
col_names TRUE/Vector (اسم عمود مخصص) TRUE (استخدام الصف الأول)
na علامة القيمة المفقودة "NA"
skip تخطي أول N أسطر 0
n_max الحد الأقصى لعدد الصفوف المراد قراءتها Inf (الكل)
locale الإعدادات الإقليمية (الترميز، النقطة العشرية) default_locale()
progress إظهار شريط التقدم TRUE

(3) تدريب عملي: المعلمات الشائعة

R
library(readr)

# 1. Basic Reading(Intelligent Inference Types)
df <- read_csv("data.csv")

# 2. Specify Column Type(Avoiding Fallacies in Reasoning)
df <- read_csv("data.csv", col_types = cols(
  id = col_integer(),
  date = col_date(format = "%Y-%m-%d"),
  amount = col_double(),
  name = col_character()
))

# 3. Skip to the beginning 5 Line Comments
df <- read_csv("data.csv", skip = 5)

# 4. Custom NA Mark(CSV For internal use "NULL" Indicates missing)
df <- read_csv("data.csv", na = c("", "NA", "NULL", "N/A"))

# 5. Read-only before 1000 row(For debugging purposes)
df <- read_csv("data.csv", n_max = 1000)

# 6. Skip Column(Use col_types Set as col_skip())
df <- read_csv("data.csv", col_types = cols(
  temp_col = col_skip()
))

(4) شرح مفصل لاستدلال الأنواع الذكي

أكبر ميزة لـ readr هي الاستدلال التلقائي:

بيانات نموذجية يُستنتج أنها
1, 2, 3 integer
1.5, 2.3 double
2024-01-15 date
12:30:00 time
TRUE, FALSE logical
Beijing, Shanghai character
R
# Examples of Inference
sales <- read_csv("sales.csv")
spec(sales)  # View the inference results
# cols(
#   id = col_integer(),
#   date = col_date(format = "%Y-%m-%d"),
#   product = col_character(),
#   region = col_character(),
#   amount = col_double()
# )


6. write_csv(): إخراج تقرير

(1) قواعد النحو الأساسية

R
write_csv(x, file, na = "NA", append = FALSE, col_names = TRUE)

(2) التطبيق العملي

R
# 1. Basic Output
write_csv(sales, "sales_clean.csv")

# 2. Output to the specified path
write_csv(sales, "output/2024_sales.csv")

# 3. Append to the existing file(Do not cover)
write_csv(new_data, "sales.csv", append = TRUE, col_names = FALSE)

# 4. Custom NA indicates
write_csv(df, "output.csv", na = "")

(3) ⚠️ لا يحافظ write_csv على أنواع البيانات

عندما يقوم برنامج «readr» بالكتابة إلى ملف CSV، تُفقد معلومات الأنواع (نظرًا لأن ملف CSV عبارة عن نص عادي). وعند قراءته مرة أخرى، يجب استنتاج الأنواع من جديد:

R
# Write
write_csv(sales, "sales.csv")

# Read it again
sales_loaded <- read_csv("sales.csv")
# Type by read_csv Re-inference
💡 نصيحة: استخدم .rds للتخزين الداخلي في R (الحفاظ على نوع البيانات) — انظر الدرس 12.



7. حل المشكلات الشائعة

(1) أحرف صينية مشوشة

R
# 1. Read Using a Specified Encoding
df <- read_csv("data.csv", locale = locale(encoding = "UTF-8"))
# Or
df <- read_csv("data.csv", locale = locale(encoding = "GBK"))

# 2. Check the file encoding
guess_encoding("data.csv")
# Returns in most cases "UTF-8" or "GBK"

# 3. Specify the encoding when writing
write_csv(df, "output.csv")  # Default UTF-8

(2) الفاصل ليس فاصلة

R
# 1. Tab-separated(TSV)
df <- read_tsv("data.tsv")  # sep = "\t"

# 2. Semicolon-separated(Commonly Used in Europe)
df <- read_csv2("data.csv")  # sep = ";"

# 3. Custom Delimiters(e.g. |)
df <- read_delim("data.txt", delim = "|")

(3) الأرقام التي تحتوي على فواصل الآلاف

R
# European Format:1.234,56(A percentile is .,A decimal is ,)
df <- read_csv("data_eu.csv",
               locale = locale(grouping_mark = ".", decimal_mark = ","))

(4) بطء قراءة الملفات الكبيرة

R
# 1. Read only the required columns(Speed Up 2-3x)
df <- read_csv("big.csv", col_select = c(id, amount))

# 2. Use col_types Skip Column
df <- read_csv("big.csv", col_types = cols(
  temp_col_1 = col_skip(),
  temp_col_2 = col_skip()
))

# 3. Close the progress bar
df <- read_csv("big.csv", progress = FALSE)

# 4. A Faster Solution:data.table::fread
# fread("big.csv") is 5-10x faster than read_csv


8. مستوى متقدم: تحديد نوع الأعمدة باستخدام الدالة cols()

(1) الصيغة الكاملة لدالة cols()

R
col_types = cols(
  id = col_integer(),       # Integer
  name = col_character(),   # Character
  amount = col_double(),    # Double-precision floating-point
  date = col_date(),        # Date
  time = col_time(),        # Time
  datetime = col_datetime(),# Date and Time
  is_active = col_logical(),# Logic
  skip = col_skip(),        # Skip this column
  guess = col_guess()       # Let readr infer
)

(2) الاختصار في استخدام السلاسل (أكثر إيجازًا)

R
# Use "i" "c" "d" "D" "l" Abbreviation
col_types = cols(
  id = "i",          # integer
  name = "c",        # character
  amount = "d",      # double
  date = "D",        # date
  is_active = "l"    # logical
)

# All Inferences(Default)
col_types = TRUE

# Using a list(Sequence-Mapped Columns)
col_types = list(
  id = col_integer(),
  name = col_character()
)


9. مثال كامل: استيراد بيانات المبيعات وتحليلها

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

▶ مثال: استيراد بيانات المبيعات + تنقية البيانات + إنشاء التقارير

R 📖 للعرض فقط
# ============================================
# Importing and Processing Sales Data
# Features:Read CSV → Cleaning → Analysis → Generate Report
# ============================================

library(readr)
library(dplyr)

# 1. Preparing Sample Data
sample_data <- tibble(
  id = 1:10,
  date = as.Date("2024-01-01") + 0:9,
  product = c("Cell Phone", "Computer", "Cell Phone", "Tablet", "Cell Phone",
              "Computer", "Tablet", "Cell Phone", "Computer", "Cell Phone"),
  region = c("Beijing", "Shanghai", "Guangzhou", "Beijing", "Shenzhen",
            "Shanghai", "Guangzhou", "Beijing", "Shenzhen", "Shanghai"),
  amount = c(2999, 5999, 2899, 3999, 3099,
            6299, 3899, 2899, 5999, 3199),
  note = c(NA, "Promo", NA, NA, "New Products", NA, NA, "Promo", NA, NA)
)

# Write Example CSV(UTF-8 Coding)
write_csv(sample_data, "sales_demo.csv")

cat("=== The file has been generated ===\n")

# 2. Read CSV(Intelligent Inference)
sales <- read_csv("sales_demo.csv",
                  na = c("", "NA"),
                  col_types = cols(
                    id = col_integer(),
                    date = col_date(format = "%Y-%m-%d"),
                    product = col_character(),
                    region = col_character(),
                    amount = col_double(),
                    note = col_character()
                  ))

cat("=== Read the results ===\n")
print(sales)

# 3. Data Quality Check
cat("\n=== Data Structures ===\n")
str(sales)

# 4. Data Analysis
cat("\n=== Sales Statistics ===\n")
summary_stats <- sales |>
  group_by(region) |>
  summarise(
    Number of Orders = n(),
    Total Sales = sum(amount),
    Average Order = round(mean(amount), 2),
    Highest Order = max(amount)
  ) |>
  arrange(desc(Total Sales))

print(summary_stats)

# 5. Find promotional orders
cat("\n=== Promotional Orders ===\n")
promo <- sales |> filter(!is.na(note))
print(promo)

# 6. By Product Category
cat("\n=== Product Sales ===\n")
product_stats <- sales |>
  group_by(product) |>
  summarise(Sales = n(), Sales = sum(amount))
print(product_stats)

# 7. Generate clean reports
write_csv(summary_stats, "sales_by_region.csv")
write_csv(product_stats, "sales_by_product.csv")
cat("\n=== The report has been generated ===\n")
cat("  - sales_by_region.csv(By Region)\n")
cat("  - sales_by_product.csv(By Product)\n")

# 8. Use RDS Reserved Types(Recommendations)
saveRDS(sales, "sales_clean.rds")
sales_reloaded <- readRDS("sales_clean.rds")
cat("\nRDS Type After Loading:\n")
print(sapply(sales_reloaded, class))
57 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

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

TEXT 📖 للعرض فقط
=== Sales Statistics ===
# A tibble: 4 × 5
  region Number of Orders Total Sales Average Order Highest Order
  <chr>   <int>   <dbl>    <dbl>    <dbl>
1 Beijing       3   9897    3299     3999
2 Shanghai       3  15497    5166.    6299
3 Guangzhou       2   6798    3399     3899
4 Shenzhen       2   9098    4549.    5999

=== Promotional Orders ===
# A tibble: 2 × 6
     id date       product region amount note
  <int> <date>     <chr>   <chr>   <dbl> <chr>
1     2 2024-01-02 Computer    Shanghai     5999 Promo
2     8 2024-01-08 Cell Phone    Beijing     2899 Promo


❓ أسئلة شائعة

س هل تظهر الأحرف الصينية كنص مشوه عند قراءة ملف CSV؟
ج استخدم locale = locale(encoding = "UTF-8") أو "GBK". إذا لم تكن متأكدًا من الترميز، فجرب guess_encoding() أولاً للتحقق.
س كيف يمكنني قراءة ملف CSV بحجم 1 جيجابايت؟
ج 3 خطوات للتحسين: ① col_select اقرأ الأعمدة التي تحتاجها فقط ② col_types تخطى الأعمدة غير الضرورية ③ قم بتعطيل progress = FALSE. إذا كان الأداء لا يزال بطيئًا، فاستخدم data.table::fread (أسرع).
س كيف أختار بين read_csv وfread؟
ج read_csv هو الإعداد الافتراضي في tidyverse ويتكامل جيدًا مع dplyr وggplot2؛ أما fread فهو أسرع (الخيار المفضل للبيانات على نطاق GB)، لكنه يتطلب تثبيت حزمة data.table. بالنسبة لمعظم المشاريع، يكفي استخدام read_csv.

📖 ملخص


📝 تمارين

  1. تمرين أساسي: أنشئ tibble يحتوي على 5 صفوف و4 أعمدة (id/name/score/date). استخدم write_csv() للكتابة في test.csv، ثم استخدم read_csv() لقراءته مرة أخرى، وتأكد من صحة استنتاج النوع (date من النوع Date).

  2. تمرين أساسي: اقرأ test.csv من السؤال السابق، واستخدم col_types = cols() لتحديد أنواع جميع الأعمدة بشكل صريح (id: عدد صحيح، score: عدد مزدوج، name: سلسلة، date: تاريخ)، وتأكد من أن الأنواع تتطابق مع المواصفات الصريحة.

  3. تمرين أساسي: أنشئ إطار بيانات يحتوي على قيم NA (باستخدام c(1, NA, 3, NA, 5))، وقم بتصديره إلى ملف CSV، ثم اقرأه باستخدام na = c("NA", "")، وتأكد من معالجة قيم NA بشكل صحيح.

  4. تمرين متقدم: قم بمحاكاة 100 سطر من بيانات المبيعات (المنتج/المنطقة/المبلغ/التاريخ). بعد استيراد البيانات باستخدام read_csv: ① احسب إجمالي المبيعات حسب المنطقة؛ ② حدد الطلبات الخمسة ذات المبالغ الأعلى؛ ③ استخدم read_csv لإنشاء تقريرين: top5.csv وby_region.csv.

  5. التحدي: أنشئ ملف CSV يحتوي على أحرف خاصة (أسماء أعمدة تحتوي على مسافات، وسلاسل تحتوي على فواصل، والفاصل |)، واقرأه باستخدام read_csv وread_delim على التوالي، وقارن الاختلافات في النتائج. التقط لقطة شاشة لإخراج وحدة التحكم واحفظها.

Web-Tutorial.com

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

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

100%