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.
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.
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.
I tried that and it resolves to nothing. What could be wrong?
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.
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.
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).
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.
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!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: