libname in "C:\Users\kim_trevino1\Desktop\Advanced STATS 2020"; run;
*options symbolgen;
Data work.worddata2;
set in.gss7218_r3(Keep= Year ID marital wrkstat hrs1 age educ region sex race
rincome income occ10 prestg10 indus10 size worda wordB wordc wordd worde wordf wordg wordh wordi wordj wordsum wtssall);
Array worddata (10)$ worda --wordj; /*wordsum not included because 9 is a value and not missin*/
Do i= 1 to 10;
if worddata(i)in (9,-1)then worddata (i)=.;
/*Where year=1988*/
end;
run;
Proc freq data=work.worddata2;
Table year*worda--wordsum;
weight wtssall;
Run;
Data work.worddatamacro;
set work.worddata2;
run;
%macro wordscore(year);
proc sort data=work.worddatamacro; by year; run;
*read following data;
proc freq data=work.worddatamacro;
where year=&year.;
tables worda--wordsum;
title 'Word Score for &year.';
run;
%mend wordscore;
data worddata3; set work.worddatamacro;Run;
%wordscore(1988);
%macro wordscore (year);
%Do i=1974 %to 1984 %by 2; %wordscore(year=&i.) %end;
%Do i=1987 %to 1994 %by 1; %wordscore(year=&i.) %end;
%Do i=1996 %to 2000 %by 2; %wordscore(year=&i.) %end;
%Do i=2004 %to 2018 %by 2; %wordscore(year=&i.) %end;
%mend wordscore;
%wordscore;
Ods rtf close;
run;
This was an assignment I had from a few weeks ago that I don't think I did correctly. Part three looping macros is what is giving me trouble. Can someone tell me where I am going wrong?
We don't have your data sets, and I'm not going to go line by line through your code to figure out what you mean. You can't simply ask "where I am going wrong?", because we don't know what is wrong, and we need specific information about what you think (or what SAS thinks) is wrong.
Please run your code again with this line at the top
options mprint;
We need to see the LOG. We need to see the LOG properly formatted so we can read it. You do this by copying it as text and pasting it into the window that appears when you click on the </> icon. DO NOT SKIP THIS STEP. Otherwise, we get a badly formatted log which is of no use to us.
Lastly, I am somewhat annoyed at your professor, as repeating analyses over years is not really something you want to do with macros. Using a BY statement is a much simpler method. Teaching to do this via macros positively re-inforces bad practices.
Licensed to BAYLOR UNIVERSITY - SFA - T&R, Site 70092987. NOTE: This session is executing on the X64_10PRO platform. NOTE: Analytical products: SAS/STAT 15.1 SAS/ETS 15.1 SAS/IML 15.1 SAS/QC 15.1 NOTE: Additional host information: X64_10PRO WIN 10.0.18362 Workstation NOTE: SAS initialization used: real time 1.00 seconds cpu time 0.54 seconds 1 libname in "C:\Users\kim_trevino1\Desktop\Advanced STATS 2020"; NOTE: Libref IN was successfully assigned as follows: Engine: V9 Physical Name: C:\Users\kim_trevino1\Desktop\Advanced STATS 2020 1 ! run; 2 3 *options symbolgen; 4 options mprint; 5 Data work.worddata2; 6 set in.gss7218_r3(Keep= Year ID marital wrkstat hrs1 age educ region sex race 7 rincome income occ10 prestg10 indus10 size worda wordB wordc wordd worde wordf wordg wordh 7 ! wordi wordj wordsum wtssall); 8 9 Array worddata (10)$ worda --wordj; /*wordsum not included because 9 is a value and not 9 ! missin*/ 10 Do i= 1 to 10; 11 if worddata(i)in (9,-1)then worddata (i)=.; 12 /*Where year=1988*/ 13 end; 14 run; NOTE: There were 64814 observations read from the data set IN.GSS7218_R3. NOTE: The data set WORK.WORDDATA2 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 3.86 seconds cpu time 1.39 seconds 15 ibname in "C:\Users\kim_trevino1\Desktop\Advanced STATS 2020"; ------ 14 NOTE: Libref IN was successfully assigned as follows: Engine: V9 Physical Name: C:\Users\kim_trevino1\Desktop\Advanced STATS 2020 WARNING 14-169: Assuming the symbol LIBNAME was misspelled as ibname. 16 17 *options symbolgen; 18 options mprint; run; 19 Data work.worddata2; 20 set in.gss7218_r3(Keep= Year ID marital wrkstat hrs1 age educ region sex race 21 rincome income occ10 prestg10 indus10 size worda wordB wordc wordd worde wordf wordg wordh 21 ! wordi wordj wordsum wtssall); 22 23 Array worddata (10)$ worda --wordj; /*wordsum not included because 9 is a value and not 23 ! missin*/ 24 Do i= 1 to 10; 25 if worddata(i)in (9,-1)then worddata (i)=.; 26 /*Where year=1988*/ 27 end; 28 run; NOTE: There were 64814 observations read from the data set IN.GSS7218_R3. NOTE: The data set WORK.WORDDATA2 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 2.91 seconds cpu time 1.07 seconds 29 Proc freq data=work.worddata2; 30 Table year*worda--wordsum; 31 weight wtssall; 32 Run; NOTE: Writing HTML Body file: sashtml.htm NOTE: There were 64814 observations read from the data set WORK.WORDDATA2. NOTE: PROCEDURE FREQ used (Total process time): real time 1.09 seconds cpu time 0.68 seconds 33 34 Data work.worddatamacro; 35 set work.worddata2; 36 run; NOTE: There were 64814 observations read from the data set WORK.WORDDATA2. NOTE: The data set WORK.WORDDATAMACRO has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds 37 38 %macro wordscore(year); 39 proc sort data=work.worddatamacro; by year; run; 40 41 *read following data; 42 proc freq data=work.worddatamacro; 43 where year=&year.; 44 tables worda--wordsum; 45 title 'Word Score for &year.'; 46 run; 47 %mend wordscore; 48 49 data worddata3; set work.worddata2;Run; NOTE: There were 64814 observations read from the data set WORK.WORDDATA2. NOTE: The data set WORK.WORDDATA3 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 50 51 %wordscore(1988); MPRINT(WORDSCORE): proc sort data=work.worddatamacro; MPRINT(WORDSCORE): by year; MPRINT(WORDSCORE): run; NOTE: There were 64814 observations read from the data set WORK.WORDDATAMACRO. NOTE: The data set WORK.WORDDATAMACRO has 64814 observations and 29 variables. NOTE: PROCEDURE SORT used (Total process time): real time 0.03 seconds cpu time 0.03 seconds MPRINT(WORDSCORE): *read following data; MPRINT(WORDSCORE): proc freq data=work.worddatamacro; MPRINT(WORDSCORE): where year=1988; MPRINT(WORDSCORE): tables worda--wordsum; MPRINT(WORDSCORE): title 'Word Score for &year.'; MPRINT(WORDSCORE): run; NOTE: There were 1481 observations read from the data set WORK.WORDDATAMACRO. WHERE year=1988; NOTE: PROCEDURE FREQ used (Total process time): real time 0.05 seconds cpu time 0.03 seconds 52 Data work.worddatamacro2; 53 set work.worddata3; 54 run; NOTE: There were 64814 observations read from the data set WORK.WORDDATA3. NOTE: The data set WORK.WORDDATAMACRO2 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 55 %macro loopyear (year); 56 %Do i=1974 %to 1984 %by 2; %loopyear(year=&i.) %end; 57 %Do i=1987 %to 1994 %by 1; %loopyear(year=&i.) %end; 58 %Do i=1996 %to 2018 %by 2; %loopyear(year=&i.) %end; 59 run; 60 61 %mend loopyear; 62 data worddata4; set work.worddatamacro2;Run; NOTE: There were 64814 observations read from the data set WORK.WORDDATAMACRO2. NOTE: The data set WORK.WORDDATA4 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 63 %loopyear (year);
So after this step, part three of the assignment, it does nothing. It just spins its wheels for eternity.
The data set is the GSS, if that helps, and I'm using his notes and the little sas book to code.
Thank you, Paige, for helping me. I was a little intimidated, reaching out for help. The assignment is over, but I want to make sure I understand how to code a macro correctly. I will be analyzing panel data soon, so it is useful to know that this might not be the best way. Do you mind explaining why macros are inappropriate for this task or pointing me in the direction of a good resource?
Thank you again.
As I explained, if you want perform the same analysis on each year, virtually every SAS PROC has a BY statement which eliminates the need for macro loops. You use BY YEAR; in the PROC.
Okay, thank you.
This part of the code does not look right.
55 %macro loopyear (year); 56 %Do i=1974 %to 1984 %by 2; %loopyear(year=&i.) %end; 57 %Do i=1987 %to 1994 %by 1; %loopyear(year=&i.) %end; 58 %Do i=1996 %to 2018 %by 2; %loopyear(year=&i.) %end; 59 run; 60 61 %mend loopyear; 62 data worddata4; set work.worddatamacro2;Run; NOTE: There were 64814 observations read from the data set WORK.WORDDATAMACRO2. NOTE: The data set WORK.WORDDATA4 has 64814 observations and 29 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 63 %loopyear (year);
First you defined the macro LOOPYEAR to take parameter named YEAR, and when you called it you assigned the YEAR parameter the text string year instead of a real value. But since the macro is not using the YEAR parameter in any way that actually doesn't matter.
Second you are calling your same macro LOOPYEAR recursively. So it will keep calling itself until SAS runs out of memory. You need to change the calls to LOOPYEAR inside the definition of the macro LOOPYEAR to call the macro WORDSCORE.
Why do you have two definitions for the same macro? That way lies madness as you may not know which version is running.
Defining a macro and calling the same macro inside the macro also seems like a descent into madness would follow.
%macro wordscore (year); %Do i=1974 %to 1984 %by 2; %wordscore(year=&i.) %end; %Do i=1987 %to 1994 %by 1; %wordscore(year=&i.) %end; %Do i=1996 %to 2000 %by 2; %wordscore(year=&i.) %end; %Do i=2004 %to 2018 %by 2; %wordscore(year=&i.) %end; %mend wordscore;
Thank you, Ballardw. The TA helped me write this. I wish I could explain why, but I wasn't aware the texts was defining the same macro twice.
Could you instruct me on how to write this better?
%Do i=1974 %to 1984 %by 2; %end;
Is the text above all I need?
The professors question and hint are as clear as mud.
You need two macros. One that works for one specific year.
Then a second one that has the %DO loop and then calls the first one.
You seemed to create the first one, but then instead of making a second one you replaced the first one.
%macro one_year(year);
.... put actual code here ...
%mend ;
%macro mutliple_years(start,end,increment);
%local year;
%do year=&start %to &end %by &increment;
%one_year(&year)
%end;
%mend multiple_years;
Thank you, Tom. I will try this and get back to you. The problem with learning a new language (SAS) is that I know I have questions, but I'm not sure how to ask them clearly. I'm left asking, "How do I make the thing work?"hahaha.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.