Hello,
In SAS Base 9.4, I'd like to create n datasets based on n .txt files (player files) then add a variable into the datasets containing the name of the player. I currently use macro variables for the player name and the file path, but it creates tedious redundancy.
My code is :
%let player1 = Frank Anderson;
%let dir1 = /data/import217_anderson.txt;
%let player2 = Tom Wilson;
%let dir2 = /data/wilson_skj.txt;
%let player3 = Andrew Pelbigone;
%let dir3 = /data/pelbigone_fhz_rtf.txt;
data player1;
infile "&dir1" dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.
format last_game_date ddmmyy10.;
player="&player1";
run;
data player2;
infile "&dir2" dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.
format last_game_date ddmmyy10.;
player="&player2";
run;
data player3;
infile "&dir3" dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.
format last_game_date ddmmyy10.;
player="&player3";
run;
I would like to make the addition of extra players and paths smoother (not have to create a macro variable for each name AND path) and also reduce the size of the code needed to create data sets: while it's not tedious for 2-3 players, it's difficult for a longer player list. I guess you have to go through a macro/loop to create data sets and use some lists/arrays for the initial inputs but I'm not sure this is the optimal solution and how to implement it.
Optimally, I search a solution for an unknown n-number of .txt files and variable .txt files (the files have the same data structure but not the same name structure, ie one can be "player.txt" and the next one "import_123.txt"). The player names are known.
Thanks for your support !
Put all files with identical structure (and only those)in a directory, and use wildcards to read all files in one step. Use the filename= option to retrieve the name of the currently read file.
%macro player(player=,data=.out=);
data &out.;
infile "&data." dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.
format last_game_date ddmmyy10.;
player="&player.";
run;
%mend player;
%macro player(player=Frank Anderson,data=data/import217_anderson.txt,out=player1);
%macro player(player=Tom Wilson,data=/data/wilson_skj.txt,out=player2);
%macro player(player=Andrew Pelbigone,data=/data/pelbigone_fhz_rtf.txt,out=player3);
Thank you for your answer.
Unfortunately, it doesn't seem to be working. If I launch it once, the data sets are not created (no error in logs) and if I launch it again, log notes give this kind of message :
NOTE: The quoted string currently being processed has become more than 262 bytes long. You might have unbalanced quotation marks.
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
2 TITLE;
3 FOOTNOTE;
4 OPTIONS LOCALE=en_US DFLANG=LOCALE;
5 DATA _NULL_;
89 &GRAPHTERM; ;*';*";*/;RUN;QUIT;
_________________
49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space
between a quoted string and the succeeding identifier is recommended.
6 RUN;
7 OPTIONS VALIDVARNAME=ANY;
8 OPTIONS VALIDMEMNAME=EXTEND;
9 FILENAME _HTMLOUT TEMP;
10 FILENAME _RTFOUT TEMP ENCODING='UTF-8';
10 FILENAME _RTFOUT TEMP ENCODING='UTF-8'
_
49
10 ! ;
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space
between a quoted string and the succeeding identifier is recommended.
I tried with the following code too (I think that you made few typos l.1, l.4 and l.9) but the problem remains :
%macro player(player=,data=,out=);
data &out.;
infile "&data." dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.;
format last_game_date ddmmyy10.;
player="&player.";
run;
%mend player;
%macro player(player=Frank Anderson,data=/data/import217_anderson.txt,out=player1);
%macro player(player=Tom Wilson,data=/data/wilson_skj.txt,out=player2);
%macro player(player=Andrew Pelbigone,data=/data/pelbigone_fhz_rtf.txt,out=player3);
My (redundant and tedious) code had no problem creating datasets so the input shouldn't be the problem.
I solved the previous problem with the current code :
%macro player(play, dir, out);
data &out;
infile &dir dlm=';' dsd firstobs=2;
input stf :$50. rolb :$50. last_game_date :yymmdd.;
format last_game_date ddmmyy10.;
player=&play;
run;
%mend;
%player("Frank Anderson", "/data/import217_anderson.txt", Player1);
%player("Tom Wilson", "/data/wilson_skj.txt", Player2);
%player("Andrew Pelbigone", "/data/pelbigone_fhz_rtf.txt", Player3);
However, it still have some redundancy with the macro call (1 for each player). Can we make it smoother for n players ? It would be pretty tedious for 100 players and it won't solve one part of the initial problem: we don't know the starting player number (and the number of files to convert therefore).
Put all files with identical structure (and only those)in a directory, and use wildcards to read all files in one step. Use the filename= option to retrieve the name of the currently read file.
@Masande wrote:
Thank you for your answer.
Unfortunately, it doesn't seem to be working. If I launch it once, the data sets are not created (no error in logs) and if I launch it again, log notes give this kind of message :
NOTE: The quoted string currently being processed has become more than 262 bytes long. You might have unbalanced quotation marks. 1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK; 2 TITLE; 3 FOOTNOTE; 4 OPTIONS LOCALE=en_US DFLANG=LOCALE; 5 DATA _NULL_; 89 &GRAPHTERM; ;*';*";*/;RUN;QUIT; _________________ 49 NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space between a quoted string and the succeeding identifier is recommended. 6 RUN; 7 OPTIONS VALIDVARNAME=ANY; 8 OPTIONS VALIDMEMNAME=EXTEND; 9 FILENAME _HTMLOUT TEMP; 10 FILENAME _RTFOUT TEMP ENCODING='UTF-8'; 10 FILENAME _RTFOUT TEMP ENCODING='UTF-8' _ 49 10 ! ; NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space between a quoted string and the succeeding identifier is recommended.
I tried with the following code too (I think that you made few typos l.1, l.4 and l.9) but the problem remains :
%macro player(player=,data=,out=); data &out.; infile "&data." dlm=';' dsd firstobs=2; input stf :$50. rolb :$50. last_game_date :yymmdd.; format last_game_date ddmmyy10.; player="&player."; run; %mend player; %macro player(player=Frank Anderson,data=/data/import217_anderson.txt,out=player1); %macro player(player=Tom Wilson,data=/data/wilson_skj.txt,out=player2); %macro player(player=Andrew Pelbigone,data=/data/pelbigone_fhz_rtf.txt,out=player3);
My (redundant and tedious) code had no problem creating datasets so the input shouldn't be the problem.
Start a new session; you have unbalanced quotes from previous code.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.