إضافة عمود: df$new <- value
لإضافة عمود في base R، أسنِد قيمة إلى اسم غير موجود بعد. وغالبًا ما تُحسب القيمة من أعمدة موجودة فعلًا:
حدث أمران. حصل orders$total على متجه كامل، إذ تُحسب price * qty لكل الصفوف دفعة واحدة لأن العمليات الحسابية في R متجهية. أما orders$currency فحصل على قيمة مفردة كرّرها R على الصفوف الأربعة جميعها. وأي طول آخر يُعد خطأ (replacement has 3 rows, data has 4)، وهي حماية يوفرها R لك من عمود غير محاذٍ.
ينجح هذا لأن data frame هو قائمة من الأعمدة المتساوية الطول، وإسناد عنصر مسمّى جديد يوسّع القائمة. ويشرح مستند أطر البيانات هذا النموذج بالتفصيل.
الأعمدة الشرطية: ifelse()
العمود الذي تعتمد قيمته على شرط يحتاج إلى ifelse()، وهي النظيرة المتجهية لـ if. تأخذ متجهًا كاملًا من الشروط وتُرجع قيمة لكل صف:
ولماذا لا نستخدم if العادية؟ لأن if تُقيّم قيمة TRUE/FALSE واحدة تمامًا، وإذا مُرِّر إليها عمود كامل أطلقت خطأ (the condition has length > 1). أما ifelse(test, yes, no) فتفحص كل عنصر وتختار لكل صف. ولثلاث نتائج أو أكثر يمكنك المداخلة:
المداخلة على مستويين مقبولة، أما ثلاثة أو أكثر فتتحول إلى هرم، وهذا بالضبط ما بُنيت case_when() من dplyr (أدناه) من أجله. وتغطي وثيقة if-else صيغة if/else ذات القيمة المفردة.
عدة أعمدة دفعة واحدة: transform()
تضيف transform() في base R عدة أعمدة في استدعاء واحد، مع أسماء أعمدة مجردة:
لاحظ أن transform() تُرجع data frame جديدًا، فعليك إسناد النتيجة مجددًا، بينما تعدّل df$new <- ... في المكان. وثمة قيد واحد: لا يمكن للتعابير داخل استدعاء transform() واحد أن يرى بعضها بعضًا، لذا تفشل discount = ifelse(total > 50, ...) هناك (لأن total غير موجود بعد). نفّذ ذلك على خطوتين، أو استخدم mutate() التي تسمح به.
التعديل مقابل الإنشاء
تكتب صيغة الإسناد نفسها فوق عمود موجود، والفارق الوحيد هو ما إذا كان العمود موجودًا من قبل:
يستحق هذا وقفة: لا يعطيك R أي تحذير حين تكتب فوق عمود. فخطأ إملائي مثل df$prise <- round(df$price, 2) ينشئ بصمت عمودًا جديدًا بدل إصلاح القديم. وبعد أي تحويل، استخدم print() أو str() على الإطار وتأكد أنك غيّرت ما قصدته.
حذف عمود
أسنِد NULL للحذف:
اختفى العمود دون أي تعقيد. ولحذف عدة أعمدة، تكون df[, c("a", "b")] (أي الاحتفاظ بما تذكره) أوضح عادةً من تكرار NULL.
أسلوب dplyr: mutate()
فعل dplyr المكافئ لكل ما سبق هو mutate(). المقتطفات أدناه ثابتة لأن البيئة التجريبية تشغّل base R فقط، لكن هكذا تبدو العمليات نفسها:
library(dplyr)
orders |>
mutate(
total = price * qty,
big = total > 50 # can use total, defined one line up
)
ميزتان على base R. أولًا، الأعمدة المعرَّفة داخل mutate() نفسها يمكنها الإشارة إلى بعضها بالترتيب، وهو ما ترفضه transform(). ثانيًا، المساعدات الشرطية أفضل من ifelse() المتداخلة:
students |>
mutate(
grade = if_else(score >= 60, "pass", "fail"),
band = case_when(
score >= 85 ~ "high",
score >= 60 ~ "mid",
.default = "low"
)
)
الدالة if_else() هي نسخة أكثر صرامة من ifelse() (إذ يجب أن يكون الفرعان من النوع نفسه، ما يكشف أخطاءً حقيقية). أما case_when() فتُقرأ كقائمة مسطحة من أزواج condition ~ value تُفحص من الأعلى إلى الأسفل، مع .default كخيار احتياطي، وهي البديل الواضح لهرم ifelse(). وكسائر أفعال dplyr، تُرجع mutate() data frame جديدًا. راجع مقدمة dplyr لمعرفة كيفية تسلسلها مع بقية الأفعال.
الخلاصة
- تضيف
df$new <- expressionعمودًا، ويُنفَّذ التعبير على كل الصفوف دفعة واحدة. - تبني
ifelse(test, yes, no)الأعمدة الشرطية، وهو ما لا تستطيعهifالعادية. - تضيف
transform()عدة أعمدة في الاستدعاء الواحد لكنها لا يرى بعضها بعضًا، بينما تستطيعmutate()ذلك. - الإسناد نفسه يكتب فوق العمود بصمت، فتحقق من الإملاء بعد كل تحويل.
- تحذف
df$col <- NULLعمودًا، وتحلcase_when()محل أهرامifelse()المتداخلة.
في المستند التالي: إعادة تسمية الأعمدة عبر names()، والصيغة المتينة في base، وrename() في dplyr.
الأسئلة الشائعة
كيف أضيف عمودًا جديدًا إلى data frame في R؟
أسنِد قيمة إلى اسم عمود غير موجود بعد: df$total <- df$price * df$qty. ينشئ R العمود فورًا. ويمكن أن تكون القيمة قيمة مفردة (تُكرَّر على كل الصفوف) أو متجهًا محسوبًا من أعمدة أخرى، ما دام طوله مطابقًا لعدد الصفوف.
كيف أنشئ عمودًا شرطيًا في R؟
استخدم الدالة المتجهية ifelse(): تفحص df$grade <- ifelse(df$score >= 60, "pass", "fail") كل الصفوف دفعة واحدة. ولا تستخدم if العادية، فهي تتعامل مع شرط مفرد لا مع عمود كامل. ولأكثر من نتيجتين، داخِل استدعاءات ifelse() أو استخدم case_when() من dplyr.
ماذا تفعل mutate() في R؟
mutate() هي فعل dplyr لإضافة الأعمدة أو تحويلها: تُرجع df |> mutate(total = price * qty) نسخة من data frame تحتوي على العمود الجديد. ويمكنها تعريف عدة أعمدة في استدعاء واحد، كما يمكن للأعمدة اللاحقة استخدام الأعمدة السابقة المعرَّفة داخل الاستدعاء نفسه.
كيف أحذف عمودًا من data frame في R؟
أسنِد إليه القيمة NULL: تزيل df$notes <- NULL العمود في مكانه. وفي dplyr، تُرجع select(-notes) نسخة خالية منه.