Menu
flag Ar iconالعربيةdown icon

السلاسل النصية في R: ‏paste وsprintf وgsub وsubstr وغيرها

كل ما تحتاجه للنصوص في R: إنشاء السلاسل، والدمج بـ paste وpaste0، والتنسيق بـ sprintf، والبحث بـ gsub وgrepl وstrsplit.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

إنشاء السلاسل النصية في R

السلسلة النصية في R نص بين علامتي اقتباس. وتعمل علامتا الاقتباس المزدوجة والمفردة معًا وتعنيان الشيء نفسه تمامًا؛ والعرف هو الاقتباس المزدوج، مع الانتقال إلى المفرد حين يحتوي النص نفسه على علامة اقتباس مزدوجة:

وتعمل رموز الهروب بالشرطة المائلة العكسية كما في معظم اللغات: \" لعلامة اقتباس حرفية، و\n لسطر جديد، و\t لمسافة جدولة، و\\ للشرطة المائلة العكسية نفسها.

والآن الخطأ الذي يرتكبه كل مبتدئ في R مرة واحدة بالضبط: سؤال سلسلة نصية عن طولها باستخدام length().

تعد nchar() المحارف - أي 5. وتعد length() عناصر المتجه، والسلسلة الواحدة متجه من عنصر واحد - فتعطي 1. ففي R كل شيء متجه، بما في ذلك النص، وكل الدوال في هذه الصفحة تعمل بهدوء عنصرًا عنصرًا عبر متجهات نصية كاملة. وهذه ميزة، حالما تكف عن التفاجؤ بها.

دمج السلاسل: ‏paste() وpaste0()

ليس في R معامل + للنصوص. فالدمج يتم بـ paste() التي تصل وسائطها بمسافة افتراضيًا، وبـ paste0() التي تصلها دون فاصل:

ولأن paste متجهية، فإن تمرير متجه إليها يبني سلاسل كثيرة دفعة واحدة - وهكذا تولّد أسماء الملفات والعناوين والمعرفات في سطر واحد:

ويؤدي الوسيط collapse العكس: فهو يصهر متجهًا كاملًا في سلسلة واحدة بفاصل تختاره:

تذكر الفصل بينهما: يتحكم sep في الصمغ الواصل بين الوسائط، ويتحكم collapse في الصمغ الواصل بين عناصر متجه واحد. ويمكنك استخدامهما معًا في استدعاء واحد.

التنسيق باستخدام sprintf()

حين تحتاج إلى أرقام منسّقة داخل نص - منازل عشرية ثابتة، أو عرض محشو - تنفد طاقة paste() وتتولى sprintf() المهمة. وهي تستخدم رموز تنسيق بأسلوب C: ‏%s للسلاسل، و%d للأعداد الصحيحة، و%f للأعداد العشرية:

يعني %.1f "منزلة عشرية واحدة"، ويعني %.3f ثلاث منازل، ويحشو %05d القيمة إلى خمسة أرقام بالأصفار. والرمز %% المضاعف ينتج علامة نسبة مئوية حرفية. كما أن sprintf() متجهية، فتستطيع تنسيق عمود كامل من القيم في استدعاء واحد - راجع الإدخال والإخراج لنمط إعداد التقارير بـ sprintf() مع cat().

تغيير حالة الأحرف والاقتطاع: ‏toupper() وtolower() وsubstr()

تحويل حالة الأحرف يفعل تمامًا ما يقوله اسمه:

وتثبت tolower() جدارتها في توحيد البيانات الفوضوية قبل المقارنة - فتصبح "Yes" و"YES" و"yes" القيمة نفسها.

وتستخرج substr(x, start, stop) مقطعًا وفق موضع المحارف، بدءًا من 1 (فـ R تبدأ الفهرسة من 1 في كل مكان):

وكلا الطرفين مشمول: فالمواضع من 1 إلى 11 تعطي "Programming".

البحث والاستبدال: ‏sub() وgsub() وgrepl()

تستبدل sub() الظهور الأول للنمط؛ وتستبدل gsub() ‏("global substitute") كل الظهورات:

وثمة تفصيل حاسم: النمط تعبير نمطي افتراضيًا، لا نص حرفي. فمحارف التعبيرات النمطية مثل . و* و( و? لها معانٍ خاصة - فالنقطة . المجردة تطابق أي محرف. وحين تقصد النص الحرفي، مرر fixed = TRUE:

يعطي السطر الأول a-b-c؛ ويعطي الثاني -----، لأن النقطة . بوصفها تعبيرًا نمطيًا طابقت كل محرف على حدة. وإلى أن تتعلم التعبيرات النمطية، اجعل fixed = TRUE خيارك الافتراضي ولن تُلدغ أبدًا.

أما grepl() فلا تستبدل - بل تختبر ما إذا كان كل عنصر يطابق، وتعيد متجهًا منطقيًا. وهذا ما يجعلها الأداة القياسية لترشيح النصوص:

تحدد النتيجة الأولى أي أسماء الملفات تحتوي على .csv؛ وتستخدم الثانية ذلك المتجه المنطقي للإبقاء على المطابقات فقط.

التقسيم والتشذيب: ‏strsplit() وtrimws()

تقطّع strsplit() سلسلة نصية عند فاصل. ولها خصوصية واحدة: فهي تعيد قائمة، لأنها قادرة على تقسيم عدة سلاسل دفعة واحدة. وللسلسلة الواحدة، خذ العنصر الأول بالصيغة [[1]]:

وتزيل trimws() المسافات البيضاء التي تصل البيانات الواقعية مغلفة بها دائمًا:

وهي تشذّب الطرفين افتراضيًا؛ بينما يشذّب which = "left" أو "right" طرفًا واحدًا فقط (والتسميتان تشيران إلى بداية السلسلة ونهايتها).

البديل: حزمة stringr

كل ما سبق من R الأساسية - متاح دائمًا ودون تثبيت. وتغلّف حزمة stringr من منظومة tidyverse العمليات نفسها في نظام تسمية متسق بالبادئة str_* مع وضع السلسلة النصية دائمًا في الوسيط الأول، وهو ما يجده كثيرون أسهل للتذكر (راجع الحزم لتثبيتها):

library(stringr)

str_detect(files, "csv")            # like grepl(), data first
str_replace_all(s, "good", "great") # like gsub(), arguments reordered
str_length("hello")                 # like nchar()

ودوال السلاسل في R الأساسية تستحق المعرفة في كل الأحوال - فستصادفها في كل نص برمجي وكل إجابة على Stack Overflow وكل رسالة خطأ كُتبت يومًا. تعلم الأسماء الأساسية أولًا؛ وتبنَّ stringr حين يبدأ ترتيب الوسائط غير المتسق في إزعاجك.

ما تخرج به

  • تستخدم السلاسل النصية علامات الاقتباس المزدوجة عرفًا؛ وتعد nchar() المحارف، بينما تعد length() عناصر المتجه.
  • ادمج بـ paste() أو paste0()؛ ويصل sep بين الوسائط، ويصهر collapse المتجه في سلسلة واحدة.
  • تتولى sprintf() المخرجات المنسّقة: ‏%s و%d و%.2f.
  • تستبدل sub() المطابقة الأولى، وgsub() كل المطابقات، وتختبر grepl() وجود المطابقات - وجميعها تعبيرات نمطية افتراضيًا، فمرر fixed = TRUE للنص الحرفي.
  • تعيد strsplit() قائمة (خذ منها [[1]])؛ وتنظّف trimws() المدخلات المحشوة بالمسافات.

التالي: إدخال النصوص إلى برامجك وإخراجها منها - الطباعة بـ print() وcat()، وقراءة مدخلات المستخدم.

الأسئلة الشائعة

كيف تدمج السلاسل النصية في R؟

باستخدام paste() أو paste0() - فليس في R معامل + للنصوص. فالتعبير paste("data", "science") يعطي "data science" (مفصولة بمسافة افتراضيًا)؛ بينما paste0("data", "science") يدمج دون فاصل. استخدم sep = لتغيير الفاصل وcollapse = لصهر متجه كامل في سلسلة واحدة.

كيف تحصل على طول سلسلة نصية في R؟

تعيد nchar("hello") القيمة 5، أي عدد المحارف. أما length("hello") فتعيد 1 - إذ تعد length() في R عناصر المتجه، والسلسلة الواحدة متجه من عنصر واحد. والخلط بين length() وnchar() هو خطأ المبتدئين الكلاسيكي.

ما الفرق بين sub() وgsub() في R؟

كلتاهما تبحث وتستبدل، لكن sub() تستبدل المطابقة الأولى فقط بينما تستبدل gsub() ‏("global sub") كل المطابقات. وكلتاهما تعامل النمط بوصفه تعبيرًا نمطيًا افتراضيًا - مرر fixed = TRUE لمطابقة النص الحرفي بدلًا من ذلك.

كيف تقسم سلسلة نصية في R؟

تقسم strsplit(x, split) وفق نمط، لكنها تعيد قائمة (لأنها قادرة على تقسيم عدة سلاسل دفعة واحدة). وللسلسلة الواحدة، خذ العنصر الأول: فالتعبير strsplit("a,b,c", ",")[[1]] يعطي المتجه النصي "a" "b" "c".

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن