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

Hi all,

I am having a problem looping through a list for class statement in the proc surveylogistic step.  The code is below

%let catclass = agegrp(ref="40-49") raceth(ref="NH White") maritals(ref="Married") educat(ref="Some College/College Grad")
wrkstat(ref="Employed") income(ref=">= $50,000") insure(ref="No") hlthcost(ref="No") doctor(ref="No")
hltstat(ref="Excellent/Very Good"); %macro ccls(); %do i = 1 %to %sysfunc(countw(&catclass)); %let logref = %scan(&catclass,&i); %end; %mend; %ccls;

When I loop through it, I get this error (see below).


MLOGIC(REF): Beginning execution.
SYMBOLGEN: Macro variable CATCLASS resolves to
agegrp(ref="40-49") raceth(ref="NH White")
maritals(ref="Married")
educat(ref="Some College/College Grad")
wrkstat(ref="Employed") income(ref=">=
$50,000") insure(ref="No") hlthcost(ref="No")
doctor(ref="No") hltstat(ref="Excellent/Very
Good")
MLOGIC(REF): %DO loop beginning; index variable I; start value
is 1; stop value is 29; by value is 1.
MLOGIC(REF): %LET (variable name is LOGREF)
SYMBOLGEN: Macro variable CATCLASS resolves to
agegrp(ref="40-49") raceth(ref="NH White")
maritals(ref="Married")
educat(ref="Some College/College Grad")
wrkstat(ref="Employed") income(ref=">=
$50,000") insure(ref="No") hlthcost(ref="No")
doctor(ref="No") hltstat(ref="Excellent/Very
Good")
SYMBOLGEN: Macro variable I resolves to 1
MLOGIC(REF): %DO loop index variable I is now 2; loop will
iterate again.
MLOGIC(REF): %LET (variable name is LOGREF)
SYMBOLGEN: Macro variable CATCLASS resolves to
agegrp(ref="40-49") raceth(ref="NH White")
maritals(ref="Married")
educat(ref="Some College/College Grad")
wrkstat(ref="Employed") income(ref=">=
$50,000") insure(ref="No") hlthcost(ref="No")
doctor(ref="No") hltstat(ref="Excellent/Very
Good")
SYMBOLGEN: Macro variable I resolves to 2
ERROR: Literal contains unmatched quote.
ERROR: The macro REF will stop executing.
MLOGIC(REF): Ending execution.

 

Additionally, when I try it another way, I get another error. Code is below and error is after that

%let ref = "40-49" "NH White" "Married" "Some College/College Grad" "Employed" ">= $50,000" "No" "No" "No" "Excellent/Very Good";

%macro ref();
%do i = 1 %to %sysfunc(countw(&ref));
    %let logref = %scan(&ref,&i);
%end;
%mend;
%ref;

MLOGIC(REF): Beginning execution.
SYMBOLGEN: Macro variable REF resolves to "40-49" "NH White"
"Married" "Some College/College Grad" "Employed"
">= $50,000" "No" "No" "No" "Excellent/Very
Good"
MLOGIC(REF): %DO loop beginning; index variable I; start value
is 1; stop value is 19; by value is 1.
MLOGIC(REF): %LET (variable name is LOGREF)
SYMBOLGEN: Macro variable REF resolves to "40-49" "NH White"
"Married" "Some College/College Grad" "Employed"
">= $50,000" "No" "No" "No" "Excellent/Very
Good"
SYMBOLGEN: Macro variable I resolves to 1
ERROR: Literal contains unmatched quote.
ERROR: The macro REF will stop executing.
MLOGIC(REF): Ending execution.

 

How do I figure this out?

 

Thanks for the help.

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

It depends on your code. The macros in your initial post overwrite the value of macro variable logref again and again with different substrings of &catclass or &ref, respectively. Therefore I assumed that these are only simplified code examples and that your real macros use those substrings in a more sensible way. To test my code I added a %PUT statement to the %DO loop:

%let catclass = agegrp(ref="40-49") raceth(ref="NH White") maritals(ref="Married") educat(ref="Some College/College Grad")                wrkstat(ref="Employed")  income(ref=">= $50,000") insure(ref="No") hlthcost(ref="No")  doctor(ref="No")                 hltstat(ref="Excellent/Very Good");

%macro test;
%do i = 1 %to %sysfunc(countw(&catclass,%str( ),q));
  %let logref = %scan(&catclass,&i,%str( ),q);
  %put &i  &logref;
%end;
%mend;
%test

Result in the log:

1  agegrp(ref="40-49")
2  raceth(ref="NH White")
3  maritals(ref="Married")
4  educat(ref="Some College/College Grad")
5  wrkstat(ref="Employed")
6  income(ref=">= $50,000")
7  insure(ref="No")
8  hlthcost(ref="No")
9  doctor(ref="No")
10  hltstat(ref="Excellent/Very Good")

If you want to obtain different substrings (e.g., first agegrp, then (ref="40-49"), etc.), please let me know.

View solution in original post

6 REPLIES 6
FreelanceReinh
Jade | Level 19

Hi @sas_apprenant,

 

I guess you want to use blanks as delimiters, unless they belong to a substring in quotation marks. In this case you should add two more arguments to both the COUNTW function and the %SCAN function:

%sysfunc(countw(&catclass,%str( ),q))
%scan(&catclass,&i,%str( ),q)

Otherwise, the embedded blanks and other characters ("default delimiters") would be treated as delimiters.

sas_apprenant
Fluorite | Level 6

I tried that and it resolves to nothing. What could be wrong?

FreelanceReinh
Jade | Level 19

It depends on your code. The macros in your initial post overwrite the value of macro variable logref again and again with different substrings of &catclass or &ref, respectively. Therefore I assumed that these are only simplified code examples and that your real macros use those substrings in a more sensible way. To test my code I added a %PUT statement to the %DO loop:

%let catclass = agegrp(ref="40-49") raceth(ref="NH White") maritals(ref="Married") educat(ref="Some College/College Grad")                wrkstat(ref="Employed")  income(ref=">= $50,000") insure(ref="No") hlthcost(ref="No")  doctor(ref="No")                 hltstat(ref="Excellent/Very Good");

%macro test;
%do i = 1 %to %sysfunc(countw(&catclass,%str( ),q));
  %let logref = %scan(&catclass,&i,%str( ),q);
  %put &i  &logref;
%end;
%mend;
%test

Result in the log:

1  agegrp(ref="40-49")
2  raceth(ref="NH White")
3  maritals(ref="Married")
4  educat(ref="Some College/College Grad")
5  wrkstat(ref="Employed")
6  income(ref=">= $50,000")
7  insure(ref="No")
8  hlthcost(ref="No")
9  doctor(ref="No")
10  hltstat(ref="Excellent/Very Good")

If you want to obtain different substrings (e.g., first agegrp, then (ref="40-49"), etc.), please let me know.

sas_apprenant
Fluorite | Level 6

Can you show me how one would go about doing this (If you want to obtain different substrings (e.g., first agegrp, then (ref="40-49"), etc.), please let me know.)? I would like to learn.

Thank you.

FreelanceReinh
Jade | Level 19

You could split the value of logref further, e.g., using the %SCAN, %SUBSTR and %INDEX functions:

%macro test2;
%do i = 1 %to %sysfunc(countw(&catclass,%str( ),q));
  %let logref = %scan(&catclass,&i,%str( ),q);
  %let varname = %scan(&logref,1,%str(%());
  %let refopt = %substr(&logref,%index(&logref,%str(%()));
  %put &i  &=logref  &=varname  &=refopt;
%end;
%mend;
%test2

The unmatched parentheses require an extra percent sign (see documentation of %STR and %NRSTR functions).

Tom
Super User Tom
Super User

Just split the original on space and the substring on parentheses.

%let catclass = agegrp(ref="40-49") raceth(ref="NH White") maritals(ref="Married") educat(ref="Some College/College Grad")                wrkstat(ref="Employed")  income(ref=">= $50,000") insure(ref="No") hlthcost(ref="No")  doctor(ref="No")

%macro test(list);
%local i var ref ;
%do i = 1 %to %sysfunc(countw(&list,%str( ),q));
  %let var = %scan(&catclass,&i,%str( ),q);
  %let ref = %scan(&var,2,());
  %let var = %scan(&var,1,());
  %put &=i &=var &=ref;
%end;
%mend;

Results:

36   %test(&catclass);
I=1 VAR=agegrp REF=ref="40-49"
I=2 VAR=raceth REF=ref="NH White"
I=3 VAR=maritals REF=ref="Married"
I=4 VAR=educat REF=ref="Some College/College Grad"
I=5 VAR=wrkstat REF=ref="Employed"
I=6 VAR=income REF=ref=">= $50,000"
I=7 VAR=insure REF=ref="No"
I=8 VAR=hlthcost REF=ref="No"
I=9 VAR=doctor REF=ref="No"
I=10 VAR=hltstat REF=ref="Excellent/Very Good"

You can add the parentheses back again if you want.  Or do another %SCAN() call to remove the REF= part.   You could even add a %QSYSFUNC(DEQUOTE()) call to remove the quotes.

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1519 views
  • 0 likes
  • 3 in conversation