I want to produce these outputs for the 5 levels of a LEVELS variable (BY statement does not work for the next steps I have in my macro). I tried a %do statement by that was not working. May you please help me with this? Thanks
%macro do_sf(varname,levels);
%do i = 1 %to 5;
proc surveyfreq data = have VARHEADER = NAMELABEL nosummary;
tables &varname /cl nofreq nostd;
WHERE &levels =&i;
weight weight_var;
run;
%end;
%mend;
%do_sf(coffee_cons_level,city);
So the variable city has values from 1 to 5?
Please post your log.
Thank you, KurtBremser. Yes, the variable city has five levels from 1 to 5. My log repeats the following 5 times.
NOTE: The input data set is subset by WHERE, OBS, or FIRSTOBS. This provides a completely separate analysis of the subset. It does not provide a statistically valid subpopulation or domain analysis, where the total number of units in the subpopulation is not known with certainty. If you want a domain analysis, you should include the domain variables in the TABLES request.
NOTE: PROCEDURE SURVEYFREQ used (Total process time):
real time 0.02 seconds
cpu time 0.00 seconds
That is not the complete log. It doesn't show anything about how many observations were used or other bits expected. You should also set OPTIONS MPRINT; before running the macro to see what is generated and get notes in context to more details.
Does your variable City actually have numeric values 1, 2, 3, 4 and 5? That is what you are asking for
with
WHERE &levels =&i;
If City is character you need quotes around the value such as: &levels= "&i." ;
Suggestion: Add your &levels variable to the TABLES statement, drop the whole bit of looping in a macro and use ODS OUTPUT to place all the desired output into a data set.
You could use (without a macro) to get analysis of these combinations.
proc surveyfreq data = have VARHEADER = NAMELABEL nosummary;
tables coffee_cons_level * city /cl nofreq nostd;
WHERE city in (1:5);/* if city is a numeric variable*/
/* Where city in ('1' '2' '3' '4' '5'); if city is character*/
weight weight_var;
run;
If you have multiple variables you need to do such with the tables statement will accept syntax like
tables (a b c) *(x y z) .
Which will create output for a*x a*y a*z b*x b*y b*z c*x c*y c*z (nine tables in this case). Placing the output into a data set allows for later report writing or selecting the desired records for detailed examination.
So any looping or the macro may not be needed at all.
If your data set is of any significant size this sort of loop requires reloading the data set an may cause a serious performance issue, especially when you start calling it with multiple combinations of different variables.
Now:
"Not working" is awful vague.
Are there errors in the log?: Post the code and log in a code box opened with the "<>" to maintain formatting of error messages.
No output? Post any log in a code box.
Unexpected output? Provide input data in the form of data step code pasted into a code box, the actual results and the expected results. Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the "</>" icon or attached as text to show exactly what you have and that we can test code against.
Shouldn't you use DOMAIN analysis instead?
https://documentation.sas.com/doc/en/statug/15.2/statug_surveyfreq_details06.htm
Perhaps something like:
%macro do_sf(varname,levels);
proc surveyfreq data = have VARHEADER = NAMELABEL nosummary;
tables &levels*&varname /cl nofreq nostd domain=row;
weight weight_var;
run;
%mend;
%do_sf(coffee_cons_level,city);
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.
Ready to level-up your skills? Choose your own adventure.