أساسيات برمجة SAS Base. الدرس 4. إنشاء مجموعات بيانات SAS

في مقال سابق ، تعلمنا كيفية قراءة البيانات الأولية الخارجية. اليوم سنتعرف على عامل التشغيل SET ، الذي يقرأ مجموعات بيانات SAS القياسية (مجموعة بيانات SAS) ، ونتعلم كيفية إنشاء شرائح البيانات ، وتكوين السمات الثابتة ، وكذلك تعلم بعض وظائف SAS المفيدة. مرة أخرى ، سأحاول تقديم المادة بأبسط لغة ممكنة ، باستخدام أكبر عدد ممكن من الأمثلة.



لنفترض أن البيانات مخزنة بتنسيق EXCEL في الدليل C: \ Workshop \ habrahabr . نقوم باستيراد جدول البيانات ، وإنشاء شريحة منه ، وإنشاء أعمدة محسوبة جديدة باستخدام وظائف SAS ، ثم تقسيم مجموعة البيانات هذه إلى قسمين.

استيراد جدول البيانات وتعيين عامل تصفية



يتم تخزين ملف excel في الدليل أعلاه ويبدو كما يلي:

مقتطف الملف:


نطبق إجراء PROC IMPORT لتحويل جدول بيانات إلى مجموعة بيانات SAS:

options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company replace; getnames=yes; run; 

يعين الخيار validvarname = V7 أسماء الحقول الصحيحة من وجهة نظر SAS: يستبدل جميع الأحرف غير الصالحة بشرطة سفلية. يمكن العثور على قواعد تسمية المتغيرات في الدرس 1.

نقوم بتعيين المرشح على الفور عند قراءة ملف خارجي ، على سبيل المثال ، نختار فقط تلك الملاحظات التي لا يفقد فيها تاريخ الانتهاء. لاحظ بناء الجملة للمعلمة.

 options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company (where=(End_Date not is missing)) replace; getnames=yes; run; 

دعونا نفكر بالتفصيل في مشغلي خطوة استيراد PROC:

ملف البيانات - يحدد المسار الكامل واسم الملف الخارجي
Dbms - يحدد نوع البيانات المراد استيرادها.
Out - يحدد مجموعة بيانات إخراج SAS باسم SAS واحد أو مستويين (اسم المكتبة واسم مجموعة البيانات).
استبدال - استبدال مجموعة بيانات SAS موجودة.
Getnames - يشير إلى ما إذا كان PROC IMPORT يولد أسماء متغيرات SAS من قيم البيانات في السطر الأول من ملف الإدخال الخارجي.

قم بتشغيل خطوة استيراد PROC وفحص LOG:


قم بطباعة مجموعة بيانات SAS الناتجة:

 proc print data=work.company noobs; run; 

يظهر ناتج إجراء PROC PRINT أدناه:

جزء:


أيضًا في SAS UE ، يمكنك استخدام علامة التبويب "النتائج" لعرض مجموعة بيانات SAS المستوردة.


قراءة مجموعات بيانات SAS



يتم تنفيذ قراءة مجموعة بيانات SAS في خطوة DATA باستخدام عبارة SET :

خذ بعين الاعتبار بناء الجملة العام لعبارة SET:

 SET<SAS-data-set(s) <(data-set-options(s) )> > <options>; 

إذا لم تحدد مجموعة بيانات في عبارة SET ، فستقرأ الملاحظات من آخر مجموعة بيانات SAS تم إنشاؤها.

في عبارة SET ، يمكنك تحديد عدة مجموعات بيانات ؛ في هذه الحالة ، ستتم إضافة مجموعات بيانات SAS واحدة تحت الأخرى (على غرار UNION في SQL).

أيضًا ، في خطوة DATA ، يمكن أن يكون هناك عبارتان SET ، وفي هذه الحالة يتم ربط الجداول بعمود مشترك. يمكنك قراءة المزيد عن عبارتي SET في هذه المقالة ، على سبيل المثال.

أبسط كود لإنشاء نسخة من مجموعة بيانات SAS هو كما يلي:

 data company1; set company; run; 

تكوين واصف مجموعة بيانات SAS


يمكنك فحص واصف مجموعة بيانات SAS باستخدام إجراء المحتويات PROC ( انظر الدرس 2 ). في هذا البرنامج التعليمي ، سنقوم بطباعة مكون الواصف باستخدام إجراء PROC DATASETS :

 proc datasets library=work nolist; contents data=company order=varnum; quit; 

جزء من النتائج:


قم بتعيين تنسيق ثابت لمتغيرات Travel_Expenses والميزانية:

 data company; set company; format Travel_Expenses Budget dollar10.2; run; 

تحقق من سمات مجموعات بيانات SAS:

 proc datasets library=work nolist; contents data=company order=varnum; quit; 


إنشاء أعمدة محسوبة


يمكن استكشاف جميع وظائف SAS في وظائف SAS 9.4 وإجراءات CALL: المرجع ، الإصدار الخامس .

بالإضافة إلى ذلك ، إذا لم تكن هناك وظيفة مناسبة لأداء مهمة معينة ، يمكنك استخدام إجراء PROC FCMP وإنشاء وظيفتك الخاصة.

في هذا الدرس ، سوف نستكشف الوظائف الثلاث YRDIF و SUM و CATS.

لحساب الفرق في التواريخ بالسنوات ، سنستخدم الدالة YRDIF .

دعني أذكرك بأن التاريخ بتنسيق SAS هو عدد الأيام بدءًا من 1 يناير 1960 ( انظر الدرس 1 ). على البيانات المقدمة ، نحتاج إلى حساب وقت التنفيذ:

 data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); format Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run; 

يرجى ملاحظة أنه باستخدام تنسيق 3.1 لمتغير Lead_Time ، قمنا بتقريب القيم المحسوبة في التقرير (!) إلى خانة عشرية واحدة. لا يغير عامل التنسيق القيمة في مجموعة بيانات SAS!

جزء من النتائج:


بعد ذلك ، نحسب تكلفة العمل بدون نفقات السفر:

 data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run; 

جزء من النتائج:


كجزء من مهمتنا ، قمنا بحساب تكلفة العمل دون الأخذ في الاعتبار نفقات السفر دون استخدام الوظيفة. لا توجد قيم مفقودة في جدولنا ، إذا كانت قيمة أحد المتغيرات (الميزانية أو Travel_Expenses) مفقودة ، كانت النتيجة "مهمة".

على سبيل المثال:

إنشاء مجموعة بيانات اختبار:

 data test; input Budget Travel_Expenses; datalines; 12345 233 . 345 12543 . ; 

حساب الفرق في المتغيرات ميزانية Travel_Expenses

 data test; set test; value=Budget-Travel_Expenses; run; 

نتيجة هذه الخطوة:


للحصول على النتيجة الصحيحة ، يمكنك استخدام الدالة SUM .

تنتمي هذه الوظيفة إلى فئة وظائف الإحصاء الوصفي . تتجاهل الدوال الإحصائية الوصفية القيم المفقودة.

كتابة الرمز عبر SUM:

 data test; set test; value=sum(Budget,-Travel_Expenses); run; 

في هذه الحالة تكون نتيجة الخطوة كما يلي:


العمود المحسوب الثالث هو عنوان البريد الإلكتروني للمدير. يمكن "تجميعها" من الأعمدة Manager_FirstName و Manager_LastName وقيم habr .com

يمكنك استخدام الدالة CATS لدمج قيم النص في سطر واحد.

 data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run; 

جزء من النتائج:


دعنا نفحص واصف مجموعة البيانات التي تم إنشاؤها:

 proc contents data=work.company1 varnum; run; 

جزء مقبض:


انتبه إلى طول متغير البريد الإلكتروني ، حيث يبلغ 200 بايت ، وهذا هو الطول الافتراضي الذي يتم إرجاعه بواسطة دالة CATS. إذا فحصنا سمات المتغيرين Manager_FirstName و Manager_LastName ، فيمكننا التأكد من أن 8 + 6 + طول السلسلة "@ habr.com" كافٍ لمتغير البريد الإلكتروني ، أي 9 بايت أخرى ، إجمالي 23. لماذا يجب الانتباه إلى ذلك؟ تحقق جميع الأحرف المفقودة مسافات ، مما يؤثر على حجم مجموعة البيانات وسيؤثر على الأداء على كميات كبيرة من البيانات.

لتعيين طول متغير البريد الإلكتروني بشكل صريح ، يجب عليك استخدام عامل التشغيل LENGTH:

 data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run; 

التعامل مع الشظية


