R: أنواع البيانات في لغة R: 6 أنواع أساسية وتحويل الأنواع

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

في الدرس السابق، تعرفنا على التعيين والإخراج. جميع البيانات في برامج R — سواء الأرقام أو النصوص أو القيم المنطقية — لها «أنواع» مميزة خاصة بها. في هذا الدرس، سنستكشف بالتفصيل أنواع البيانات الأساسية الستة في R وسنتقن «تحويل الأنواع»، وهي مهارة أساسية في علم البيانات باستخدام R.

لغة R هي لغة ذات أنواع ديناميكية، لكن هذا لا يعني أن الأنواع غير مهمة — فـ 90% من أخطاء R تتعلق بتحويلات الأنواع.

1. ما ستتعلمه



2. فخ «المساواة الظاهرية»

قبل كتابة أي كود، دعونا نلقي نظرة على مثال يربك عددًا لا يحصى من المبتدئين:

R
# These two numbers look the same, but R considers them "unequal"
1 == 1L
# [1] FALSE

# Verify their types
typeof(1)
# [1] "double"  (Double-precision floating-point numbers)

typeof(1L)
# [1] "integer" (Integer)

أليس هذا مخالفًا للمنطق؟ في لغة R، "1" و"1L" ليسا نفس الشيء. في هذا الدرس، سنكشف عن جميع أسرار أنواع البيانات في لغة R.



3. أنواع البيانات الستة الأساسية في لغة R

تنتمي جميع البيانات في لغة R إلى أحد الأنواع الأساسية الستة التالية:

100%
graph TB
    A[R Data Types]
    A --> B[numeric<br/>Double-precision floating-point numbers<br/>Default number]
    A --> C[integer<br/>Integer<br/>Need to add L Suffix]
    A --> D[character<br/>String<br/>Quotation marks must be used]
    A --> E[logical<br/>Logical value<br/>TRUE/FALSE]
    A --> F[complex<br/>Plural<br/>1+2i]
    A --> G[raw<br/>Byte<br/>as.raw 0xff]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#cce5ff
    style D fill:#d4edda
    style E fill:#f8d7da
    style F fill:#e1d4ff
    style G fill:#ffe1e1

(1) جدول عام للأنواع الستة

النوع المعنى مثال القيمة التي تُرجعها دالة typeof()
رقمي رقم عائم بدقة مزدوجة (الافتراضي) 3.14، -2.5، 1e3 "double"
عدد صحيح عدد صحيح (يجب أن يُلحق به L) 1L، 100L، -5L "integer"
الحرف سلسلة (يجب وضعها بين علامتي اقتباس) "Hello"، 'R' "character"
منطقي القيمة المنطقية (منطقية) TRUE، FALSE "logical"
مركب جمع 1+2i، 3-4i "complex"
خام نوع البايت as.raw(0xff) "raw"
💡 نصيحة: في عملية التطوير الفعلية، الأنواع الأربعة الأكثر استخدامًا هي: الرقمي، والحرفي، والمنطقي، والصحيح. أما النوعان «المعقد» و«الخام» فنادرًا ما يُستخدمان.

(2) شرح مفصل لكل نوع

R
# numeric —— Double-precision floating-point numbers(Default number)
x <- 3.14
typeof(x)
# [1] "double"

# integer -- Strict Integers (Add L Suffix)
x <- 10L
typeof(x)
# [1] "integer"

# character —— String
x <- "Hello R"
typeof(x)
# [1] "character"

# logical —— Logical value(Must be all uppercase)
x <- TRUE
typeof(x)
# [1] "logical"

# complex —— Plural
x <- 1 + 2i
typeof(x)
# [1] "complex"
⚠️ ملاحظة: يجب كتابة القيم المنطقية بأحرف كبيرة: لا يمكن كتابة TRUE على أنها true أو True؛ حيث سيؤدي ذلك إلى ظهور خطأ object 'true' not found.

(3) الأعداد الصحيحة مقابل الأعداد العائمة: متى يستخدم أي منهما؟

