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.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 805 views
  • 0 likes
  • 3 in conversation