Hello,
I am trying to read many raw time series data using MACRO. The filename consist of common string and year. (e.g: AA09.txt for 2009). Because the strucure of the raw data is different acroos years, I have to use IF statement as follows:
%MACRO READDATA (startyear,endyear);
%DO IYEAR = &startyr %TO &endyr;
%LET FYEAR = %SUBSTR(&IYEAR,3,2);
%LET FILE = "c:\raw\aa&FYEAR..txt";
DATA AA;
IF &IYEAR<=1970 THEN DO;
INFILE &FILE LRECL=4576;
INPUT ...
END;
IF 1970<&IYEAR<=1990 THEN DO;
INFILE &FILE LRECL=6767;
INPUT ...
END;
IF &IYEAR>1990 THEN DO;
INFILE &FILE LRECL=6767;
INPUT ...
END;
RUN;
%End;
%MEND;
%READDATA(1960,2010);
When I run this code, I got an error as follows:
DATA AA; IF &IYEAR<=1970 THEN DO; INFILE &FILE
--
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
Can you please let me know why IF statement is wrong and how I can fix it?
Best,
The program you provided is fine.
Something else must be happening in your actual program.
The error message suggests you use macro quoting.
Also you may consider using the filevar= option and avoid using macros altogether.
I'd rather structure the macro like that:
%macro readdata (startyear,endyear);
%do iyear= &startyr %to &endyr;
%let fyear = %substr(&iyear,3,2);
%let file = "c:\raw\aa&fyear..txt";
data aa&Iyear;
%if &iyear <= 1970 %then %do;
infile &file lrecl=4576;
input ...
%end;
%else %if &iyear <= 1990 %then %do;
infile &file lrecl=6767;
input ...
%end;
%else %do;
infile &file lrecl=6767;
input ...
%end;
run;
%end;
%mend;
%readdata(1960,2010);
That way only one infile and input statement is generated as data step code. And the output dataset is not overwritten with each macro iteration.
Why do you need a macro for that? Put your files in a directory and then run:
data want; length ...; infile "<path to files>\*.txt" lrecl=32767; input ...; run;
The variable lrecl lets me suspect that there will also be different record structures, so at least the input statement will have to be conditional. Including the infile statement in the same conditional block does make some sense in terms of understandability, IMO.
Yes, I would assume so as well. If the OP can show his data import agreement for each file type then further code can be shown. If the files are different formats, then why bother trying to make a macro, from the data import agreement the structure will be given and hence can be copied directly into code,. less work, robust process.
Of course if he has no import agreement/specifications...
It's at least worth mentioning that your macro parameters are named &STARTYEAR and &ENDYEAR. So your loop should read slightly differently:
%do IYEAR = &startyear %TO &endyear;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.