Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using %PUT to correctly format the dynamic file name

Tags:

sas

I have a SAS script that reads in a CSV file and stores it in a SAS data set:

LIBNAME IN '\\path\Data';
FILENAME CSV '\\path\Data\DT.csv';

DATA IN.DT;
  INFILE CSV DLM=',' DSD FIRSTOBS=1;
  INPUT KEY VALUE1 VALUE2;
RUN;

I want to change it such that instead of expecting the input to be named DT.csv, it would accept an input named DT-2016-03-03-TEST.csv, or whatever the current date is. In other words, I need to use a dynamic value in my FILENAME statement.

Here is what I have so far:

%LET curday   = %SYSFUNC(day("&sysdate"d));
%LET curmonth = %SYSFUNC(month("&sysdate"d));
%LET curyear  = %SYSFUNC(year("&sysdate"d));

%PUT %SYSFUNC(PUTN(&curday, z2.));

FILENAME CSV "\\path\Data\DT-&curyear-&curmonth-&curday-TEST.csv";

But the string it generates is like Data\DT-2016-3-3-TEST.csv rather than Data\DT-2016-03-03-TEST.csv

In other words, the trailing zeros are not there. What am I doing incorrectly?

like image 543
Merik Avatar asked Dec 16 '25 14:12

Merik


2 Answers

You'll need to use either a macro variable or a big group of macro functions (whichever you'd like). We'll go with creating macro variables for readability purposes. Based upon what you've said, we know a few things about the pattern:

  1. It starts with DT-
  2. It has today's date in a yyyy-mm-dd format
  3. It ends in .csv

Two of these are static values, and one needs to be dynamic in a specific format. Let's get crackin'.

Start off by storing the path in its own macro variable. This makes the code more generalizable to other applications (i.e. you can copy/paste old code for new programs! It's good to be lazy in the programming world).

%let path = \\path\data;

Next, let's build our dynamic pattern using a %let statement. We know it starts with DT-:

___________________________________________

%let file = DT-

___________________________________________

We can now cross #1 off the list! Let's knock out #2.

Two functions will help us get this in the order that we want:

  1. %sysfunc()
  2. today()

We'll encapsulate today() with %sysfunc(). %sysfunc() lets us run most non-macro-language SAS functions, and also has the added benefit of returning the value in a format that you desire using an additional argument. This is really helpful for us here.

So, let's grab today's date as a numeric SAS date, then convert it to yymmddx10 format, where x is some delimiter keyword. We'll use yymmddd10. - that is, a format that specifies yyyy-mm-dd. The extra d means dash.

___________________________________________

%let file = DT-%sysfunc(today(), yymmddd10.)

___________________________________________

2 is now out of the way. Hard part's over! All we need to do is append .csv to it, and we'll be all set.

___________________________________________

%let file = DT-%sysfunc(today(), yymmddd10.).csv;

___________________________________________

You can confirm the macro variable file's value with a %put statement:

%put NOTE: This is my filename: &file;

You should see in green text in the log NOTE: This is my filename: DT-2016-03-03.csv

Now, we'll just put it all together:

%let path = \\path\data;
%let file = DT-%sysfunc(today(), yymmddd10.).csv;

libname IN "&path";
filename CSV "&path\&file";

data in.DT;
    infile csv dlm=',' dsd firstobs=1;
    input key value1 value2;
run;

You've now got a dynamic way to read in these CSVs, and you can adapt this code elsewhere. Awesomesauce. I think you've earned yourself a celebratory coffee, and maybe a biscotti or two; don't go too crazy.

like image 83
Stu Sztukowski Avatar answered Dec 19 '25 07:12

Stu Sztukowski


Stu's answer is absolutely correct. For the tl;dr version.

%put echos stuff to the log. All you are doing is "putting" the result of %SYSFUNC(PUTN(&curday, z2.)) to the log. You are not updating the value in &curday.

Try

%LET curday = %SYSFUNC(PUTN(&curday, z2.));

Do that for the other curmonth, too.

Take the time and read Stu's answer.

like image 34
DomPazz Avatar answered Dec 19 '25 05:12

DomPazz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!