دمج إطارات البيانات في R: المطابقة الكاملة والجزئية
⚡ ملخص ذكي
تتيح عملية دمج إطارات البيانات في لغة R ربط جدولين بناءً على عمود مفتاح مشترك واحد أو أكثر. تغطي دالة merge() عمليات الربط الداخلي، والربط الأيسر، والربط الأيمن، والربط الكامل، ويوضح هذا الشرح كلاً من الربط الكامل والربط الجزئي.

في كثير من الأحيان، لدينا بيانات من مصادر متعددة. لإجراء التحليل، نحن بحاجة إلى دمج إطاري بيانات مع واحد أو أكثر المتغيرات الرئيسية المشتركة.
أنواع الدمج (الربط) في لغة R
قبل الخوض في الأمثلة، من المفيد معرفة أن الدالة merge() تُنفذ جميع أنواع الربط التي يتوقعها مستخدم SQL. ويتم التحكم في سلوكها من خلال الوسائط all و all.x و all.y، وليس من خلال اسم دالة مختلف.
| نوع الانضمام | صفوف محفوظة | استدعاء دالة الدمج () | مكافئ dplyr |
|---|---|---|---|
| الربط الداخلي (افتراضي) | المفاتيح الموجودة فقط في كلا الإطارين | merge(x, y, by = “k”) | inner_join(x, y, by = “k”) |
| ترك صلة خارجية | جميع صفوف x، NA حيث لا يوجد تطابق لـ y | merge(x, y, by = “k”, all.x = TRUE) | left_join(x, y, by = “k”) |
| الصلة الخارجية اليمنى | جميع صفوف y، NA حيث لا يوجد تطابق لـ x | merge(x, y, by = “k”, all.y = TRUE) | right_join(x, y, by = “k”) |
| صلة خارجية كاملة | كل صف من كلا الإطارين | merge(x, y, by = “k”, all = TRUE) | full_join(x, y, by = “k”) |
| تقاطع الانضمام | كل مجموعة من الصفوف | merge(x, y, by = NULL) | cross_join(x, y) |
هناك تفصيلان يجدر تذكرهما قبل المكالمة الأولى:
- يؤدي حذف كلمة "by" إلى دمج R على كل اسم عمود مشترك بين الإطارين، وهو أمر نادرًا ما يكون ما تريده.
- تقوم الدالة merge() بفرز النتيجة حسب عمود المفتاح؛ مرر sort = FALSE للحفاظ على الترتيب الوارد.
مباراة كاملة
تُعيد المطابقة الكاملة القيم التي لها نظير في جدول الوجهة فقط. أما الصفوف التي لا يوجد لها تطابق فتُحذف من إطار البيانات الجديد. في المقابل، تحتفظ المطابقة الجزئية بتلك الصفوف وتملأ الأعمدة المفقودة بقيم NA.
سوف نرى بسيطة الانضمام الداخلي. تحدد الكلمة الأساسية "الربط الداخلي" السجلات التي تحتوي على قيم متطابقة في كلا الجدولين. لضم مجموعتي بيانات، يمكننا استخدام وظيفة الدمج (). سنستخدم ثلاث حجج:
merge(x, y, by.x = x, by.y = y) Arguments: -x: The origin data frame -y: The data frame to merge -by.x: The column used for merging in x data frame. Column x to merge on -by.y: The column used for merging in y data frame. Column y to merge on
على سبيل المثال:
إنشاء مجموعة البيانات الأولى مع المتغيرات
- لقب
- الجنسية
إنشاء مجموعة البيانات الثانية مع المتغيرات
- لقب
- أفلام
المتغير الرئيسي المشترك هو اسم العائلة. يمكننا دمج كليهما إطارات البيانات وتأكد من أن الأبعاد هي 7×3.
نضيف stringsAsFactors=FALSE في إطار البيانات لأننا لا نريد R لتحويل السلاسل إلى عامليجب أن يبقى المتغير عبارة عن متجه نصي. منذ الإصدار 4.0.0 من R، أصبح هذا هو الوضع الافتراضي للدالة data.frame()، لذا فإن الوسيط اختياري في الكود الجديد وغير ضار في الكود القديم.
# Create origin dataframe( producers <- data.frame( surname = c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"), nationality = c("US","US","UK","US","Poland"), stringsAsFactors=FALSE) # Create destination dataframe movies <- data.frame( surname = c("Spielberg", "Scorsese", "Hitchcock", "Hitchcock", "Spielberg", "Tarantino", "Polanski"), title = c("Super 8", "Taxi Driver", "Psycho", "North by Northwest", "Catch Me If You Can", "Reservoir Dogs","Chinatown"), stringsAsFactors=FALSE) # Merge two datasets m1 <- merge(producers, movies, by.x = "surname") m1 dim(m1)
الإخراج:
surname nationality title 1 Hitchcock UK Psycho 2 Hitchcock UK North by Northwest 3 Polanski Poland Chinatown 4 Scorsese US Taxi Driver 5 Spielberg US Super 8 6 Spielberg US Catch Me If You Can 7 Tarantino US Reservoir Dogs
لنقم بدمج إطارات البيانات عندما يكون للمتغيرات الرئيسية المشتركة أسماء مختلفة.
نقوم بتغيير اللقب إلى الاسم في إطار بيانات الأفلام. نستخدم الدالة المتطابقة (x1, x2) للتحقق مما إذا كان كلا إطاري البيانات متطابقين.
# Change name of ` movies ` dataframe colnames(movies)[colnames(movies) == 'surname'] <- 'name' # Merge with different key value m2 <- merge(producers, movies, by.x = "surname", by.y = "name") # Print head of the data head(m2)
الإخراج:
##surname nationality title ## 1 Hitchcock UK Psycho ## 2 Hitchcock UK North by Northwest ## 3 Polanski Poland Chinatown ## 4 Scorsese US Taxi Driver ## 5 Spielberg US Super 8 ## 6 Spielberg US Catch Me If You Can
# Check if data are identical
identical(m1, m2)
الإخراج:
## [1] TRUE
يوضح هذا أن عملية الدمج يتم تنفيذها حتى لو كانت أسماء الأعمدة مختلفة.
مباراة جزئية
أدى الربط الداخلي المذكور أعلاه إلى حذف أي بيانات لا يوجد لها نظير. ليس من المستغرب ألا تحتوي مجموعتا البيانات على نفس متغيرات المفتاح المشترك. مطابقة كاملة، يعود إطار البيانات فقط الصفوف الموجودة في إطار البيانات x و y. مع دمج جزئي، فمن الممكن الاحتفاظ بالصفوف التي لا تحتوي على صفوف متطابقة في إطار البيانات الآخر. ستحتوي هذه الصفوف على NA في تلك الأعمدة التي عادةً ما تكون مملوءة بقيم من y. يمكننا القيام بذلك عن طريق تعيين all.x= TRUE.
على سبيل المثال، يمكننا إضافة منتج جديد، لوكاس، إلى إطار بيانات المنتجين دون الحاجة إلى مراجع الأفلام الموجودة في إطار بيانات الأفلام. إذا قمنا بتعيين all.x= FALSE، فسيقوم R بدمج القيم المتطابقة فقط في مجموعتي البيانات. في حالتنا، لن يتم دمج المنتج لوكاس في النتيجة، لأنه غير موجود في إحدى مجموعتي البيانات.
دعونا نرى أبعاد كل مخرج عندما نحدد all.x= TRUE ومتى لا نفعل ذلك.
# Create a new producer add_producer <- c('Lucas', 'US') # Append it to the ` producer` dataframe producers <- rbind(producers, add_producer) # Use a partial merge m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE) m3
الإخراج:
يُظهر خرج وحدة التحكم أدناه صف لوكاس الإضافي، مع استبدال NA بعنوان الفيلم المفقود.
# Compare the dimension of each data frame
dim(m1)
الإخراج:
## [1] 7 3
dim(m2)
الإخراج:
## [1] 7 3
dim(m3)
الإخراج:
## [1] 8 3
كما نرى، فإن إطار البيانات الجديد هو 8×3، مقارنةً بـ 7×3 لـ m1 و m2. يقوم برنامج R بملء عمود العنوان بـ NA لـ Lucas، المنتج الذي لا يوجد له صف مطابق في إطار بيانات الأفلام.
دمج الدوال مقابل دمج الدوال باستخدام dplyr في لغة R
تقوم لغة R الأساسية بحل كل عملية ربط باستخدام دالة واحدة ومجموعة من العلامات. com.dplyr بدلاً من ذلك، تمنح الحزمة كل عملية ربط فعلها الخاص، وهو ما تجده العديد من الفرق أسهل في القراءة في خط الأنابيب.
| المعايير | دمج القاعدة() | ينضم dplyr |
|---|---|---|
| اختيار نقطة الالتقاء | جميع العلامات x / جميع العلامات y / جميع العلامات | تم تسميتها في الفعل: left_join()، full_join() |
| ترتيب الصفوف | يتم الترتيب حسب المفتاح إلا إذا كانت قيمة sort تساوي FALSE | يتم الحفاظ على ترتيب الطاولة اليسرى |
| سرعة الإطارات الكبيرة | أبطأ | عموما أسرع |
| عمود المفتاح مفقود | يفشل في وقت متأخر أو يدمج البيانات في الأعمدة الخاطئة | الأخطاء فوراً |
| تبعيات | قاعدة R، لا حاجة للتثبيت | يتطلب حزمة dplyr |
يترجم دمج الكلمتين الموضحتين أعلاه مباشرة إلى أفعال dplyr:
library(dplyr) # Same inner join as merge(producers, movies, by.x = "surname", by.y = "name") m4 <- inner_join(producers, movies, by = c("surname" = "name")) # Same partial merge as all.x = TRUE m5 <- left_join(producers, movies, by = c("surname" = "name"))
يُعدّ دمج الملفات الأساسية (Base merge()) الخيار الأكثر أمانًا داخل حزمة لا ينبغي أن تحتوي على أي تبعيات. أما dplyr فهو الخيار الأفضل في التحليل التفاعلي، حيث تُعدّ سهولة القراءة والسرعة أكثر أهمية.
أخطاء الدمج الشائعة في لغة R وكيفية إصلاحها
معظم مشاكل الدمج تظهر على شكل عدد صفوف غير متوقع بدلاً من رسالة خطأ، لذا فإن التحقق من dim() بعد كل عملية دمج هو عادة تستحق البناء.
- تحتوي النتيجة على صفوف أكثر من أي من المدخلات. يؤدي تكرار المفتاح في كلا الإطارين إلى إنشاء عملية ربط متعددة الأطراف، ويعيد R جميع التوليفات الممكنة. افحص المفاتيح باستخدام الأمر table(duplicated(x$k)) قبل الدمج.
- النتيجة فارغة. تختلف أعمدة المفاتيح عادةً في نوعها، أو قد يحتوي أحدها على مسافات زائدة. قم بتشغيل الدالة str() على كلا الإطارين، ثم نظّف المفتاح باستخدام الدالة trimws() قبل الدمج.
- تعود الأعمدة على شكل title.x و title.y. يحتوي كلا الإطارين على عمود غير رئيسي يحمل نفس الاسم. مرر اللواحق = c(“_producer”, “_film”) لجعل المصدر واضحًا.
- لم تعد الصفوف مرتبة بترتيبها الأصلي. تقوم الدالة merge() بالفرز بناءً على المفتاح افتراضيًا. أضف sort = FALSE، أو استخدم فرز صريح بعد ذلك.
- فشل أحد المقارنات الرئيسية في بعض العوامل. قارن الأحرف، وليس مستويات العوامل: قم بتغليف المفتاح في as.character() قبل دمج الإطارات التي تم إنشاؤها في ظل الإعدادات الافتراضية القديمة لـ R.
عندما يتعين تشغيل عملية الدمج نفسها بشكل متكرر، قم بتضمينها في وظيفة محددة من قبل المستخدم لذا لا يمكن أن تتغير الوسائط بين عمليات التشغيل.