السيناريو النوع الموصى به السبب
الحسابات الرياضية العامة رقمية الإعداد الافتراضي في R؛ لا داعي للقلق بشأن هذا
المصفوفات العددية الكبيرة (أكثر من مليار عنصر) عدد صحيح توفر نصف الذاكرة
العمليات البتية، المعرّفات، العد عدد صحيح خالٍ من الغموض الدلالي
نتائج مقارنات الأرقام العائمة، sqrt()، وما إلى ذلك رقمي العمليات الحسابية هي بطبيعتها عمليات أرقام عائمة
R
# Performance Comparison(1 A billion integers vs 1 A billion floating-point numbers)
# integer: ~400 MB
# numeric: ~800 MB

# Not required in normal situations integer,numeric That's enough
💡 نصيحة: لن تحتاج إلى النوع integer على الإطلاق خلال مرحلة المبتدئين. ما لم تكن تجري حسابات واسعة النطاق (أكثر من مليار عنصر)، فإن النوع numeric يكفي.



4. typeof() مقابل class(): دالتان يسهل الخلط بينهما

يحتوي لغة R على دالتين يمكن لكلتيهما التحقق من «النوع»، لكن لكل منهما معنى مختلف.

(1) دليل مرئي سريع للاختلافات

100%
graph TB
    A["R Object"] --> B["typeof()<br/>Bottom Layer C Type<br/>6 Basic Types"]
    A --> C["class()<br/>Business OOP Class<br/>data.frame / Date / factor"]
    
    B --> D["double / integer<br/>character / logical<br/>complex / raw"]
    C --> E["Business Concepts<br/>(20+ kinds)"]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda

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

R
# 1. Ordinary Vectors:The two are consistent
x <- 1:10
typeof(x)
# [1] "integer"
class(x)
# [1] "integer"

# 2. Data Frame: The two are different!
y <- data.frame(a = 1:3, b = c("x", "y", "z"))
typeof(y)
# [1] "list"        ← The bottom layer is list

class(y)
# [1] "data.frame"  ← In business terms, it's a data frame.

(3) توصيات الاختيار

السيناريو أيهما يجب استخدامه
هل تريد معرفة «ما هذا داخل R» typeof()
هل تريد معرفة «ماذا يعني هذا بالنسبة للأعمال» class()
المبتدئون موصى به class() (أكثر سهولة في الاستخدام)


5. التحقق من النوع: مجموعة الدوال is.*

يوفر R مجموعة الدوال is.* للتحقق من الأنواع، وجميع الدوال تُرجع القيمة TRUE أو FALSE.

(1) وظائف الفحص الشائعة

وظيفة الفحص الغرض أمثلة على النتائج
is.numeric(x) هل القيمة عددية (عددية أو صحيح) is.numeric(1L) → TRUE
is.integer(x) هو عدد صحيح صارم (مع لاحقة "L") is.integer(1) → FALSE
is.character(x) عبارة عن سلسلة is.character("a") → TRUE
is.logical(x) هي قيمة منطقية is.logical(TRUE) → TRUE
is.na(x) هل القيمة المفقودة هي NA is.na(NA) → TRUE
is.null(x) هي NULL (قيمة فارغة) is.null(NULL) → TRUE

(2) المشكلة الرئيسية: لا يميز is.numeric() بين الأعداد الصحيحة والأعداد المزدوجة

R
# is.numeric() is the "superset" of is.integer()
is.numeric(1)     # [1] TRUE
is.numeric(1L)    # [1] TRUE
is.integer(1)     # [1] FALSE
is.integer(1L)    # [1] TRUE
💡 نصيحة: للتحقق مما إذا كانت القيمة عددًا، استخدم is.numeric()؛ وللتحقق مما إذا كانت عددًا صحيحًا صارمًا، استخدم is.integer().



6. تحويل الأنواع: مجموعة الدوال as.*

يمكن لمجموعة الدوال as.* في لغة R تحويل نوع ما إلى نوع آخر.

(1) وظائف التحويل الشائعة

دالة التحويل الغرض سلوك الفشل
as.numeric(x) → الرقم إرجاع «غير متوفر» + تحذير
as.integer(x) → عدد صحيح اقتطاع الأرقام العشرية
as.character(x) → سلسلة ناجحة دائمًا
as.logical(x) → القيمة المنطقية 0 → FALSE، الأرقام الأخرى → TRUE

(2) تكلفة عملية التحويل الفاشلة

R
# String → Numbers(Success)
as.numeric("3.14")
# [1] 3.14

# String → Numbers(Failure)
as.numeric("Hello")
# Warning: NAs introduced by coercion
# [1] NA
⚠️ ملاحظة: عند إجراء تحويل جماعي، تأكد من التحقق من عدد NA:

R
# One failure won't stop me,But there will be a warning
as.numeric(c("1", "2", "abc", "4"))
# Warning: NAs introduced by coercion
# [1]  1  2 NA  4

(3) سيناريو واقعي: عدم تطابق الأنواع بعد قراءة ملف CSV

تتمثل إحدى المشكلات الأكثر شيوعًا عند قراءة ملفات CSV في تفسير الأعمدة الرقمية على أنها أحرف:

R
# Suppose we read one CSV,All columns are character
df <- data.frame(
  id = c("1", "2", "3"),
  value = c("10.5", "20.3", "30.1")
)

# Before Conversion
str(df)
# 'data.frame':	3 obs. of  2 variables:
#  $ id   : chr  "1" "2" "3"
#  $ value: chr  "10.5" "20.3" "30.1"

# After conversion
df$id <- as.numeric(df$id)
df$value <- as.numeric(df$value)
str(df)
#  $ id   : num  1 2 3
#  $ value: num  10.5 20.3 30.1
💡 نصيحة: في الدرس 11، عندما نتعرف على readr::read_csv()، سيقوم باستنتاج النوع تلقائيًا — فهو أكثر ذكاءً بكثير من read.csv()، لذا لن تحدث هذه المشكلة.



  1. القيم الخاصة: NA / NaN / Inf / NULL

يحتوي لغة R على أربع قيم خاصة ذات معانٍ مختلفة تمامًا — وهذا يمثل أكبر عقبة أمام المبتدئين.

(1) العلاقة بين القيم الأربع الخاصة

100%
graph TB
    A["Missing values/Null value"]
    A --> B[NA<br/>Missing values Not Available<br/>Missing Data,Not assigned,Conversion Failed]
    A --> C[NaN<br/>Non-numeric Not a Number<br/>Not defined mathematically]
    A --> D[Inf<br/>Infinity Infinity<br/>1/0,exp 1000]
    A --> E[NULL<br/>Empty object<br/>Undefined,Functions with no return value]
    
    B --> F[Includes NaN]
    
    style A fill:#fff3cd
    style B fill:#d4edda
    style C fill:#f8d7da
    style D fill:#cce5ff
    style E fill:#e1d4ff

(2) جدول مقارنة بين أربع قيم خاصة

قيمة خاصة typeof المعنى سيناريو الاستخدام وظيفة الفحص
NA منطقي قيمة مفقودة بيانات مفقودة، غير مُعيَّنة، فشل التحويل is.na()
ليس رقمًا مزدوج غير رقمي 0/0، sqrt(-1) is.nan()
Inf double اللانهاية الموجبة 1/0، exp(1000) is.infinite()
NULL NULL كائن فارغ غير مُعرَّف، الدالة لا تُرجع أي قيمة is.null()

(3) غير متوفر: النوع الأكثر شيوعًا من «البيانات المفقودة»

R
# NA Participating in calculations is contagious(NA It won't disappear)
x <- c(1, 2, NA, 4)
sum(x)
# [1] NA  <- The entire result turned out NA

# Must use na.rm = TRUE Skip NA
sum(x, na.rm = TRUE)
# [1] 7

# Inspection NA Location
is.na(x)
# [1] FALSE FALSE  TRUE FALSE

(4) NaN: «غير مُعرَّف» في الرياضيات

R
# 0 Divide by 0
0 / 0
# [1] NaN

# Taking the square root of a negative number
sqrt(-1)
# Warning: NaNs produced
# [1] NaN

# NaN It is special. NA(NA a subset of)
is.na(NaN)
# [1] TRUE  ← NaN Me too NA

(5) معلومة: «اللانهاية» في الرياضيات

R
# 1 Divide by 0
1 / 0
# [1] Inf

# A negative number divided by 0
-1 / 0
# [1] -Inf

# Inspection Inf
is.infinite(c(1, Inf, -Inf, 2))
# [1] FALSE  TRUE  TRUE FALSE

(6) NULL: كائن فارغ (أو كائن غير موجود أصلاً)

R
# NULL Doesn't take up memory
x <- NULL
length(x)
# [1] 0

# NA occupies 1 position, NULL disappears entirely
length(c(1, 2, NA, 4))    # [1] 4
length(c(1, 2, NULL, 4))  # [1] 3  ← NULL Swallowed whole

# Default return value for functions with no return value NULL
my_void_func <- function() { }
result <- my_void_func()
is.null(result)
# [1] TRUE
⚠️ ملاحظة: الفرق الأساسي بين NA وNULL: NA تعني «الموضع موجود لكن القيمة غير معروفة»، بينما NULL تعني «الموضع غير موجود على الإطلاق». غالبًا ما تُستخدم الأولى للإشارة إلى البيانات المفقودة، بينما تُستخدم الثانية غالبًا عندما لا يكون للدالة قيمة إرجاع.



7. مثال كامل: تدريب شامل على تحويل الأنواع

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

▶ مثال: تنقية البيانات المدخلة من قبل المستخدم

R
# ============================================
# Cleaning User-Input Data
# Features:Convert a character vector to a number,Processing NA
# ============================================

# 1. Simulate from CSV Read"Dirty Data"(All of them character)
raw_data <- c("1", "2.5", "3.14", "abc", "5", "", "7.8")
cat("Raw Data:\n")
print(raw_data)
cat("Primitive Types:", typeof(raw_data), "\n\n")

# 2. Convert to a number ("abc" and "" will become NA)
nums <- as.numeric(raw_data)
cat("After conversion:\n")
print(nums)

# 3. See which ones are NA
na_positions <- is.na(nums)
cat("\nNA Location:")
print(na_positions)

# 4. Statistics NA Quantity
na_count <- sum(na_positions)
cat("\nNA Quantity:", na_count, "\n")

# 5. Keep only non- NA the number
clean_nums <- nums[!na_positions]
cat("\nData After Cleaning:")
print(clean_nums)

# 6. Statistical Indicators
cat("\n=== Statistical Indicators ===\n")
cat("Total Number of Elements:", length(raw_data), "\n")
cat("Valid Data:", length(clean_nums), "\n")
cat("Invalid data:", na_count, "\n")
cat("Total:", sum(clean_nums), "\n")
cat("Average:", round(mean(clean_nums), 2), "\n")
cat("Maximum value:", max(clean_nums), "\n")
cat("Minimum value:", min(clean_nums), "\n")
▶ جرّب الكود

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

TEXT 📖 للعرض فقط
Raw Data:
[1] "1" "2.5" "3.14" "abc" "5" "" "7.8"
Primitive Types: character

After conversion:
[1] 1.00 2.50 3.14   NA 5.00   NA 7.80

NA Location:
[1] FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE

NA Quantity: 2

Data After Cleaning:
[1] 1.00 2.50 3.14 5.00 7.80

=== Statistical Indicators ===
Total Number of Elements: 7
Valid Data: 5
Invalid data: 2
Total: 19.44
Average: 3.89
Maximum value: 7.8
Minimum value: 1

(1) الإجراء

