R: أنواع البيانات في لغة R: 6 أنواع أساسية وتحويل الأنواع
آخر تحديث: 2026-08-26
في الدرس السابق، تعرفنا على التعيين والإخراج. جميع البيانات في برامج R — سواء الأرقام أو النصوص أو القيم المنطقية — لها «أنواع» مميزة خاصة بها. في هذا الدرس، سنستكشف بالتفصيل أنواع البيانات الأساسية الستة في R وسنتقن «تحويل الأنواع»، وهي مهارة أساسية في علم البيانات باستخدام R.
لغة R هي لغة ذات أنواع ديناميكية، لكن هذا لا يعني أن الأنواع غير مهمة — فـ 90% من أخطاء R تتعلق بتحويلات الأنواع.
1. ما ستتعلمه
- أنواع البيانات الستة الأساسية في لغة R (الرقمية، الصحيحة، الحرفية، المنطقية، المركبة، الأولية)
- الفرق بين
typeof()وclass() is.*مجموعة دوال التحقق من النوعas.*مجموعة دوال تحويل الأنواع- الاختلافات بين القيم الأربع الخاصة (NA، NaN، Inf، NULL)
- سيناريوهات تحويل الأنواع الشائعة في التطبيقات العملية
2. فخ «المساواة الظاهرية»
قبل كتابة أي كود، دعونا نلقي نظرة على مثال يربك عددًا لا يحصى من المبتدئين:
# 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 إلى أحد الأنواع الأساسية الستة التالية:
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) شرح مفصل لكل نوع
# 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()، وما إلى ذلك |
رقمي | العمليات الحسابية هي بطبيعتها عمليات أرقام عائمة |
# 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) دليل مرئي سريع للاختلافات
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) المقارنة الفعلية
# 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() بين الأعداد الصحيحة والأعداد المزدوجة
# 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) تكلفة عملية التحويل الفاشلة
# String → Numbers(Success)
as.numeric("3.14")
# [1] 3.14
# String → Numbers(Failure)
as.numeric("Hello")
# Warning: NAs introduced by coercion
# [1] NA
NA:
# 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 في تفسير الأعمدة الرقمية على أنها أحرف:
# 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
readr::read_csv()، سيقوم باستنتاج النوع تلقائيًا — فهو أكثر ذكاءً بكثير من read.csv()، لذا لن تحدث هذه المشكلة.
- القيم الخاصة: NA / NaN / Inf / NULL
يحتوي لغة R على أربع قيم خاصة ذات معانٍ مختلفة تمامًا — وهذا يمثل أكبر عقبة أمام المبتدئين.
(1) العلاقة بين القيم الأربع الخاصة
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) غير متوفر: النوع الأكثر شيوعًا من «البيانات المفقودة»
# 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: «غير مُعرَّف» في الرياضيات
# 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) معلومة: «اللانهاية» في الرياضيات
# 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: كائن فارغ (أو كائن غير موجود أصلاً)
# 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. مثال كامل: تدريب شامل على تحويل الأنواع
فيما يلي مثال على مسار عمل كامل يربط بين جميع المفاهيم التي تم تناولها في هذا الدرس.
▶ مثال: تنقية البيانات المدخلة من قبل المستخدم
# ============================================
# 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")
الناتج المتوقع (مقتطف):
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 في الغالبية العظمى من سيناريوهات معالجة البيانات.📖 ملخص
- أنواع البيانات الأساسية الستة في لغة R: رقمي (الافتراضي)، صحيح (يُضاف إليه اللاحقة
L)، حرفي (سلسلة)، منطقي (بولياني)، مركب (الأعداد المركبة)، خام (بايت) typeof()يتناول أنواع البيانات في لغة C على المستوى الأساسي (6 أنواع أساسية)؛class()يتناول أنواع البيانات المتعلقة بالأعمال (data.frame، Date، factor) — سيجد المبتدئون أنclass()أكثر سهولة في الفهم- عائلة الدوال
is.*تتحقق من النوع (تُرجع TRUE/FALSE)، وعائلة الدوالas.*تُجري تحويلًا للنوع (تُرجع NA وتصدر تحذيرًا في حالة فشل التحويل) as.numeric()تتطابق مع كل من الأعداد الصحيحة والأعداد المزدوجة؛ وتميّز بينهما بشكل دقيق باستخدامas.integer()- للقيم الأربع الخاصة معانٍ مختلفة: NA (قيمة مفقودة — معدية)، NaN (ليس رقمًا)، Inf (اللانهاية)، وNULL (كائن فارغ — غير موجود)
- الطرق القياسية للتعامل مع القيم غير المتوفرة (NA):
sum(x, na.rm = TRUE)تخطي القيم غير المتوفرة؛!is.na(x)استبعاد القيم غير المتوفرة
📝 تمارين
-
تمرين أساسي: حدد 6 متغيرات تمثل أنواع البيانات الأساسية الستة (الرقمي، الصحيح، الحرفي، المنطقي، المركب، الخام). استخدم الأمر
typeof()للتحقق من نوع كل متغير، واحفظ لقطات شاشة لنتائج الأوامر الستةtypeof(). -
المشكلة الأساسية: استخدم
as.numeric()لتحويل المتجه الحرفيc("1", "2.5", "3.14", "abc", "5")إلى أرقام، وسجل رسائل التحذير ونتائج التحويل، واستخدمis.na()لتحديد العناصر التي أصبحت قيمتها NA. التقط لقطة شاشة لمخرجات وحدة التحكم واحفظها. -
تمرين أساسي: في وحدة التحكم في RStudio، احسب قيم
0/0و1/0و-1/0وsqrt(-1)، وسجل كل نتيجة، ثم استخدمis.na()وis.nan()وis.infinite()للتحقق من القيمة الخاصة التي تنتمي إليها كل قيمة. -
مشكلة متقدمة: عرّف متجهًا باسم
scores <- c(85, 92, NA, 78, NA, 95, 88). المتطلبات: ① احسب المجموع الكلي للدرجات (باستثناء القيم NA)؛ ② احسب متوسط الدرجات (باستثناء القيم NA، مع تقريب النتيجة إلى رقمين عشريين)؛ ③ استخدم!is.na()لتصفية العناصر التي ليست NA؛ ④ احسب عدد قيم NA. احفظ لقطة شاشة لنتائج كل خطوة. -
التحدي: اكتب برنامجًا نصيًّا بلغة R لمحاكاة «عدم تطابق الأنواع بعد قراءة ملف CSV»: ① قم يدويًّا بإنشاء إطار بيانات (data.frame) تكون جميع أعمدةه من النوع
character؛ ② استخدمas.numeric()لتحويل أحد الأعمدة دفعة واحدة إلى نوع رقمي؛ ③ استخدمsum(is.na(df$col))لحساب عدد العناصر التي فشل تحويلها؛ ④ استخدمpaste()لإنشاء رسالة تحذير وعرضها. بعد تشغيل البرنامج النصي، التقط لقطة شاشة واحفظ مخرجات وحدة التحكم بالكامل.