sassas-macrodatastep

How to recall a numeric macro variable with a string prefix in SAS


I obtain an error in SAS while creating a new field in a dataset recalling a numeric macro variable. Here there's an example.

data input;
input cutoff_1 cutoff_2;
datalines;
30 50
;

data db;
input outstanding;
datalines;
1000.34
2000.45
3000.90
5000.98
8000.02
;


data _null_;
set input;
call symput("perc1",cutoff_1);
call symput("perc2",cutoff_2);
run;
    
proc univariate data=db noprint;
    var outstanding;
 
    output out=test
    pctlpts = &perc1. &perc2.
    pctlpre = P_;
run;

data test2;
set test;
p_&perc1._round=round(P_&perc1.,1);
p_&perc2._round=round(P_&perc2.,1);
run;

From the log it seems that the macros &perc. are solved, but that it's not possible to use those results (30, 50) to name a new variable in the dataset test2. What am I missing?


Solution

  • When you ask normal SAS code to use a numeric value in a place where a character value is required (both arguments to CALL SYMPUT() require character values) then SAS will convert the number into a string using the BEST12. If the value does not require all 12 characters it will be right aligned. So you created macro variables with leading spaces. The leading spaces make no difference for generating pctlpts= option values as extra spaces will not matter there. But having the leading spaces mean you are generating code like:

    p_         30_round=round(P_          30,1);
    

    You should use the modern (probably over 20 years old) CALL SYMPUTX() function instead. That function will remove leading/trailing spaces from the second argument when creating the macro variable. It also accepts a numeric value as the second argument converting the number into a character string using a format more like BEST32 instead of BEST12.

    call symputx("perc1",cutoff_1);
    call symputx("perc2",cutoff_2);
    

    The only cases where you should ever use the ancient CALL SYMPUT() function is when you actually need to create macro variables that contain leading and/or trailing spaces.

    Other solutions are to remove the spaces in the function call

    call symput("perc1",strip(put(cutoff_1,best32.)));
    

    or after generating the macro variables.

    %let perc1=&perc1;