Notice, that in the code above we have multiple if-then-else statements of a certain pattern that are repeated multiple times and thus they can be generated via %do-loop. Let’s implement this the data-driven way, without any hard-coded values. Besides, if a number of categories is large, the code becomes large too. Except when category definition changes you would have to find every place in your code where to apply that change. ![]() If ACTUAL < 2000 then SALE_CATEGORY = 'F' If ACTUAL < 900 then SALE_CATEGORY = 'E' else If ACTUAL < 700 then SALE_CATEGORY = 'D' else If ACTUAL < 500 then SALE_CATEGORY = 'C' else If ACTUAL < 200 then SALE_CATEGORY = 'B' else If ACTUAL < 50 then SALE_CATEGORY = 'A' else Suppose we have to create SALE_CATEGORY variable on our sashelp.prdsale table, something that you would routinely code like this: Let’s solve the following coding problem. The problem is the data _null_ statement that converts primary index &i to the secondary index &cntry, since we can’t use a data step within another data step. This implementation of the macro %do-loop works perfectly fine, except in the situations when we need to use it within a data/proc step. During the code compilation, SAS macro processor loops through the %do-loop &i times repeatedly generating SAS code within it, each time with a new value &cntry, thus accomplishing our task.For each iteration &i of %do-loop, we create a secondary index – macro variable &cntry, which is used as a true index for our loop. We use data _null_ step within that loop to sequentially read values of COUNTRY using direct access to observations of untries table by means of point= option.Within macro called %loop, we use primary index – macro variable &i – to iterate from 1 to &num with increment 1.We determine the number of unique COUNTRY values, &num.Using proc sort with nodupkey option we create a table untries of unique COUNTRY values.Proc gchart data=sashelp.prdsale(where=(COUNTRY eq "&cntry")) Title1 "Product sales by year for &cntry" Goptions reset=all device=actximg colors=() htext=9pt hsize=5in vsize=3in Ods html path=odsout file="report_&cntry.html" style=aside ![]() Proc sort data=sashelp.prdsale(keep=COUNTRY) out=untries nodupkey Here is how this can be done the data-driven way without any hard-coding:įilename odsout "C:\PROJECTS\_BLOG_SAS\data-driven-macro-loops\html" Suppose, we need to produce in separate HTML files for each country - charts showing actual product sales by years. SAS macro loops containing data or proc stepsįor example, we have data table sashelp.prdsale that looks like this: The following figure illustrates this concept. To make macro loop driven by data we can use two index macro variables: the first one (primary index) iterates from 1 to n incrementing by 1 effectively going through the observations of a driver table, the other macro variable (secondary index) gets its values from the driver variable and is being a true data-driven index for our macro loop. They can be either within a data step (or proc step) generating multiple data/proc step statements, or outside data/proc step generating multiple data/proc steps or global statements. Syntactically speaking, while SAS programming loops or do-loopsalways reside within SAS data step, SAS macro loops or %do-loopsare located within SAS macros. That makes SAS macro loops a powerful code generator tool allowing to produce multiple variations of SAS code snippets with actually writing them just once. SAS macro loops, on the other hand, are completely different creatures as they do not iterate during execution time, but rather during code compilation time. ![]() Handpicked Related Content: CALL EXECUTE made easy for SAS data-driven programming These ordinary programming loops iterate during code execution while processing some data elements of an input data table. In my previous post, Introducing data-driven loops, I suggested a way of implementing programming loops with a list of index variables pulled from an external data table.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |