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

Hey all,

Below is a code that I inherited for analysis on survey data. After many attempts and adjustments, I am still getting an error message that I am unsure how to resolve. Please see attached data. Please assist. Thanks.

 

SAS Code:

%let var = qn8 qn9 qn10 qn13 qn15 qn16 qn17 qn18 qn22 qn23 qn24 qn25 qn26 qn27 qn28 qn29 qn31 qn32 qn33 qn34;

%macro tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);

%do i=1 %to %eval(%sysfunc(countc(&var., " "))+1);
%let var1=%scan(&var, &i);
%put var1;

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
table Virginia*&var1./cl(type=logit) cv row ;
strata stratum;
cluster psu;
weight weight;
ods output crosstabs=part.&var1.&cross1;
run;

data part.&var1.&cross1;
length F_Virginia $90 characteristic $195;
format rowpercent rowlowercl rowuppercl 8.1 frequency comma10.;
set part.&var1.&cross1;
characteristic='Total';
keep characteristic f_Virginia Virginia f_&var1. &var1. frequency rowpercent rowuppercl rowlowercl;
rename f_Virginia=level;
rename Virginia=levnum;
run;

data part.&var1.&cross1;
set part.&var1.&cross1;
if f_&var1.="Total" then delete;
run;

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
table sex* &var1./cl(type=logit) cv row ;
strata stratum;
cluster psu;
weight weight;
ods output crosstabs=part.&var1.&cross2;
run;

data part.&var1.&cross2;
length F_sex $90 characteristic $195;
format rowpercent rowlowercl rowuppercl frequency comma10.;
set part.&var1.&cross2;
characteristic='Sex';
keep characteristic f_sex sex f_&var1. &var1. frequency rowpercent rowuppercl rowlowercl;
rename f_sex=level;
rename sex=levnum;
run;

data part.&var1.&cross2;
set part.&var1.&cross2;
if f_&var1.="Total" then delete;
if level="Total" then delete;
run;

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
table raceeth2*&var1./ cl(type=logit) cv row ;
strata stratum;
cluster psu;
weight weight;
ods output crosstabs=part.&var1.&cross3;
run;

data part.&var1.&cross3;
length F_raceeth2 $90 characteristic $195;
format rowpercent rowlowercl rowuppercl frequency comma10.;
set part.&var1.&cross3;
characteristic='Race/Ethnicity';
keep characteristic f_raceeth2 raceeth2 f_&var1. &var1. frequency rowpercent rowuppercl rowlowercl;
rename f_raceeth2=level;
rename raceeth2=levnum;
run;

data part.&var1.&cross3;
set part.&var1.&cross3;
if f_&var1.="Total" then delete;
if level="Total" then delete;
run;

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
table age*&var1./cl (type=logit)cv row ;
strata stratum;
cluster psu;
weight weight;
ods output crosstabs=part.&var1.&cross4;
run;

data part.&var1.&cross4;
length F_age $90 characteristic $195;
format rowpercent rowlowercl rowuppercl frequency comma10.;
set part.&var1.&cross4;
characteristic='Age';
keep characteristic f_age age f_&var1. &var1. frequency rowpercent rowuppercl rowlowercl;
rename f_age=level;
rename age=levnum;
run;

data part.&var1.&cross4;
set part.&var1.&cross4;
if f_&var1.="Total" then delete;
if level="Total" then delete;
run;

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
table grade*&var1./cl (type=logit) cv row ;
strata stratum;
cluster psu;
weight weight;
ods output crosstabs=part.&var1.&cross5;
run;

data part.&var1.&cross5;
length F_grade $90 characteristic $195;
format rowpercent rowlowercl rowuppercl frequency comma10.;
set part.&var1.&cross5;
characteristic='Grade';
keep characteristic f_grade grade f_&var1. &var1. frequency rowpercent rowuppercl rowlowercl;
rename f_grade=level;
rename grade=levnum;
run;

data part.&var1.&cross5;
set part.&var1.&cross5;
if f_&var1.="Total" then delete;
if level="Total" then delete;
run;

data part.&var1.&col1;
retain &var1. characteristic level levnum frequency rowpercent rowlowercl rowuppercl;
set part.&var1.&cross1 - part.&var1.&cross5;
keep f_&var1. characteristic level levnum frequency rowpercent rowlowercl rowuppercl;
if f_&var1.='Yes' then output part.&var1.&col1;
run;

data part.&var1.&col2;
retain &var1. characteristic level levnum frequency rowpercent rowlowercl rowuppercl;
set part.&var1.&cross1 - part.&var1.&cross5;
keep f_&var1. characteristic level levnum frequency rowpercent rowlowercl rowuppercl;
if f_&var1.='No' then output part.&var1.&col2;
run;

data part.&var1.&col1;
set part.&var1.&col1;
ci&varseage=cat(' (',strip(put(rowlowercl,8.1)),' - ', strip(put(rowuppercl,8.1)),')');
keep characteristic level levnum frequency rowpercent ci&varseage /*rowstderr*/ rowlowercl rowuppercl;
rename frequency=f&varseage;
rename rowpercent=per&varseage;
rename rowlowercl=lowercl&varseage;
rename rowuppercl=uppercl&varseage;
run;

data part.&var1.&col2;
set part.&var1.&col2;
ci&varsesex=cat(' (',strip(put(rowlowercl,8.1)),' - ', strip(put(rowuppercl,8.1)),')');
keep characteristic level levnum frequency rowpercent ci&varsesex /*rowstderr*/ rowlowercl rowuppercl;
rename frequency=f&varsesex;
rename rowpercent=per&varsesex;
rename rowlowercl=lowercl&varsesex;
rename rowuppercl=uppercl&varsesex;
run;

proc sort data= part.&var1.&col1; by level; run;
proc sort data= part.&var1.&col2; by level; run;

data data.&var1.;
merge part.&var1.&col1 part.&var1.&col2;
by level;
level=cat(' ',level);
order=_N_;
run;

data data.&var1.;
set data.&var1.;
if characteristic='Total' then charnum=1;
else if characteristic='Sex' then charnum=2;
else if characteristic='Race/Ethnicity' then charnum=3;
else if characteristic='Age' then charnum=4;
else if characteristic='Grade' then charnum=5;
run;

proc sort data= data.&var1. out= data.&var1. ; by charnum levnum; run;

data data.&var1.;
set data.&var1.;
if f1=. then f1=0;
if f2=. then f2=0;
if per1=. then per1=0.0;
if per2=. then per2=0.0;
if per1=0.0 then ci1='(. - .)';
if per2=0.0 then ci2='(. - .)';
frequency1=f1+f2;
run;

data data.&var1.;
format frequency1 comma10.;
set data.&var1.;
run;

data data.&var1.;
set data.&var1.;
frequency=strip(put(frequency1, comma10.));
per1&varseage=strip(put(per&varseage, 8.1));
per1&varsesex=strip(put(per&varsesex, 8.1));
run;

%end;
%mend;

%tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, 1, col2, 2)

 

Error Message:

 

var1
ERROR: Variable CL not found.
ERROR: Variable CV not found.
ERROR: Variable ROW not found.
NOTE: Line generated by the macro variable "VAR1".
1 *
--
22
200
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

WARNING: Output 'crosstabs' was not created. Make sure that the output object name, label, or
path is spelled correctly. Also, verify that the appropriate procedure options are
used to produce the requested output object. For example, verify that the NOPRINT
option is not used.

ERROR 22-322: Syntax error, expecting one of the following: a name, ;, (, *, -, /, :, _ALL_,
_CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 200-322: The symbol is not recognized and will be ignored.


ERROR: File PART.CROSS1.DATA does not exist.

WARNING: The variable Virginia in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable f_ in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable Virginia in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set PART.CROSS1 may be incomplete. When this step was stopped there were 0
observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

 


NOTE: Variable f_ is uninitialized.
NOTE: There were 0 observations read from the data set PART.CROSS1.
NOTE: The data set PART.CROSS1 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds


NOTE 137-205: Line generated by the invoked macro "TOTTABLE".
643 rowlowercl; rename f_Virginia=level; rename Virginia=levnum; run; data
643 ! part.&var1.&cross1; set part.&var1.&cross1; if f_&var1.="Total" then delete; run;
643 ! proc surveyfreq data=yrbs.yrbs17_bot nomcar; table sex* &var1./cl cv
-
22
ERROR 22-322: Syntax error, expecting one of the following: a name, _ALL_, _CHARACTER_, _CHAR_,
_NUMERIC_.

ERROR: Variable NAME not found.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

WARNING: Output 'crosstabs' was not created. Make sure that the output object name, label, or
path is spelled correctly. Also, verify that the appropriate procedure options are
used to produce the requested output object. For example, verify that the NOPRINT
option is not used.


ERROR: File PART.CROSS2.DATA does not exist.

WARNING: The variable sex in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable f_ in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable sex in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set PART.CROSS2 may be incomplete. When this step was stopped there were 0
observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

 

NOTE: Variable f_ is uninitialized.
NOTE: There were 0 observations read from the data set PART.CROSS2.
NOTE: The data set PART.CROSS2 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds


NOTE: Line generated by the macro variable "VAR1".
1 *
-
22
200
ERROR: Variable CL not found.
ERROR: Variable CV not found.
ERROR: Variable ROW not found.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

WARNING: Output 'crosstabs' was not created. Make sure that the output object name, label, or
path is spelled correctly. Also, verify that the appropriate procedure options are
used to produce the requested output object. For example, verify that the NOPRINT
option is not used.

ERROR 22-322: Syntax error, expecting one of the following: a name, ;, (, *, -, /, :, _ALL_,
_CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 200-322: The symbol is not recognized and will be ignored.


ERROR: File PART.CROSS3.DATA does not exist.

WARNING: The variable raceeth2 in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable f_ in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable raceeth2 in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set PART.CROSS3 may be incomplete. When this step was stopped there were 0
observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

 


NOTE: Variable f_ is uninitialized.
NOTE: There were 0 observations read from the data set PART.CROSS3.
NOTE: The data set PART.CROSS3 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds


ERROR: Variable CL not found.
ERROR: Variable CV not found.
ERROR: Variable ROW not found.
NOTE: Line generated by the macro variable "VAR1".
1 *
-
22
200
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

WARNING: Output 'crosstabs' was not created. Make sure that the output object name, label, or
path is spelled correctly. Also, verify that the appropriate procedure options are
used to produce the requested output object. For example, verify that the NOPRINT
option is not used.

ERROR 22-322: Syntax error, expecting one of the following: a name, ;, (, *, -, /, :, _ALL_,
_CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 200-322: The symbol is not recognized and will be ignored.


ERROR: File PART.CROSS4.DATA does not exist.

WARNING: The variable age in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable f_ in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable age in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set PART.CROSS4 may be incomplete. When this step was stopped there were 0
observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds

 


NOTE: Variable f_ is uninitialized.
NOTE: There were 0 observations read from the data set PART.CROSS4.
NOTE: The data set PART.CROSS4 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds


ERROR: Variable CL not found.
ERROR: Variable CV not found.
ERROR: Variable ROW not found.
NOTE: Line generated by the macro variable "VAR1".
1 *
-
22
200
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

WARNING: Output 'crosstabs' was not created. Make sure that the output object name, label, or
path is spelled correctly. Also, verify that the appropriate procedure options are
used to produce the requested output object. For example, verify that the NOPRINT
option is not used.

ERROR 22-322: Syntax error, expecting one of the following: a name, ;, (, *, -, /, :, _ALL_,
_CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 200-322: The symbol is not recognized and will be ignored.


ERROR: File PART.CROSS5.DATA does not exist.

WARNING: The variable grade in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable f_ in the DROP, KEEP, or RENAME list has never been referenced.
WARNING: The variable grade in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set PART.CROSS5 may be incomplete. When this step was stopped there were 0
observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds

 


NOTE: Variable f_ is uninitialized.
NOTE: There were 0 observations read from the data set PART.CROSS5.
NOTE: The data set PART.CROSS5 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.03 seconds

 

NOTE: Variable levnum is uninitialized.
WARNING: The variable levnum in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: There were 0 observations read from the data set PART.CROSS1.
NOTE: There were 0 observations read from the data set PART.CROSS2.
NOTE: There were 0 observations read from the data set PART.CROSS3.
NOTE: There were 0 observations read from the data set PART.CROSS4.
NOTE: There were 0 observations read from the data set PART.CROSS5.
NOTE: The data set PART.COL1 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.03 seconds

 

NOTE: Variable levnum is uninitialized.
WARNING: The variable levnum in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: There were 0 observations read from the data set PART.CROSS1.
NOTE: There were 0 observations read from the data set PART.CROSS2.
NOTE: There were 0 observations read from the data set PART.CROSS3.
NOTE: There were 0 observations read from the data set PART.CROSS4.
NOTE: There were 0 observations read from the data set PART.CROSS5.
NOTE: The data set PART.COL2 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds

 

WARNING: The variable levnum in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: There were 0 observations read from the data set PART.COL1.
NOTE: The data set PART.COL1 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.01 seconds

 

WARNING: The variable levnum in the DROP, KEEP, or RENAME list has never been referenced.
NOTE: There were 0 observations read from the data set PART.COL2.
NOTE: The data set PART.COL2 has 0 observations and 7 variables.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.03 seconds

 

NOTE: Input data set is empty.
NOTE: The data set PART.COL1 has 0 observations and 7 variables.
NOTE: PROCEDURE SORT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

 

NOTE: Input data set is empty.
NOTE: The data set PART.COL2 has 0 observations and 7 variables.
NOTE: PROCEDURE SORT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds


NOTE: Line generated by the macro variable "VAR1".
1 data.
-----
22
201

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;,
_DATA_, _LAST_, _NULL_.

ERROR 201-322: The option is not recognized and will be ignored.

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.DATA16 may be incomplete. When this step was stopped there were 0
observations and 13 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.03 seconds

 

NOTE: Line generated by the macro variable "VAR1".
1 data.
-----
22
201
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;,
_DATA_, _LAST_, _NULL_.

ERROR 201-322: The option is not recognized and will be ignored.

NOTE: Line generated by the macro variable "VAR1".
1 data.
-----
22
201

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, ;, CUROBS,
END, INDSNAME, KEY, KEYRESET, KEYS, NOBS, OPEN, POINT, _DATA_, _LAST_, _NULL_.

ERROR 201-322: The option is not recognized and will be ignored.

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.DATA17 may be incomplete. When this step was stopped there were 0
observations and 14 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Why did you create a macro that has a parameter named VAR1 and then have the macro immediately overwrite the value passed to it?

Why does you macro write the four character string var1 to the log? How does that help?

%macro tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);

%do i=1 %to %eval(%sysfunc(countc(&var., " "))+1);
%let var1=%scan(&var, &i);
%put var1;

Why is the macro referencing the macro variable VAR at all? It is not an input parameter.  It is not listed in comments or code anywhere to indicate that it be used by this macro.  It is what I refer to as a magic macro variable that just appears out of nowhere in the middle of a program.

 

Perhaps you intended to define the top of the macro in this way?

%macro tottable(varlist, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);
%local i var1;
%do i=1 %to %sysfunc(countw(&varlist,%str( )));
  %let var1=%scan(&varlist, &i,%str( ));
  %put &=i &=var1;

View solution in original post

9 REPLIES 9
PaigeMiller
Diamond | Level 26

Add this line to the top of your code and run it again

 

options mprint symbolgen mlogic;

Then show us the relevant parts of the LOG, unedited, do not chop anything out, from about 50 lines above the error to maybe 10 lines after the error. When you do this, copy the LOG as text and paste it into the window that appears when you click on the {i} icon — do not skip this step!

--
Paige Miller
Tom
Super User Tom
Super User

Why did you create a macro that has a parameter named VAR1 and then have the macro immediately overwrite the value passed to it?

Why does you macro write the four character string var1 to the log? How does that help?

%macro tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);

%do i=1 %to %eval(%sysfunc(countc(&var., " "))+1);
%let var1=%scan(&var, &i);
%put var1;

Why is the macro referencing the macro variable VAR at all? It is not an input parameter.  It is not listed in comments or code anywhere to indicate that it be used by this macro.  It is what I refer to as a magic macro variable that just appears out of nowhere in the middle of a program.

 

Perhaps you intended to define the top of the macro in this way?

%macro tottable(varlist, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);
%local i var1;
%do i=1 %to %sysfunc(countw(&varlist,%str( )));
  %let var1=%scan(&varlist, &i,%str( ));
  %put &=i &=var1;
LuckySe7en
Calcite | Level 5

Hi Tom,

Thank you for responding Because I inherited this sas code, I am unsure why the macro is written in its current form.  VAR1 is supposed to represent the variables assigned to %LET = VAR (please see posted code above). The %put var serves no purpose, but again inherited not the creator.

%macro tottable(varlist, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);

%local i var1;

%do i=1 %to %sysfunc(countw(&varlist,%str( )));

  %let var1=%scan(&var, &i,%str( ));

  %put &=i &=var1;

New Macro:
%macro tottable(var1, cross1, cross2, cross3, cross4, cross5, col1, varseage, col2, varsesex);
	%local i var1;

	%do i=1 %to %sysfunc(countw(&var.,%str( )));
		%let var1=%scan(&var, &i,%str( ));
		%put i=&i var1=&var1;

 

After using your code, it work (awesome and thanks)…. However the program only recognized the first variable (qn8) assigned to the %LET = VAR and I need the macro to pick up all the variables from the survey.  Therefore, I changed the varlist in the %tottable to var1 and in the do loop syntax as well.

Lastly, the code works but I would like to better understanding of

  • %Local
  • Countw instead of countc
  • Why %eval was no longer usefully
  • What purpose did the +1 serve

I am in the beginning phase of using macros. Thanks again.

ballardw
Super User

@LuckySe7en wrote:

Hi Tom,

Thank you for responding Because I inherited this sas code, I am unsure why the macro is written in its current form.  

If the original code was old enough it may be because of a bug in Surveyfreq that didn't properly handle the tables for things like

var1  *(varx vary varz) or more complex examples.

 

I had some inconsistent errors when using the grouping syntax with Surveyfreq in one of the early releases with the survey procs. I didn't write any loopy code but did to bits with multiple calls to surveyfreq because of the behavior at that time.

Tom
Super User Tom
Super User

You can read up on the meaning of the statements and functions you don't understand in the documentation.  It is all on-line.

 

The reason you had to include +1 when using the COUNTC() function to count the number of times a space appeared in the list instead of using the COUNTW() function to count the number of items (words) in the list is because when you have a delimited list there is one less delimiter than the number of words the delimiters are separating.   Since you no longer need to do any integer arithmetic in the macro logic that means you don't have to wrap that arithmetic inside a %EVAL() function call to force the macro processor to treat the plus character as an addition operator instead of just another character.

 

The reason to use a %LOCAL statement is so you can use a macro variable inside the macro without worrying that assigning values to it will overwrite the value of an already existing macro variable with the same name.  This is critical if you use common names for macro variables, like I and VAR and VAR1, as those are much more likely to have already been used in your program.

 

The reason to %str( ) instead of " " in the calls to COUNTW() and %SCAN() is because the macro processor treats the quotes as part of the value. So instead of just use space as the delimiter it will treat either a space or a quote as a delimiter.  Might not matter with your current list of variable name, but if you used a name literal, like "XXXYYY"n, in your variable list then it would get parsed as two names instead of one.

 

Your code is including the typo  (now fixed) that I had in my answer as it is counting the number of variables in &VARLIST but then pulling the variable names from the value of  &VAR instead of &VARLIST.  If you want to pass the list of variables to the macro you should include the list in the CALL to the macro. Don't put the value in some macro variable, some magic macro variable, and just reference that macro variable in the middle of macro.   If it makes the code easier to read or if you need to use the same list of variables in multiple places in your code, you can put the value into a macro variable, but then reference that macro variable in the call to macro.  So you should follow the pattern below in writing your program. Note I have put ellipses where I have removed code so that you can concentrate on the parts of the code to see the pattern I am talking about.

%macro tottable(varlist, .....);
...
%let var1=%scan(&varlist,&i,%str( ));
...
%mend;
%let var=A B C D E ;
%tottable(varlist=&var, ....)
ballardw
Super User

A couple comments.

At the top of your macro you have a %put var1; which will ALWAYS have the text VAR1 in the log. Not particularly helpful as a diagnostic.

I would suggest instead:

%put i=&i var1=&var1;

which tells you which loop value and the name of the actual variable with something like:

i=1 var1=qn8

Second, Proc Surveyfreq will let you summarize multiple sets of variables with a single tables statement just like in Proc Freq. So you could quite likely reduce all of that looping and multiple calls to proc surveyfreq with:

proc surveyfreq data=yrbs.yrbs17_bot nomcar;
   table (Virginia sex raceeth2 age grade)* (&var.)/cl(type=logit) cv row ;
/* yes that is &var. NOT &var1. ^^^^^*/ strata stratum; cluster psu; weight weight; ods output crosstabs=part.&var1.&cross1; run;

I admit that this may create a somewhat different data set but all the info is there and you will have fewer issues with combining data sets. I didn't even try to figure out what all of your data steps may actually be attempting to accomplish but suspect that you may be trying to make a data set look like a report structure. Often that is lots of extra work let the report procedures play with such things.

 

You also repeatedly use a code structure that is moderately to seriously dangerouse when it comes to diagnosing problems of

data part.&var1.&cross1;
   set part.&var1.&cross1;

every time you use the output data set name as the input name you completely replace the source data. Which with macros and multiple data steps using the same dataset names you can have a very difficult time determining which step has any logic problems.

JeffMaggio
Obsidian | Level 7

Looking at this quickly, it looks like you are calling the macro with a bunch of parameters:

%tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, 1, col2, 2)

but the only one that I can see is defined by the time you call it is var1. 

Tom
Super User Tom
Super User

@JeffMaggio wrote:

Looking at this quickly, it looks like you are calling the macro with a bunch of parameters:

%tottable (var1, cross1, cross2, cross3, cross4, cross5, col1, 1, col2, 2)

but the only one that I can see is defined by the time you call it is var1. 


This is not quite right. The macro is defined to allow calling the macro with position based parameter values.

%macro tottable
(var1
,cross1
,cross2
,cross3
,cross4
,cross5
,col1
,varseage
,col2
,varsesex
);

So the call is the same as if it was it was called using this syntax:

%tottable
(var1=var1
,cross1=cross1
,cross2=cross2
,cross3=cross3
,cross4=cross4
,cross5=cross5
,col1=col1
,varseage=1
,col2=col2
,varsesex=2
);

The macro call does look a little strange, but perhaps the dataset that is being analyzes actually does have variables named VAR1, CROSS1 etc.

 

JeffMaggio
Obsidian | Level 7

True, but glancing at the rest of the macro, I figured it was pretty safe to assume that was not the intention.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 9 replies
  • 991 views
  • 3 likes
  • 5 in conversation