BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Batman
Quartz | Level 8

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

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

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

6 REPLIES 6
Reeza
Super User

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


 

Batman
Quartz | Level 8

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;

Tom
Super User Tom
Super User

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;
Reeza
Super User

@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.

Tom
Super User Tom
Super User

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.

 

ballardw
Super User

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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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