الخطوة الإجراء الوصف
1 إنشاء مشروع RStudio r-types File → New Project
2 إنشاء برنامج نصي جديد data_cleaning.R نسخ الكود أعلاه
3 تحديد الكل → Ctrl+Enter إرسال إلى وحدة التحكم
4 راقب الناتج انظر إلى العلامة "NA" والنتائج بعد التنظيف


❓ أسئلة شائعة

س أيهما يجب أن أستخدم، typeof() أم class()؟
ج استخدم typeof() (6 أنواع أساسية) إذا كنت ترغب في التعرف على الأنواع الداخلية الأساسية في لغة R؛ واستخدم class() (data.frame/Date/factor) إذا كنت ترغب في التعرف على الأنواع المستخدمة في مجال الأعمال. بالنسبة للمبتدئين، يُعد class() أكثر سهولة في الفهم.
س لماذا تُرجع is.numeric(1L) القيمة TRUE، لكن is.integer(1L) تُرجع أيضًا القيمة TRUE؟
ج لأن is.numeric() هي «المجموعة الأم» لـ [YIJIAN3PH» — فالعدد الصحيح هو دائمًا قيمة رقمية، لكن العكس ليس صحيحًا. توصية: استخدم is.numeric() للتحقق مما إذا كانت القيمة «رقمًا»، واستخدم is.integer() للتحقق مما إذا كانت «عددًا صحيحًا صارمًا».
س كيف أختار بين NULL وNA؟
ج استخدم NA للإشارة إلى «بيانات مفقودة» (الموقع موجود، لكن القيمة غير معروفة)؛ واستخدم NULL للإشارة إلى «الكائن غير موجود» (لا يوجد حتى موقع). يُستخدم NA في الغالبية العظمى من سيناريوهات معالجة البيانات.

📖 ملخص


📝 تمارين

  1. تمرين أساسي: حدد 6 متغيرات تمثل أنواع البيانات الأساسية الستة (الرقمي، الصحيح، الحرفي، المنطقي، المركب، الخام). استخدم الأمر typeof() للتحقق من نوع كل متغير، واحفظ لقطات شاشة لنتائج الأوامر الستة typeof().

  2. المشكلة الأساسية: استخدم as.numeric() لتحويل المتجه الحرفي c("1", "2.5", "3.14", "abc", "5") إلى أرقام، وسجل رسائل التحذير ونتائج التحويل، واستخدم is.na() لتحديد العناصر التي أصبحت قيمتها NA. التقط لقطة شاشة لمخرجات وحدة التحكم واحفظها.

  3. تمرين أساسي: في وحدة التحكم في RStudio، احسب قيم 0/0 و1/0 و-1/0 وsqrt(-1)، وسجل كل نتيجة، ثم استخدم is.na() وis.nan() وis.infinite() للتحقق من القيمة الخاصة التي تنتمي إليها كل قيمة.

  4. مشكلة متقدمة: عرّف متجهًا باسم scores <- c(85, 92, NA, 78, NA, 95, 88). المتطلبات: ① احسب المجموع الكلي للدرجات (باستثناء القيم NA)؛ ② احسب متوسط الدرجات (باستثناء القيم NA، مع تقريب النتيجة إلى رقمين عشريين)؛ ③ استخدم !is.na() لتصفية العناصر التي ليست NA؛ ④ احسب عدد قيم NA. احفظ لقطة شاشة لنتائج كل خطوة.

  5. التحدي: اكتب برنامجًا نصيًّا بلغة R لمحاكاة «عدم تطابق الأنواع بعد قراءة ملف CSV»: ① قم يدويًّا بإنشاء إطار بيانات (data.frame) تكون جميع أعمدةه من النوع character؛ ② استخدم as.numeric() لتحويل أحد الأعمدة دفعة واحدة إلى نوع رقمي؛ ③ استخدم sum(is.na(df$col)) لحساب عدد العناصر التي فشل تحويلها؛ ④ استخدم paste() لإنشاء رسالة تحذير وعرضها. بعد تشغيل البرنامج النصي، التقط لقطة شاشة واحفظ مخرجات وحدة التحكم بالكامل.

Web-Tutorial.com

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

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

100%