R: قراءة وكتابة ملفات CSV: دليل شامل لمكتبة readr
آخر تحديث: 2026-08-26
في الدروس العشر الأولى، ركزنا على البيانات داخل لغة R، ولكن في المشاريع الواقعية، يتم تخزين 99% من البيانات في ملفات خارجية. في هذا الدرس، سنتعرف على تنسيق البيانات الأكثر استخدامًا — ملفات CSV. يوفر لغة R طريقتين لقراءة وكتابة ملفات CSV: الطريقة القياسية في R
read.csvوطريقة tidyversereadr، وتعتبر الطريقة الأخيرة أكثر ذكاءً وسرعةً.
بعد الانتهاء من هذا الدرس، ستتمكن من تحميل 1,000 صف من بيانات المبيعات إلى برنامج R في غضون 5 ثوانٍ وإنشاء تقارير منظمة.
1. ما ستتعلمه
- ما هو ملف CSV، ولماذا يُستخدم في علم البيانات؟
- الفرق بين R الأساسي
read.csvوـ tidyversereadr read_csv()8 معلمات شائعة (col_types، na، skip، n_max، إلخ)write_csv()إنشاء تقرير- التعامل مع المشكلات الشائعة (الترميز، القيم المفقودة، الفواصل)
- نصائح لقراءة الملفات الكبيرة (التقسيم إلى أجزاء، وتحسين النوع)
2. إحدى المشكلات في استيراد البيانات
(1) المشكلة: يؤدي تحويل ملفات Excel إلى R إلى تجميد النظام
تشين محلل، وقد أرسل له مديره ملف CSV بحجم 100 ميغابايت يحتوي على بيانات المبيعات:
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
# 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 = قيم مفصولة بفواصل
Name,Age,City
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou
- كل سطر = سجل واحد
افصل الحقول بـ
,(أو;|\t). - عادةً ما يكون الصف الأول هو أسماء الأعمدة (الرأس)
- يدعم علامات الاقتباس في السلاسل
"..."لمعالجة الحقول التي تحتوي على فواصل
(2) لماذا يُستخدم تنسيق CSV على نطاق واسع في علم البيانات؟
| المزايا | الوصف |
|---|---|
| عام | متوافق مع Excel وPython وR وقواعد البيانات |
| نص قابل للقراءة | يمكن عرضه مباشرة في برنامج «Notepad» |
| حجم ملف صغير | أصغر بـ 5–10 مرات من Excel |
| متعدد المنصات | لا تظهر أحرف مشوهة بسبب اختلاف إصدارات Excel |
| سهل الاستخدام | خالٍ من التنسيقات أو الصيغ المعقدة في Excel |
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
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) المقارنة الفعلية
# 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) قواعد النحو الأساسية
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) تدريب عملي: المعلمات الشائعة
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 |
# 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) قواعد النحو الأساسية
write_csv(x, file, na = "NA", append = FALSE, col_names = TRUE)
(2) التطبيق العملي
# 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 عبارة عن نص عادي). وعند قراءته مرة أخرى، يجب استنتاج الأنواع من جديد:
# 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) أحرف صينية مشوشة
# 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) الفاصل ليس فاصلة
# 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) الأرقام التي تحتوي على فواصل الآلاف
# European Format:1.234,56(A percentile is .,A decimal is ,)
df <- read_csv("data_eu.csv",
locale = locale(grouping_mark = ".", decimal_mark = ","))
(4) بطء قراءة الملفات الكبيرة
# 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()
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) الاختصار في استخدام السلاسل (أكثر إيجازًا)
# 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. مثال كامل: استيراد بيانات المبيعات وتحليلها
فيما يلي مثال على مسار عمل كامل يربط بين جميع المفاهيم التي تم تناولها في هذا الدرس.
▶ مثال: استيراد بيانات المبيعات + تنقية البيانات + إنشاء التقارير
# ============================================
# 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))
النتائج المتوقعة (مقتطف):
=== 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
❓ أسئلة شائعة
locale = locale(encoding = "UTF-8") أو "GBK". إذا لم تكن متأكدًا من الترميز، فجرب guess_encoding() أولاً للتحقق.col_select اقرأ الأعمدة التي تحتاجها فقط ② col_types تخطى الأعمدة غير الضرورية ③ قم بتعطيل progress = FALSE. إذا كان الأداء لا يزال بطيئًا، فاستخدم data.table::fread (أسرع).read_csv وfread؟read_csv هو الإعداد الافتراضي في tidyverse ويتكامل جيدًا مع dplyr وggplot2؛ أما fread فهو أسرع (الخيار المفضل للبيانات على نطاق GB)، لكنه يتطلب تثبيت حزمة data.table. بالنسبة لمعظم المشاريع، يكفي استخدام read_csv.📖 ملخص
- يُعد CSV تنسيق البيانات الأكثر تنوعًا: فهو نص عادي، ويمكن قراءته بصريًّا، ويعمل عبر الأنظمة المختلفة، كما يمكن قراءته بواسطة برامج Excel وPython وR وقواعد البيانات
- موصى به:
readr::read_csv—أسرع بـ 5 إلى 10 مرات من الإصدار الأساسي Rread.csv، مع استدلال أنواع ذكي وتوافق مع Tibble - 8 معلمات شائعة الاستخدام:
col_types(تحديد النوع)،na(علامة NA)،skip،n_max،col_select،locale،progress،col_names - الاستدلال التلقائي على الأنواع: عدد صحيح / عدد عائم / تاريخ / وقت / تاريخ ووقت / قيمة منطقية / سلسلة أحرف
write_csv()يُخرج تقريرًا، لكنه لا يحافظ على نوع البيانات — استخدمsaveRDS()/readRDS()للاحتفاظ بالبيانات داخليًّا في R- استخدم
locale = locale(encoding = "UTF-8")في حالة ظهور الأحرف الصينية مشوشة؛ وإذا لم يكن الفاصل هو,، فاستخدمread_tsvأوread_delim - تحسين الملفات الكبيرة:
col_select+col_types = col_skip()+ تعطيل عرض شريط التقدم
📝 تمارين
-
تمرين أساسي: أنشئ
tibbleيحتوي على 5 صفوف و4 أعمدة (id/name/score/date). استخدمwrite_csv()للكتابة فيtest.csv، ثم استخدمread_csv()لقراءته مرة أخرى، وتأكد من صحة استنتاج النوع (dateمن النوع Date). -
تمرين أساسي: اقرأ
test.csvمن السؤال السابق، واستخدمcol_types = cols()لتحديد أنواع جميع الأعمدة بشكل صريح (id: عدد صحيح، score: عدد مزدوج، name: سلسلة، date: تاريخ)، وتأكد من أن الأنواع تتطابق مع المواصفات الصريحة. -
تمرين أساسي: أنشئ إطار بيانات يحتوي على قيم NA (باستخدام
c(1, NA, 3, NA, 5))، وقم بتصديره إلى ملف CSV، ثم اقرأه باستخدامna = c("NA", "")، وتأكد من معالجة قيم NA بشكل صحيح. -
تمرين متقدم: قم بمحاكاة 100 سطر من بيانات المبيعات (المنتج/المنطقة/المبلغ/التاريخ). بعد استيراد البيانات باستخدام
read_csv: ① احسب إجمالي المبيعات حسب المنطقة؛ ② حدد الطلبات الخمسة ذات المبالغ الأعلى؛ ③ استخدمread_csvلإنشاء تقريرين:top5.csvوby_region.csv. -
التحدي: أنشئ ملف CSV يحتوي على أحرف خاصة (أسماء أعمدة تحتوي على مسافات، وسلاسل تحتوي على فواصل، والفاصل
|)، واقرأه باستخدامread_csvوread_delimعلى التوالي، وقارن الاختلافات في النتائج. التقط لقطة شاشة لإخراج وحدة التحكم واحفظها.