Creating a Macro Variable during DATA Step Execution

Overview

In many applications, you need to create macro variables during DATA step execution. You might need to create macro variables and to assign values to them based on the following:
  • data values in SAS data sets or in external files
  • programming logic
  • computed values.
For example, suppose you want to create a report that lists students who are enrolled in a specific course, according to data in the Sasuser.All data set. Suppose you want to include a footnote in your report to indicate whether any student fees are unpaid.
The following program uses SAS programming logic to determine which value is assigned to the macro variable foot. Then foot is referenced in the FOOTNOTE statement later in the program.
options symbolgen pagesize=30;
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
      put total= paidup=; /* Write information
                            to the log. */
      if paidup<total then do; 
         %let foot=Some Fees Are Unpaid;
      end; 
      else do; 
         %let foot=All Students Have Paid; 
      end; 
   end;
run;

proc print data=revenue;
   var student_name student_company paid;
   title "Payment Status for Course &crsnum";
   footnote "&foot";
run;
Running the program produces the following report:
Payment status for course 3
Although you can see that several students still have unpaid fees, the footnote indicates that all students have paid. Obviously, the footnote is wrong. That is, the macro variable foot resolves to the value All Students Have Paid when it should not do so. Look at the following example.

Example

In order to understand the problem with this example, you should consider how macro variable processing works in conjunction with SAS processing. Remember that when both macro language statements and SAS language statements occur in the same step, the macro processor executes macro language statements before any SAS language statements are executed.
Remember, you want to create a report that lists students who are enrolled in a specific course, according to data in the Sasuser.All data set, and you want to include a footnote in your report to indicate whether any student fees are unpaid. The following program uses SAS programming logic to determine which value is assigned to the macro variable foot. Then foot is referenced in the FOOTNOTE statement later in the program.
options symbolgen pagesize=30;
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
      put total= paidup=; /* Write information
                            to the log. */
      if paidup<total then do;
         %let foot=Some Fees Are Unpaid;
      end;
      else do;
         %let foot=All Students Have Paid;
      end;
   end;
run;
    
proc print data=revenue;
   var student_name student_company paid;
   title "Payment Status for Course &crsnum";
   footnote "&foot";
run;
In this example, the first %LET statement inside the DATA step is passed to the macro processor as soon as the word scanner encounters it. The macro processor then creates a macro variable named foot in the symbol table and assigns the value Some Fees Are Unpaid to the variable.
The word scanner then continues to read the program and passes the second %LET statement in the DATA step to the macro processor as well. This time, the macro processor reassigns the value All Students Have Paid to foot in the symbol table.
When the RUN statement in the DATA step is encountered, SAS recognizes that the step is complete, and executes it. Remember that at this point the DATA step no longer includes any of the %LET statements (which have already been executed by the macro processor). Because the %LET statements are always processed by the macro processor before the DATA step is executed, the value of foot is always whatever the last %LET statement assigns.
Here is a representation of the program that is processed by the DATA step compiler as a result of the above code.
Table 10.1 Code after Substitution
data revenue;
   set sasuser.all end=final;
   where course_number=3;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
      put total= paidup=;
      if paidup<total then do;
      end;
      else do;
      end;
   end;
run;
proc print data=revenue;
   var student_name student_company paid;
   title "Payment Status for Course 3";
   footnote "All Students Have Paid";
run;
We can solve this problem with the following information.

The SYMPUT Routine

The DATA step provides functions and a CALL routine that enable you to transfer information between an executing DATA step and the macro processor. You can use the SYMPUT routine to create a macro variable and to assign to that variable any value that is available in the DATA step.
General form, SYMPUT routine:
CALL SYMPUT(macro-variable,text);
Here is an explanation of the syntax:
macro-variable
is assigned the character value of text.
macro-variable and text
can each be specified as
  • a literal, enclosed in quotation marks
  • a DATA step variable
  • a DATA step expression.
Note: If macro-variable already exists, the value of text replaces the former value.
When you use the SYMPUT routine to create a macro variable in a DATA step, the macro variable is not actually created and assigned a value until the DATA step is executed. Therefore, you cannot successfully reference a macro variable that is created with the SYMPUT routine by preceding its name with an ampersand until after the step boundary that causes DATA step execution.
In the next few sections that you will see several examples of how the SYMPUT routine can be used in different situations.

Using SYMPUT with a Literal

In the SYMPUT routine, you use a literal string for the following:
  • the first argument to specify an exact name for the name of the macro variable
  • the second argument to specify the exact character value to assign to the macro variable.
To use a literal with the SYMPUT routine, you enclose the literal string in quotation marks.
CALL SYMPUT('macro-variable', 'text');

Example

Remember the previous example, in which you wanted to conditionally assign a value to the macro variable foot based on values that are generated during DATA step execution. You can use the SYMPUT routine with literal strings as both arguments in order to accomplish this.
options symbolgen pagesize=30;
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
   if paidup<total then do;
      call symput('foot','Some Fees Are Unpaid'),
   end;
   else do;
      call symput('foot','All Students Have Paid'),
   end;
end;
run;

proc print data=revenue;
   var student_name student_company paid;
   title "Payment Status for Course &crsnum";
   footnote "&foot";
run;
This time, the value assigned to foot is either Some Fees Are Unpaid or All Students Have Paid, depending on the value of the DATA step variable Paidup, because the value is assigned during the execution of the DATA step. When you submit this code, you get the following output.
Payment status for course 3

Using SYMPUT with a DATA Step Variable

You can assign the value of a DATA step variable as the value for a macro variable by using the DATA step variable's name as the second argument to the SYMPUT routine.
To use a DATA step variable as the value for a macro variable in the SYMPUT routine, you place the name of the DATA step variable after the name of the macro variable, separated by a comma. You do not enclose the name of the DATA step variable in quotation marks.
CALL SYMPUT('macro-variable',DATA-step-variable);
This form of the SYMPUT routine creates the macro variable named macro-variable and assigns to it the current value of DATA-step-variable.
When you use a DATA step variable as the second argument,
  • a maximum of 32,767 characters can be assigned to the receiving macro variable.
  • any leading or trailing blanks that are part of the DATA step variable's value are stored in the macro variable.
  • values of numeric variables are automatically converted to character values, using the BEST12. format.
CAUTION:
If you enclose the DATA step variable name in quotation marks, SAS interprets the name as a literal value rather than as a variable name, and the DATA step variable's value is not resolved.

Example

Once again, suppose you want to create a report about students who are enrolled in a particular course. This time, suppose you want to add a title that contains the course title and the course number, and you want to include a footnote that summarizes how many students have paid their fees.
In this example, a DATA step variable named paidup records the number of students that have paid, and a DATA step variable named total records the total number of students who are registered for the class. Macro variables are created to record the values of paidup, the value of total, and the value of Course_title. These macro variables are referenced later in the program.
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
      call symput('numpaid',paidup);
      call symput('numstu',total);
      call symput('crsname',course_title);
   end;
run;
proc print data=revenue noobs;
   var student_name student_company paid;
   title "Fee Status for &crsname (#&crsnum)";
   footnote "Note: &numpaid Paid out of &numstu Students";
run;
This time the footnote shows the correct information for how many students have paid.
Fee status for local area networks (#3)

Using CALL SYMPUT with DATA Step Expressions

If you had run the last example using listing output rather than HTML output, you would have seen extra blanks in the title between the course title and the course number, as well as in the footnote.
Table 10.2 SAS Listing Output
 Fee Status for Local Area Networks       (#3)                  

                                   
 Student_Name                Student_Company                  Paid

 Bills, Ms. Paulette         Reston Railway                    Y
 Chevarley, Ms. Arlene       Motor Communications              N
 Clough, Ms. Patti           Reston Railway                    N
 Crace, Mr. Ron              Von Crump Seafood                 Y
 Davis, Mr. Bruce            Semi;Conductor                    Y
 Elsins, Ms. Marisa F.       SSS Inc.                          N
 Gandy, Dr. David            Paralegal Assoc.                  Y
 Gash, Ms. Hedy              QA Information Systems Center     Y
 Haubold, Ms. Ann            Reston Railway                    Y
 Hudock, Ms. Cathy           So. Cal. Medical Center           Y
 Kimble, Mr. John            Alforone Chemical                 N
 Kochen, Mr. Dennis          Reston Railway                    Y
 Larocque, Mr. Bret          Physicians IPA                    Y
 Licht, Mr. Bryan            SII                               Y
 McKnight, Ms. Maureen E.    Federated Bank                    Y
 Scannell, Ms. Robin         Amberly Corp.                     N
 Seitz, Mr. Adam             Lomax Services                    Y
 Smith, Ms. Jan              Reston Railway                    N
 Sulzbach, Mr. Bill          Sailbest Ships                    Y
 Williams, Mr. Gene          Snowing Petroleum                 Y

      Note:           14 Paid out of           20 Students
You do not see these blanks if you are using HTML output, but they are still stored in the value of your macro variable.
Remember that when a DATA step variable is used as the second argument in a SYMPUT routine, any leading, or trailing blanks that are part of the DATA step variable's value are stored in the macro variable. Because the value of a macro variable is always a text string, numeric variables are automatically converted using the BEST12. format, and blanks are stored as part of the macro variable's value. In order to avoid including extra blanks, you need to use a DATA step function to remove them.
In these situations that you can use DATA step functions before the SYMPUT routine executes, in order to do the following:
  • left-align character strings that have been created by numeric-to-character conversions
  • remove extraneous leading and trailing blanks.
Often you want to combine several DATA step functions in order to create a DATA step expression as the second argument of the SYMPUT routine.
CALL SYMPUT('macro-variable',expression);
Note: A DATA step expression can be any combination of DATA step functions, DATA step variables, constants, and logical or arithmetic operators that resolves to a character or numeric constant.
When you use a DATA step expression as the second argument, its current value is evaluated according to the following rules:
  • Numeric expressions are automatically converted to character constants using the BEST12. format.
  • The resulting value can be up to 32,767 characters long.
  • Any leading or trailing blanks that are part of the expression are stored in the macro variable.

Example

In order to remove the extra blanks from the title and footnote of the previous example, you can use DATA step functions. To remove trailing blanks from crsname, you can use the TRIM function. To remove leading and trailing blanks from the macro variables numstu and numpaid, you can use the STRIP function.
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;

      call symput('numpaid',strip(paidup));
      call symput('numstu',strip(total));
      call symput('crsname',trim(course_title));
   end;
run;

proc print data=revenue noobs;
   var student_name student_company paid;
   title "Fee Status for &crsname (#&crsnum)";
   footnote "Note: &numpaid Paid out of &numstu Students";
run;
Table 10.3 SAS Listing Output
              Fee Status for Local Area Networks (#3)


 NAME                        COMPANY                          PAID

 Bills, Ms. Paulette         Reston Railway                    Y
 Chevarley, Ms. Arlene       Motor Communications              N
 Clough, Ms. Patti           Reston Railway                    N
 Crace, Mr. Ron              Von Crump Seafood                 Y
 Davis, Mr. Bruce            Semi;Conductor                    Y
 Elsins, Ms. Marisa F.       SSS Inc.                          N
 Gandy, Dr. David            Paralegal Assoc.                  Y
 Gash, Ms. Hedy              QA Information Systems  Center    Y
 Haubold, Ms. Ann            Reston Railway                    Y
 Hudock, Ms. Cathy           So. Cal. Medical Center           Y
 Kimble, Mr. John            Alforone Chemical                 N
 Kochen, Mr. Dennis          Reston Railway                    Y
 Larocque, Mr. Bret          Physicians IPA                    Y
 Licht, Mr. Bryan            SII                               Y
 McKnight, Ms. Maureen E.    Federated Bank                    Y
 Scannell, Ms. Robin         Amberly Corp.                     N
 Seitz, Mr. Adam             Lomax Services                    Y
 Smith, Ms. Jan              Reston Railway                    N
 Sulzbach, Mr. Bill          Sailbest Ships                    Y
 Williams, Mr. Gene          Snowing Petroleum                 Y

                  Note: 14 Paid out of 20 Students

PUT Function

Remember that the values of macro variables are always character strings. You have seen that in the DATA step the SYMPUT routine performs automatic numeric-to-character conversion on any numeric value that you attempt to assign to a macro variable. Messages are written to the SAS log to alert you that automatic conversion has occurred. Remember that the SYMPUT routine automatically uses the BEST12. format for the conversion.
Sometimes you might want to have explicit control over the numeric-to-character conversion. The PUT function returns a character string that is formed by writing a value with a specified format.
You can use the PUT function to do the following:
  • perform explicit numeric-to-character conversions
  • format the result of a numeric expression.
General form, PUT function:
PUT(source,format.)
Here is an explanation of the syntax:
source
is a constant, a variable, or an expression (numeric or character).
format.
is any SAS format or user-defined format, which determines
  • the length of the resulting string
  • whether the string is right- or left-aligned.
source and format.
must be the same type (numeric or character).

Example

Suppose you want to create a report that shows the amount of fees that are unpaid for a specific course. In the following example, you use the SYMPUT routine to format the value of the numeric variable Begin_date with the MMDDYY10. format and assign that value to the macro variable date. Then you also use another call to the SYMPUT routine to format the result of an expression involving Fee, total, and paidup as a dollar amount and assign that value to the macro variable due.
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
     call symput('crsname',trim(course_title));
     call symput('date',put(begin_date,mmddyy10.));
     call symput('due',strip(put(fee*(total-paidup),dollar8.)));
   end;
run;
You can use the macro variables date and due in a PROC PRINT step to create your report. The values of these macro variables appear in the report with the formatting that you assigned to them when you created them.
proc print data=revenue;
   var student_name student_company paid;
   title "Fee Status for &crsname (#&crsnum) Held &date";
   footnote "Note: &due in Unpaid Fees";
run;
Fee status for local area networks (#3) held 01/08/2001

The SYMPUTX Routine

The SYMPUTX routine is very similar to the SYMPUT routine. In addition to creating a macro variable and assigning a value to it, the SYMPUTX routine also automatically removes leading and trailing blanks from both arguments.
General form, SYMPUTX routine:
CALL SYMPUTX(macro-variable,expression);
Here is an explanation of the syntax:
macro-variable
is assigned the character value of expression, and any leading or trailing blanks are removed from both macro-variable and expression.
macro-variable and expression
can each be specified as
  • a literal, enclosed in quotation marks
  • a DATA step variable
  • a DATA step expression.
Note: If macro-variable already exists, the value of expression replaces the former value.

Example

Remember the example where you created a report about students who are enrolled in a particular course. This time, suppose you want the title to contain the course name and the course number, as well as the date on which the course was held. Also, you want the footnote to list the current amount of unpaid fees for the course.
In this example, three macro variables are created. The macro variable csrname records the value of the DATA step variable Course_title. The macro variable date records the value of the DATA step variable Begin_date in MMDDYY10. format. Finally, the macro variable due uses the values of the DATA step variables paidup, total, and fee to record the current amount of unpaid fees in DOLLAR8. format. These macro variables are referenced later in the program in the title and footnote statements.
%let crsnum=3;
data revenue;
   set sasuser.all end=final;
   where course_number=&crsnum;
   total+1;
   if paid='Y' then paidup+1;
   if final then do;
      call symputx('crsname',course_title);
      call symputx('date',put(begin_date,mmddyy10.));
      call symputx('due',put(fee*(total-paidup),dollar8.));
   end;
run;
proc print data=revenue;
   var student_name student_company paid;
   title "Fee Status for &crsname (#&crsnum) Held &date";
   footnote "Note: &due in Unpaid Fees";
run;
Fee status for local area networks (#3) held 01/08/2001
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.189.228