BookmarkSubscribeRSS Feed
JP4
Calcite | Level 5 JP4
Calcite | Level 5

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,

6 REPLIES 6
ChrisNZ
Tourmaline | Level 20

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.

Kurt_Bremser
Super User

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.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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;

 

Kurt_Bremser
Super User

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.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

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...

Astounding
PROC Star

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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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
  • 1697 views
  • 2 likes
  • 5 in conversation