في
مقال سابق
، تعلمنا كيفية قراءة البيانات الأولية الخارجية. اليوم سنتعرف على عامل التشغيل 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 ، مع مراعاة الشروط التالية:
- إذا كانت قيمة متغير Lead_Time أقل من 1 ، فإن قيمة عمود التفاصيل أقل من سنة واحدة.
- إذا كانت قيمة متغير Lead_Time في النطاق من 1 إلى 2 ، بما في ذلك الحدود ، عندئذٍ يكون لعمود "التفاصيل" من سنة إلى سنتين.
- إذا كانت قيمة متغير Lead_Time في النطاق من 2 إلى 3 ، باستثناء 2 ، فإن قيمة العمود التفصيلي تتراوح بين 2-3 سنوات.
- إذا كانت قيمة متغير Lead_Time في النطاق من 3 إلى 4 ، باستثناء 3 ، عندئذٍ يكون لعمود التفاصيل قيمة 3-4 سنوات.
- إذا كانت قيمة متغير Lead_Time في النطاق من 4 إلى 5 ، باستثناء 4 ، فإن قيمة العمود التفصيلي تبلغ من 4 إلى 5 سنوات.
- في جميع الحالات الأخرى ، يكون لعمود التفاصيل قيمة أعلى من 5 سنوات.
يمكنك إنشاء عمود مفصل بطرق مختلفة ، على سبيل المثال ، الخيار الأبسط والأكثر وضوحًا هو استخدام المعالجة المشروطة. يمكن تنفيذه باستخدام العوامل التالية:
- IF-THEN-ELSE
- ELSE 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='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:
المقالات التي تم نشرها بالفعل:
- أساسيات البرمجة على SAS BASE. الدرس 1.
- أساسيات البرمجة على SAS BASE. الدرس 2. الوصول إلى البيانات
- أساسيات البرمجة على SAS BASE. الدرس 3. قراءة الملفات النصية.
- لقد تعلمت للتو الدرس الرابع.
في المقالات التالية ، أود أن أسلط الضوء على قضايا مثل الانضمام إلى الجداول في SAS Base (دمج ، مجموعة) ، معالجة شرطية ، حلقات ، وظائف SAS ، إنشاء تنسيقات مخصصة ، SAS Macro ، PROC SQL.

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