DATA Step, Macro, Functions and more

retrieve a numeric format stored in a macro variable

Accepted Solution Solved
Reply
Contributor
Posts: 23
Accepted Solution

retrieve a numeric format stored in a macro variable

In row 42 below I'm trying to select a numeric format name that I stored in a macro variable, but SAS seems to read it as character (see "NOTE 484-185" below).   What can be done to tell SAS it is numeric?

 

27 /*Store variable names*/

28 %let varvals=Partictype RecPmtRcvd;

29 /*Store their associated format names*/

30 %let formval=partictype yesno;

31 options mprint;

32 data temp1(keep=CJRorig Var_name Var_value);

33 length var_name var_value $20;

34 set CJR_Combine;

35 if CJRorig=1 then do;

36 /*Create an observation for each variable*/

37 %macro selval;

38 %do i=1 %to 2;

39 /*Assign the variable name to Var_name*/

40 Var_name="%scan(&varvals,&i)";

41 /*Assign its formatted value to Var_value*/

42 Var_value=put(Var_name,%scan(&formval,&i).);

43 %end;

44 %mend;

45 %selval

MPRINT(SELVAL): Var_name="Partictype";

NOTE: Line generated by the macro function "SCAN".

45 partictype

__________

484

MPRINT(SELVAL): Var_value=put(Var_name,partictype.);

MPRINT(SELVAL): Var_name="RecPmtRcvd";

NOTE 484-185: Format $PARTICTYPE was not found or could not be loaded.

NOTE: Line generated by the macro function "SCAN".

45 yesno

_____

2 The SAS System 09:50 Tuesday, June 12, 2018

484

MPRINT(SELVAL): Var_value=put(Var_name,yesno.);

NOTE 484-185: Format $YESNO was not found or could not be loaded.

46 output;

47 end;

48 run;

NOTE: There were 3316 observations read from the data set WORK.CJR_COMBINE.

NOTE: The data set WORK.TEMP1 has 793 observations and 3 variables.

NOTE: DATA statement used (Total process time):

real time 0.04 seconds

cpu time 0.04 seconds


Accepted Solutions
Solution
a week ago
Super User
Posts: 13,321

Re: retrieve a numeric format stored in a macro variable

It is a poor idea to define a macro in the middle of a data step.

When you do this:

if CJRorig=1 then do;

36 /*Create an observation for each variable*/

37 %macro selval;

The behavior can be very problematic.

 

Note that MACROS do not access data step variables without a lot of extra work.

In

40 Var_name="%scan(&varvals,&i)";

41 /*Assign its formatted value to Var_value*/

42 Var_value=put(Var_name,%scan(&formval,&I).);

The data step variable VAR_NAME will always be character. So if you attempt to put the value with a numeric format you get that error.

 

You might try

 

Var_value=put(%scan(&varvals,&i),%scan(&formval,&i).);

But that will require having the variable referenced in your macro variable in the data set.

Note that if you have a format that uses decimals such as F8.2 your code will also yield unexpected resultsas it attempts to use format "F8." due to the . you have to terminate the scanned formval AND that . is a default delimiter to %scan. Which then means the value following the . is the next format to use.

 

To output multiple records from one you also need an OUTPUT statement inside the DO loop.

View solution in original post


All Replies
Super User
Posts: 23,291

Re: retrieve a numeric format stored in a macro variable

PUT does not take a format without the dot and/or $, try PUTC or PUTN instead depending on the type. It also looks like you're missing the $ for a character format.

 

I can't quite decipher your code but it also looks like you have a macro definition embedded in a data step. I would highly suggest not doing that. I also think you want some array logic here, and use the macro count but not necessarily a macro here. 

 


@Batman wrote:

In row 42 below I'm trying to select a numeric format name that I stored in a macro variable, but SAS seems to read it as character (see "NOTE 484-185" below).   What can be done to tell SAS it is numeric?

 

27 /*Store variable names*/

28 %let varvals=Partictype RecPmtRcvd;

29 /*Store their associated format names*/

30 %let formval=partictype yesno;

31 options mprint;

32 data temp1(keep=CJRorig Var_name Var_value);

33 length var_name var_value $20;

34 set CJR_Combine;

35 if CJRorig=1 then do;

36 /*Create an observation for each variable*/

37 %macro selval;

38 %do i=1 %to 2;

39 /*Assign the variable name to Var_name*/

40 Var_name="%scan(&varvals,&i)";

41 /*Assign its formatted value to Var_value*/

42 Var_value=put(Var_name,%scan(&formval,&i).);

43 %end;

44 %mend;

45 %selval

MPRINT(SELVAL): Var_name="Partictype";

NOTE: Line generated by the macro function "SCAN".

45 partictype

__________

484

MPRINT(SELVAL): Var_value=put(Var_name,partictype.);

MPRINT(SELVAL): Var_name="RecPmtRcvd";

NOTE 484-185: Format $PARTICTYPE was not found or could not be loaded.