أنشئ عمودًا تفصيليًا بناءً على متغير Lead_Time ، مع مراعاة الشروط التالية:

  1. إذا كانت قيمة متغير Lead_Time أقل من 1 ، فإن قيمة عمود التفاصيل أقل من سنة واحدة.
  2. إذا كانت قيمة متغير Lead_Time في النطاق من 1 إلى 2 ، بما في ذلك الحدود ، عندئذٍ يكون لعمود "التفاصيل" من سنة إلى سنتين.
  3. إذا كانت قيمة متغير Lead_Time في النطاق من 2 إلى 3 ، باستثناء 2 ، فإن قيمة العمود التفصيلي تتراوح بين 2-3 سنوات.
  4. إذا كانت قيمة متغير Lead_Time في النطاق من 3 إلى 4 ، باستثناء 3 ، عندئذٍ يكون لعمود التفاصيل قيمة 3-4 سنوات.
  5. إذا كانت قيمة متغير Lead_Time في النطاق من 4 إلى 5 ، باستثناء 4 ، فإن قيمة العمود التفصيلي تبلغ من 4 إلى 5 سنوات.
  6. في جميع الحالات الأخرى ، يكون لعمود التفاصيل قيمة أعلى من 5 سنوات.

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

  1. IF-THEN-ELSE
  2. ELSE IF
  3. اختر عندما

بالنسبة للكميات الكبيرة من البيانات ، يكون استخدام الخيارين الأخيرين أكثر كفاءة.

 data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='4-5 years'; else detail='above 5 years'; run; 

أضف شرطًا يحدد فقط تلك الملاحظات التي لا تساوي فيها قيمة متغير التفاصيل "فوق 5 سنوات". عند استخدام المكان كمرشح ، سيحدث خطأ في البنية:


عبارة حيث لا يتم استخدام الأعمدة المحسوبة. لتحديد المتغيرات التي نحتاجها ، نحتاج إلى بيان IF انتقائي. ويلغي ناتج الملاحظة لمجموعة البيانات التي تم إنشاؤها:

 data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run; 

لاحظ أيضًا أن عبارة IF الانتقائية تتطلب عامل حسابي. لا يمكننا الكتابة ، على سبيل المثال ، مثل:

 if detail contains 'above 5 years'; 

سيتم عرض خطأ في السجل:


تكوين مجموعة بيانات SAS.


يجب ألا تكون المتغيرات Manager_FirstName و Manager_LastName موجودة في مجموعة بيانات SAS الجديدة. يتم تنفيذ هذا المطلب باستخدام معلمة DROP ، ويمكن أيضًا استخدام عامل تشغيل DROP.

 data company1 (drop=Manager_FirstName Manager_LastName); set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run; 

قمنا بتقسيم مجموعة بيانات SAS التي تم إنشاؤها إلى قسمين وفقًا للشرط المحدد


في خطوة واحدة DATA ، يمكنك إنشاء مجموعات بيانات SAS متعددة. إنشاء مجموعة بيانات منفصلة لكل بلد.

للتحقق من القيم الموجودة في عمود الدولة ، على سبيل المثال ، يمكنك استخدام إجراء PROC FREQ .

 proc freq data=company1; table Country /nocum nopercent; run; 

تأخذ هذه الخطوة في الاعتبار عدد المرات التي تحدث فيها قيمة معينة من متغير البلد في مجموعة بيانات SAS المحددة في معلمة data =.

ستكون نتيجة هذه الخطوة على النحو التالي:


لذا ، سننشئ مجموعتين من البيانات في خطوة واحدة من البيانات باستخدام عامل التشغيل OUTPUT والمعالجة المشروطة:

 data US AU; set work.company1; if Country='AU' then output AU; if Country='US' then output US; run; 

قم بتشغيل الكود وانظر LOG:


هذا باختصار حول قراءة مجموعات بيانات SAS وتكوينها. في المقالة التالية ، سوف نقدم لك دمج مجموعات البيانات باستخدام عبارات MERGE و SET.

وبصفتي PS ، سأذكرك ببنية دروس SAS BASE:

المقالات التي تم نشرها بالفعل:

  1. أساسيات البرمجة على SAS BASE. الدرس 1.
  2. أساسيات البرمجة على SAS BASE. الدرس 2. الوصول إلى البيانات
  3. أساسيات البرمجة على SAS BASE. الدرس 3. قراءة الملفات النصية.
  4. لقد تعلمت للتو الدرس الرابع.

في المقالات التالية ، أود أن أسلط الضوء على قضايا مثل الانضمام إلى الجداول في SAS Base (دمج ، مجموعة) ، معالجة شرطية ، حلقات ، وظائف SAS ، إنشاء تنسيقات مخصصة ، SAS Macro ، PROC SQL.

سأكون سعيدا للتعليق في التعليقات! ما المواضيع الأخرى التي تود رؤيتها في المقالات؟

Source: https://habr.com/ru/post/ar426765/


All Articles