تحرير أطر البيانات - بعض العمليات المتقدمة ، المقال الثالث و الأخير
يتناول هذا المقال بعض التقنيات الضرورية المستعملة في تحرير أطر البيانات بغرض الحصول على معلومات و استخراج نتائج تحليلية بخصوص معطياتها. هاته العمليات كثيرا ما يحتاجها المحلل لفهم الظواهر المدروسة. يتناول المقال هنا كيفية استخراج بيانات جديدة من أخرى موجودة ، سواءا على البيانات العددية ، سلاسل الحروف أو البيانات المنطقية ؛ ترتيب و إعادة ترتيب البيانات ؛ استخراج أطر بيانات تجميعية و تلخيصية للأطر الأصلية بغرض فهم ظواهر و تحديد اتجاهات تحليلية و في الأخير ، كيفية تحويل أطر البيانات إلى أشكال بيانات أخرى مثل القوائم أو المصفوفات.
1. استخراج بيانات جديدة من بيانات موجودة
من أهم العمليات التي قد يحتاج إليها أي محلل للبيانات هي إنشاؤه لبيانات جديدة انطلاقا من بيانات موجودة على إطار البيانات أو على أطر بيانات أخرى. سنتناول في هذا المحور إنشاء بيانات عددية جديدة و كذلك بيانات نصية انطلاقا من البيانات الموجودة لدينا. سنتناول إمكانية حساب بيانات جديدة من خلال مثال على بيانات الإطار المعرف في المقالات السابقة و هو إطار البيانات : update3_my_df
.
حساب بيانات رقمية من أخرى موجودة
سنعمل هنا على مهمة استخراج درجة أقدمية كل عضو و نصنفها بالسنوات. نتعامل هنا كبداية بشكل مبسط مع مفهوم الزمن في آر و الذي سنعود إليه بتفصيل و دقة أكبر مستقبلا. سنعمل أولا على استخراج السنة الحالية (بغض النظر عن السنة التي تقرأون فيها هاته السطور. بالنسبة لي ، فأنا أكتب هاته السطور في أفريل 2025) ثم نطرح منها سنة الانتساب.
لاستخراج السنة الحالية، نستعمل مكتبة تعالج البيانات الزمنية مثل lubridate و ذلك بكتابة الصيغة :
install.packages("lubridate")
library(lubridate)
نستعمل من هذه المكتبة أمرين و هما today()
و year()
حيث تظهر الأولى سلسلة حروف تشير إلى تاريخ اليوم حسب الشكل التالي : “yyyy-mm-dd”. أنظر المثال التالي :
today()
#[1] "2025-04-05"
الأمر الثاني ، year()
، يعطي السنة انطلاقا من وسيطة على شكل سلسلة حروف تشير إلى التاريخ المراد استخراج سنته. مثلا :
year("2025-04-05")
#[1] 2025
لتحديد السنة إذا انطلاقا من أمر today()
، ندمج الأمرين كما يلي :
year(today())
#[1] 2025
نعمل الآن على استخراج درجة أقدمية الأعضاء بالسنوات بطرح سنة الانتساب من السنة الحاضرة و ذلك محسوبا في متغير جديد نسميه أقدمية
:
أقدمية <-
year(today())-update3_my_df$انتساب
ملاحظة :
يمكن استعمال صيغة أخرى تكون مفيدة في عمليات أكثر تعقيدا لعدم الاضطرار لكتابة إطار البيانات عدة مرات و هي عبارة with(dataframe, ...)
تكون العبارة كما يلي :
أقدمية <- with(update3_my_df, year(today())-انتساب)
لاحظ هنا أنني لم أضطر إلى كتابة متغير الانتساب بالشكل الأول update3_my_df$انتساب
و إنما فقط بشكله المباشر انتساب
.
بعد ذلك نضيف متغير الأقدمية إلى إطار البيانات update3_my_df
:
update3_my_df <- cbind(update3_my_df,أقدمية)
update3_my_df
إنشاء بيانات نصية جديدة من بيانات موجودة
سنعمل الآن على كتابة لوحة تعريفية خاصة بكل عضو بالجمعية. كلمات هذه اللوحة التعريفية نخزنها في متغير اسمه تعريف. ستضم كلمات هاته اللوحة العناصر التالية :
للأعضاء الذكور :
… (الاسم) عضو في جمعية الصداقة ، منخرط منذ سنة …(سنة الانتساب) ، يبلغ من العمر …(العمر) و يقيم في مدينة …(المدينة). …(الاسم) يعمل في ميدان … (المهنة) كما يهتم بهواية … (الهواية).
للأعضاء الإناث :
… (الاسم) عضو في جمعية الصداقة منخرطة منذ سنة …(سنة الانتساب) ، تبلغ من العمر …(العمر) و تقيم في مدينة …(المدينة). …(الاسم) تعمل في ميدان … (المهنة) كما تهتم بهواية … (الهواية).
نستعمل هنا الأمر paste()
من أجل تجميع concatenation سلاسل الحروف. تتكون وسائط هذا الأمر من مجموع سلاسل الحروف المراد تجميعها ، سواء تدرج مباشرة أو عبر متغيرات أدرجت فيها من قبل حسب الصيغة : paste("string1","string2","string3",...)
.
لتسهيل العملية، سنخزن صيغتي التعريف في متغيرين ، الأول خاص بالصيغة المؤنثة fem
و الثاني خاص بالصيغة المذكرة masc
حسب ما يلي. نستعمل كما رأينا أعلاه الأمر with()
من أجل عدم الاضطرار لإعادة كتابة إطار البيانات في كل مرة أضع فيها متغيرا من متغيراته.
صيغة المؤنث
#صيغة المؤنث
fem <- with(update3_my_df, paste(
الاسم,
" عضو في جمعية الصداقة ، منخرطة منذ سنة ",
انتساب,
" ، تبلغ من العمر ",
العمر ,
" و تقيم في مدينة ",
المدينة ,
". ",
الاسم,
" تعمل في ميدان ",
المهنة,
" كما تهتم بهواية ",
هواية,
"."
)
)
صيغة المذكر
masc <- with(update3_my_df,paste(
الاسم,
" عضو في جمعية الصداقة ، منخرط منذ سنة ",
انتساب,
" ، يبلغ من العمر ",
العمر ,
" و يقيم في مدينة ",
المدينة ,
". ",
الاسم,
" يعمل في ميدان ",
المهنة,
" كما يهتم بهواية ",
هواية,
"."
)
)
بالنظر لوجود صيغتين للنص و من أجل التفريق بين العبارة المؤنثة و المذكرة نسعتمل صيغة شرطية بسيطة عبر الأمر ifelse()
تكتب الصيغة وفق ثلاثة وسائط ، في الأولى ، يحدد الشرط و في الثانية تحدد النتيجة إن كان الشرط صحيحا ، ثم في الثالثة ، توضع النتيجة حال كان الشرط غير محقق. سكتب الأمر بالشكل التالي : ifelse(condition, TRUE, FALSE)
بالنسبة لإطار بياناتنا update3_my_df
، سنستعمل المعلومة الخاصة بجنس الأفراد انطلاقا من المتغير update3_my_df$الجنس
. حيث نبحث عن تحقيق الشرط الجنس == "F"
. في حال تحقق ، نستعمل متغير fem
؛ أما في حال عدم التحقق ، نستعمل متغير masc
.
يكون تعريف إذن متغيرنا تعريف
بالصيغة التالية :
update3_my_df$تعريف <- ifelse(update3_my_df$الجنس=="F",fem, masc)
خلاصة
- لحذف عمود: استخدم
dataframe[,-n]
حيثn
هو رقم العمود. - لحذف صف: استخدم
dataframe[-n,]
حيثn
هو رقم الصف. - لحذف قيمة فردية: قم بتحديد موقعها داخل إطار البيانات واستبدالها بـ
NA
.
بهذه الطرق، يمكنك إدارة البيانات بسهولة والتحكم في مكوناتها عند الحاجة.
2. ترتيب البيانات
عند التعامل مع أطر البيانات في آر، هناك العديد من العمليات التي يمكن إجراؤها لتعديلها وتحليلها.
يمكن أن يحتاج المحلل إلى إعادة ترتيب البيانات على آر حسب أحد المتغيرات الرقمية أو الترتيبية الممكنة. لهذا الغرض ، يمكن إعادة ترتيب الإطار عبر تحديد المتغير المعني باستعمال الأمر الذي رأينا سابقا و هو order()
و ذلك عبر الصيغة : ordered_df <- df[order(df$variable), ]
. يمكن تحديد خصائص إضافية ، خاصة شكل الترتيب بإضافتها إلى أمر الترتيب مثل : ordered_df <- df[order(df$variable, decreasing = T), ]
.
مثلا ، سنعمل على استخراج أقدم عنصر في جمعيتنا انطلاقا من إطار البيانات update3_my_df
ثم نطبع اسم أقدم عضو.
ordered_df <- update3_my_df[order(update3_my_df$أقدمية, decreasing = T), ]
print(ordered_df[1,])
#1 أحمد 25 الجزائر التعليم قراءة 2010 15
print(ordered_df$الاسم[1])
#[1] "أحمد"
يمكن مباشرة طبع الاسم و التعريف باعتماد الترتيب ، مثلا :
with(update3_my_df, print(c(الاسم[1], تعريف[1])))
#[1] "أحمد"
#[2] "أحمد عضو في جمعية الصداقة ، منخرط منذ سنة 2010 ، يبلغ من العمر 25 و يقيم في مدينة الجزائر . أحمد يعمل في ميدان التعليم كما يهتم بهواية قراءة ."
في حال نريد التعمق أكثر ، يمكن كتابة وظيفة كاملة ، انطلاقا منها ، ندخل الاسم من أجل الحصول على البطاقة التعريفية و لكن هذا يستلزم دراسة أوامر أخرى و هي function()
للوظائف الجديدة ، which
لتحديد ترتيب القيمة ضمن المتغير و الشرطية if()
و else()
.
على الرغم من أنه قد يبدو صعبا ، يمكنك التمعن في الوظيفة المقترحة. سنعود لهذا الموضوع بشكل أكثر عمقا :
welcome <- function(الاسم){#تعريف الدالة
i = which(update3_my_df$الاسم == الاسم)#تحديد رتبة الاسم المراد عبر الأمر which()
if(length(i)>0) {#الصيغة الشرطية
print(update3_my_df$تعريف[i])}# المنتظر حال تحقق الشرط
else {
print("هذا الاسم غير موجود بالجمعية")}#المنتظر حال لم يتحقق الشرط
}
هنا بعض النتائج :
welcome("فاطمة")
# "فاطمة عضو في جمعية الصداقة ، منخرطة منذ سنة 2012 ، تبلغ من العمر 30 و تقيم في مدينة تونس . فاطمة تعمل في ميدان الطب كما تهتم بهواية تصوير ."
welcome("أحمد")
#[1] "أحمد عضو في جمعية الصداقة ، منخرط منذ سنة 2010 ، يبلغ من العمر 25 و يقيم في مدينة الجزائر . أحمد يعمل في ميدان التعليم كما يهتم بهواية قراءة ."
welcome ("كريم")
#[1] "هذا الاسم غير موجود بالجمعية"
بهذا نكون قد بينا بعض الأمثلة لبناء متغيرات جديدة انطلاقا من متغيرات موجودة ضمن إطار البيانات ، سواء بالحساب بالنسبة للمتغيرات الكمية أو بدمج سلاسل الحروف بالنسبة للمتغيرات الحروفية.
3. تجميع البيانات و استخراج أطر بيانات تركيبية و جداول تجميعية للبيانات
لضرورة التحليل الإحصائي ، كثيرا ما يحتاج الباحث إلى تقنية تلخيص الجداول و تجميع البيانات بغرض تحديد اتجاهات إحصائية في التحليل تعين على ظهور نتائج. لهذا الغرض ، سنتطرق هنا إلى خاصية مهمة متعلقة بتجميع الجداول و إنشاء جداول تركيبية على أطر البيانات في أر تعطي نتائج و اتجاهات معينة للتحليل الإحصائي. نستعمل هنا الأمر aggregate()
.
وظيفة التجميع-aggregate تسمح بتلخيص بيانات معينة بناءا على متغيرات محددة. أهميتها تكون كبيرة في البيانات الكبيرة حيث تسمح بحساب قيم مثل المجموع ، المعدل ، القيمة المتوسطة أو العدد أو غيرها لمجموعات فرعية من البيانات يتم تحديدها. عندما نريد تجميع بيانات المتغير variable1
وفق مجموعات فرعية محددة بالمتغير variable2
ووفق طريقة الحساب operation
، تكتب صيغة التجمبع بتعريف متغير جديد للجدول الملخص كما يلي : aggregated_table <- aggregate(dataframe$variable1, by = list(variable2), FUN = "operation")
في مثالنا update3_my_df
، سنبحث عن سؤالين :
- مقارنة متغير السن بين الذكور و الإناث ،
- تحديد نسبة الأقدمية في الجمعية.
معرفة متوسط العمر بحسب جنس الأعضاء :
للإجابة على السؤال الأول ، نسمي متغيرا للجدول المقصود بالاسم avg_age
بحيث نعالج متغير العمر
و نقارنه بالمتغير المعاملي الجنس
. نبين العملية المقصودة و هي حساب المعدل "mean"
. الكتابة تكون كما يلي. نعرض الجدول عند النهاية.
avg_age<-with(update3_my_df, aggregate(العمر, by = list(الجنس), FUN = mean))
avg_age
نلاحظ أن الجدول فقد عناوينه و لذا ، نضيف له عناوين جديدة باستعمال الأمر colnames()
colnames(avg_age)<-c("الجنس","متوسط_عمر")
نلاحظ أن متوسط عمر الإناث أكبر من عمر الذكور في جمعيتنا ، مع التحفظ على العدد القليل جدا من المشاهدات.
في الدروس المقبل ، سنتعامل مع بيانات أكبر.
تحديد أقدمية الأعضاء :
في هذا المثال سنحتاج إلى معالجة أكبر قليلا للبيانات المتاحة بحيث نرتب أقدمية الأعضاء ، المخزنة في المتغير أقدمية
إلى أربعة (04) مراتب : “الرواد” و أقدميتهم أكثر من 15 سنة ، “الثابتون” ، من 10 إلى 15 سنة ، ”المتدرجون” ، من 05 إلى 10 سنوات و “الآتون الجدد” ، من 0 إلى 5 سنوات.
يجب إذًا اقتراح متغير ترتيبي جديد نسميهrank1
يعبر عن الأصناف الأربعة أعلاه بدل المتغير العددي أقدمية
. أول مرحلة هي إنشاء المتغير و استعمال صيغة شرطية رأيناها أعلاه ifelse(condition, TRUE, FALSE)
تعتمد على حصر سنوات الأقديم كما يلي :
update3_my_df$rank1 <- with(update3_my_df,ifelse(old>=15,"pionner",
ifelse(old>=10,"confirmed",
ifelse(old>=5,"initiate",
ifelse(5>old,"new-comer",
NA)))))
ثم نحول المتغير الناتج rank1
إلى متغير ترتيبي باستعمال الأمر factor()
مع تحديد ترتيب للمستويات levels
من الأول (الأقدم) إلى الأخير. يدرج ترتيب المستويات في وسيطة levels
ضمن الأمر factor()
وفق الصيغة التالية :
variable <- factor(variable, levels = c("level1","level2","level3",...))
في المثال المناقش ، نعرف المتغير rank1
كما يلي :
update3_my_df$rank1 <- factor(update3_my_df$rank1, levels = c("pionner", "confirmed", "initiate", "new-comer"))
يبقى الآن إنشاء الجدول التلخيصي old_agg
باعتماد عد مشاهدات أي متغير و مقارنة العدد بدرجة الأقدمية rank1
. وظيفة العد تحدد بأمر FUN = length
. بما أن الوظيفة هي وظيفة عد و ليست وظيفة أخرى ، فإن المتغير المعني غير مهم. أس متغير سيعد بنفس الدرجة في الجدول.
الصيغة تكون كالآتي :
old_agg<-with(update3_my_df,aggregate(rank1,by = list(rank1),FUN = "length"))
old_agg
بنفس طريقة العملية الأولى أعلاه ، نعيد تسمية متغيرات old_agg
باستعمال وظيفة colnames()
:
colnames(old_agg) <-c("أقدمية", "عدد_منتسبين")
old_agg
نلاحظ هنا أن أكبر نسبة من الأعضاء هي نسبة ”المثبتين - confirmed “ على الرغم من صغر الجدول المدروس.
خاتمة
تناول هذا المقال أطر البيانات في أر وكيفية إنشائها أو التعامل معها. كل هيكل بيانات له استخداماته الخاصة التي تجعله مناسبًا لأنواع معينة من التحليل. يمكن تجربة هذه الأمثلة مباشرة على آر أو في RStudio لاكتساب فهم أعمق.