NOTE: Line generated by the macro function "SCAN".

45 yesno

_____

2 The SAS System 09:50 Tuesday, June 12, 2018

484

MPRINT(SELVAL): Var_value=put(Var_name,yesno.);

NOTE 484-185: Format $YESNO was not found or could not be loaded.

46 output;

47 end;

48 run;

NOTE: There were 3316 observations read from the data set WORK.CJR_COMBINE.

NOTE: The data set WORK.TEMP1 has 793 observations and 3 variables.

NOTE: DATA statement used (Total process time):

real time 0.04 seconds

cpu time 0.04 seconds


 

Contributor
Posts: 23

Re: retrieve a numeric format stored in a macro variable

Thanks Reeza, I would prefer to use arrays, but run into trouble when I try to reference a format name using an array.

 

27 data _null_;

28 length var_name var_value $20;

29 array varvals{2} Partictype RecPmtRcvd;

30 array formvals{2} $ ('partictype.' 'yesno.');

31 set CJR_Combine(obs=1);

32 Var_name=varvals(1);

33 Var_value=put(varvals(1),formvals(1));

________

85

76

ERROR 85-322: Expecting a format name.

ERROR 76-322: Syntax error, statement will be ignored.

34 put Var_name= Var_value=;

35 run;

Super User
Super User
Posts: 7,933

Re: retrieve a numeric format stored in a macro variable

[ Edited ]

To use an expression to contain the format specification you need to use PUTN() or PUTC() functions instead of the PUT() function. So you need to know whether the variable is numeric (PUTN) or character (PUTC).

 

data want;
  set CJR_Combine(obs=1);
  array varvals(2) 8 Partictype RecPmtRcvd;
  array formvals(2) $20 _temporary_ ('partictype.' 'yesno.');
  length var_name var_value $32;
  do i=1 to dim(varvals);
    Var_name=varvals(1);
    Var_value=putn(varvals(1),formvals(1));
    output;
  end;
run;
Super User
Posts: 23,291

Re: retrieve a numeric format stored in a macro variable


@Batman wrote:

Thanks Reeza, I would prefer to use arrays, but run into trouble when I try to reference a format name using an array.

 

27 data _null_;

28 length var_name var_value $20;

29 array varvals{2} Partictype RecPmtRcvd;

30 array formvals{2} $ ('partictype.' 'yesno.');

31 set CJR_Combine(obs=1);

32 Var_name=varvals(1);

33 Var_value=put(varvals(1),formvals(1));

________

85

76

ERROR 85-322: Expecting a format name.

ERROR 76-322: Syntax error, statement will be ignored.

34 put Var_name= Var_value=;

35 run;


PUTC in this case instead.

Super User
Super User
Posts: 7,933

Re: retrieve a numeric format stored in a macro variable

Don't define a macro in the middle of data step (or for that matter in the middle of program).  Define the macro first and then use it where you want it to run. 

 

From the comments in your code you need to have an OUTPUT statement generated by the macro for each variable name.

%macro selval;
%do i=1 %to 2;
/*Assign the variable name to Var_name*/
Var_name="%scan(&varvals,&i)";
/*Assign its formatted value to Var_value*/
Var_value=put(Var_name,%scan(&formval,&i).);
/*Create an observation for each variable*/
output;
%end;
%mend;

Now you can call it in the middle of a data step to generate the assignment and output statements.

/*Store variable names*/
%let varvals=Partictype RecPmtRcvd;
/*Store their associated format names*/
%let formval=partictype yesno;

data temp1(keep=CJRorig Var_name Var_value);
  length var_name var_value $20;
  set CJR_Combine;
  if CJRorig=1 then do;
     %selval
  end;
run;

The error messages are complaining that the formats have not been defined. Make sure you create the YESNO and other formats before trying to use them in a PUT() function call.

 

Solution
a week ago
Super User
Posts: 13,321

Re: retrieve a numeric format stored in a macro variable

It is a poor idea to define a macro in the middle of a data step.

When you do this:

if CJRorig=1 then do;

36 /*Create an observation for each variable*/

37 %macro selval;

The behavior can be very problematic.

 

Note that MACROS do not access data step variables without a lot of extra work.

In

40 Var_name="%scan(&varvals,&i)";

41 /*Assign its formatted value to Var_value*/

42 Var_value=put(Var_name,%scan(&formval,&I).);

The data step variable VAR_NAME will always be character. So if you attempt to put the value with a numeric format you get that error.

 

You might try

 

Var_value=put(%scan(&varvals,&i),%scan(&formval,&i).);

But that will require having the variable referenced in your macro variable in the data set.

Note that if you have a format that uses decimals such as F8.2 your code will also yield unexpected resultsas it attempts to use format "F8." due to the . you have to terminate the scanned formval AND that . is a default delimiter to %scan. Which then means the value following the . is the next format to use.

 

To output multiple records from one you also need an OUTPUT statement inside the DO loop.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 78 views
  • 0 likes
  • 4 in conversation