BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Thomasanderson
Fluorite | Level 6

I have a directory with a large number of csv files. I want to import some of them without writing a separate proc import for each, because that would be silly.

For arguments sake, let's say the files are named filename_ak.csv, filename_al.csv, filename_ct.csv.

 

A resource I found elsewhere suggested that the following macro would work;

 

%for(filename, values=filename_ak filename_al filename_ct, do=%nrstr(
PROC IMPORT
DATAFILE= "\\c:\datafiles\&filename.csv"
OUT=WORK.&filename
DBMS=CSV REPLACE;
RUN;
))

 

But I get error messages:

 

WARNING: Apparent invocation of macro FOR not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order.

 

I am running SAS 9.4 on X64_10PRO

 

Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You cannot call a macro if you haven't defined it to SAS first.

 

First submit the code that defines %FOR before submitting code that calls it.

 

But there is no need to use a macro to loop over a list of values. 

 

That is what a data step does already.

data _null_;
   length filename $256;
   do filename='filename_ak','filename_al','filename_ct';
      call execute(catx(' '
      ,'PROC IMPORT DATAFILE=',quote(cats('\\c:\datafiles\',filename,'.csv'))
      ,'OUT=',cats('WORK.',filename)
      ,'DBMS=CSV REPLACE;'
      ,'RUN;'
     ));
  end;
run;

WARNING: Using PROC IMPORT to read a series of CSV files that should have the exact same variables is a recipe for disaster.  PROC IMPORT will make DIFFERENT GUESSES about variable names, types, lengths and formats based on each file independently.  That will lead to datasets that are incompatible.  

 

Instead write your own data step to read the CSV file(s) and you will have full control over how the variables are defined.

View solution in original post

7 REPLIES 7
PaigeMiller
Diamond | Level 26
WARNING: Apparent invocation of macro FOR not resolved.

A macro has to be defined in the program (or included via %include, or included via autocall libraries, or some other way). You haven't done that. SAS doesn't know what macro %for is.

--
Paige Miller
Thomasanderson
Fluorite | Level 6
Thank you. I guess I have a lot to learn about macros.
Reeza
Super User

UCLA introductory tutorial on macro variables and macros
https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/

Tutorial on converting a working program to a macro
This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

Examples of common macro usage
https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

Tom
Super User Tom
Super User

You cannot call a macro if you haven't defined it to SAS first.

 

First submit the code that defines %FOR before submitting code that calls it.

 

But there is no need to use a macro to loop over a list of values. 

 

That is what a data step does already.

data _null_;
   length filename $256;
   do filename='filename_ak','filename_al','filename_ct';
      call execute(catx(' '
      ,'PROC IMPORT DATAFILE=',quote(cats('\\c:\datafiles\',filename,'.csv'))
      ,'OUT=',cats('WORK.',filename)
      ,'DBMS=CSV REPLACE;'
      ,'RUN;'
     ));
  end;
run;

WARNING: Using PROC IMPORT to read a series of CSV files that should have the exact same variables is a recipe for disaster.  PROC IMPORT will make DIFFERENT GUESSES about variable names, types, lengths and formats based on each file independently.  That will lead to datasets that are incompatible.  

 

Instead write your own data step to read the CSV file(s) and you will have full control over how the variables are defined.

Thomasanderson
Fluorite | Level 6

Thanks again for this

 

Can I use something like this to go through the datasets I have created and do some simple operations like "new_var = var1 + var 2;" and "keep new_var var3 var4;" ?

Kurt_Bremser
Super User

If these files have the same structure, and the data should end up in one dataset, do not use a macro and do not use PROC IMPORT.

Write a data step which either uses a wildcard in the INFILE statement or reads filenames from a dataset and uses the FILEVAR= option.

Reeza
Super User
If they all have the same layout and you have a data step import code you can read them all at once using the * in the filename as a wildcard character.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 7 replies
  • 957 views
  • 5 likes
  • 5 in conversation