Text is assigned to macro variables with the %let statement

Values may be printed to the log with the %put statement (other text may be included.) The macro variable name is preceded by an ampersand (&)

In [ ]:
%let name= Ed Norton ; 
%put The value of the macro variable name is:  &name;
In [ ]:
%let name2=' Ed Norton ';
%put name2 is &name2
In [ ]:
%let title="Joan's Report";
%put quotes are included in the saved text, title is  &title;
In [ ]:
%let start=;
%put Macro variable may be assigned a null value:  &start;
In [ ]:
%let sum=3+4;
%put Macro variables contain text, including numbers, no arithmetic is done. Sum is ∑
In [ ]:
%let total=0;
%let total=&total+∑
%put When macro variable definition included macro variables;
%put The included macro variables are "resolved" and then the definition is made;
%put total is now:  &total;

The macro facility stores values of macro variables in a Global Symbol Table

Quotation marks are stored as part of the value.

Null values are stored

Mathematical expressions are not evaluated

Macro variables included in the definition are resolved first

In [ ]:
%let x=varlist;
In [ ]:
%let &x=name age height;
%put The macro variable being defined can be a macro variable.  Still the resolution is done first;
%put &varlist;

Examples: Use a macro variable to represent a numeric value.

In [ ]:
%let units=4;
proc print data=orion.Order_Fact;
   where Quantity > &units;
   var Order_Date Product_ID Quantity;
   title "Orders exceeding &units units";
run;
In [ ]:
%let lower=34;
%let upper=44;
proc means data=fram.frex4;
var age sbp;
where &lower < age < &upper;
run;

Example: Use a macro variable to represent a character value.

In [ ]:
title;
footnote;

%let office=Sydney;
proc print data=orion.Employee_Addresses;
   where City="&office";
   var Employee_Name;
   title "&office Employees";
run;
title;

Use macro variables to select dates.

In [ ]:
%let date1=25may2007;
%let date2=15jun2007;
proc print data=orion.Order_Fact;
   where Order_Date between "&date1"d and "&date2"d;
   var Order_Date Product_ID Quantity;
   title "Orders between &date1 and &date2";
run;
title;

The user keyword with %put lists all user-defined macro variables

In [ ]:
%put _user_;

The SYMBOLGEN system option writes macro variable values to the SAS log

(NOSYMBOLGEN is default)

In [ ]:
options symbolgen;
%let office=Sydney;
proc print data=orion.Employee_Addresses;
   where City="&office";
   var Employee_Name;
   title "&office Employees";
run;
title;
options nosymbolgen;

The %SYMDEL statement deletes one or more user-defined macro variables from the global symbol table.

In [ ]:
%let x1=First macro text;
%let x2=second macro text;
%put _user_;
In [ ]:
%symdel x1 x2;
%put _user_;

Some simple examples

Example 1 Graphing the logistic model

$$p_i=\Pr(Y_i=1|x_i)=\frac{\exp (\beta_0+\beta_1*x_i)}{1+\exp (\beta_0+\beta_1*x_i)}$$$$p_i=\Pr(Y_i=1|x_i)=\frac{1}{1+\exp \{ -(\beta_0+\beta_1*x_i)\}}$$
In [ ]:
data logistic;
  do x=0 to 125;
    prob=exp(-6+.1*x)/(1+exp(-6+.1*x));
      logit=log(prob/(1-prob));
      output;
    end;

run;

proc sgplot data=logistic;
  series x=x y=prob;
qrefline 0 .5 1 /axis=y;
title "Some Properties of the Logistic Curve";
title2 "Asymptotes and Inflection Point";
footnote "Symetric Sigmoid";
run;

proc sgplot data=logistic;
    series x=x y=logit;
title "Logits are linear.";
run;

title;
footnote;
In [ ]:
%let b0=-6;
%let b1=.08;

data logistic;
  do x=0 to 125;
    prob=exp(&b0+&b1*x)/(1+exp(&b0+&b1*x));
      logit=log(prob/(1-prob));
      output;
    end;

run;

proc sgplot;
  series x=x y=prob;
qrefline 0 .5 1 /axis=y;
title "Some Properties of the Logistic Curve";
title2 "Asymptotes and Inflection Point";
footnote "Symetric Sigmoid";
run;
proc sgplot data=logistic;
    series x=x y=logit;
title "Logits are linear.";
run;
title;
footnote;

Simulate the mean from a sample of 9 normal variates for 100 different samples.

In [ ]:
data normals (keep=normmn);
array x{9};
call streaminit(1768315);
do reps=1 to 100;
  do obs=1 to 9;
    x{obs}=rand("Normal");
end;
normmn=mean(of x:);
  output;
end;
run;
ods select histogram;
proc univariate data=normals;
var normmn;
histogram normmn;
run;

Simulate the mean from a sample of &obs normal variates for &reps different samples.

In [ ]:
%let reps=1000;
%let obs=25;
%let seed=1768315;
data normals (keep=normmn);
array x{&obs};
call streaminit(&seed);
do reps=1 to &reps;
  do obs=1 to &obs;
    x{obs}=rand("normal");
end;
normmn=mean(of x:);
  output;
end;
run;
ods select histogram;
proc univariate data=normals;
var normmn;
histogram normmn;
run;

Sometimes macro variables are handy in analysis.

In [ ]:
options nofmterr;
    libname nh (tmp);
  data diettmp;
  set nh.nh1final;
  alcohol=max(0,(calories-4*protein-4*total_carbohydrate-9*fat)/7);
  if nmiss
  (PROTEIN, FAT, TOTAL_CARBOHYDRATE, Alcohol, CALCIUM,
  PHOSPHORUS, IRON, SODIUM,POTASSIUM,SATURATED_FAT, OLEIC_ACID,
  LINOLEIC_ACID, CHOLESTEROL, race, sex, age, fu_yrs, dead, BMI,
  CHOL, sbpsit1, smok2, pre_diab)
                                  =0;
  keep 
  PROTEIN  FAT  TOTAL_CARBOHYDRATE  Alcohol  CALCIUM 
  PHOSPHORUS  IRON  SODIUM POTASSIUM SATURATED_FAT OLEIC_ACID 
  LINOLEIC_ACID  CHOLESTEROL  race  sex  age  fu_yrs  dead  BMI 
  CHOL  sbpsit1  smok2  pre_diab
  ;
run;
proc sort data=diettmp;
by race sex;
run;

Do some analyses

In [ ]:
proc phreg data =diettmp;
by race sex;
    model fu_yrs*dead(0) =PROTEIN FAT TOTAL_CARBOHYDRATE Alcohol CALCIUM PHOSPHORUS IRON SODIUM
     POTASSIUM SATURATED_FAT OLEIC_ACID LINOLEIC_ACID CHOLESTEROL;
run;
proc phreg data =diettmp;
by race sex;
    model fu_yrs*dead(0) =age PROTEIN FAT TOTAL_CARBOHYDRATE Alcohol CALCIUM PHOSPHORUS IRON SODIUM
 POTASSIUM SATURATED_FAT OLEIC_ACID LINOLEIC_ACID CHOLESTEROL;
run;
proc phreg data =diettmp;
by race sex;
    model fu_yrs*dead(0) =age PROTEIN FAT TOTAL_CARBOHYDRATE Alcohol CALCIUM PHOSPHORUS IRON SODIUM
 POTASSIUM SATURATED_FAT OLEIC_ACID LINOLEIC_ACID CHOLESTEROL BMI 
  CHOL  sbpsit1  smok2  pre_diab;
run;

The same analysis with user defined macro variables

In [ ]:
options nofmterr;
%let dietvars=PROTEIN FAT TOTAL_CARBOHYDRATE Alcohol CALCIUM PHOSPHORUS IRON SODIUM
 POTASSIUM SATURATED_FAT OLEIC_ACID LINOLEIC_ACID CHOLESTEROL;
%let covars=BMI CHOL sbpsit1 smok2 pre_diab;

  data diettmp;
  set nh.nh1final;
  alcohol=max(0,(calories-4*protein-4*total_carbohydrate-9*fat)/7);
  if nmiss(of &dietvars &covars age race sex dead fu_yrs)=0;
  keep &dietvars &covars age race sex dead fu_yrs;
  ;
run;
proc sort data=diettmp;
by race sex;
run;
proc phreg data =diettmp;
by race sex;
model fu_yrs*dead(0) =&dietvars;
run;
proc phreg data =diettmp;
by race sex;
model fu_yrs*dead(0) =age &dietvars;
run;
proc phreg data =diettmp;
by race sex;
model fu_yrs*dead(0) =age &dietvars &covars;
run;
Global Symbol Table
nameEd Norton
name2' Ed Norton '
name3"Joan's Report"
start
sum3+4
total0+3+4
......