SAS trick: get the LIBNAME statement to create folders for you

41

When I work on SAS projects that create lots of files as results, it's often a requirement that those files be organized in a certain folder structure. The exact structure depends on the project, but here's an example:

/results
   |__ html
       |__ images
   |__ xls
   |__ data

Before you can have SAS populate these file folders, the folders have to actually exist. Traditionally, SAS programmers have handled this by doing one of the following:

  • Simply require that the folders exist before you run through the project. (This is the SEP method: Somebody Else's Problem.)
  • Use SAS statements and shell commands (via SYSTASK or other method) to create the folders as needed. The SAS-related archives are full of examples of this. It can get complex when you have to account for operating system differences, and whether operating system commands are even permitted (NOXCMD system option).

In SAS 9.3 there is a new system option that simplifies this: DLCREATEDIR. When this option is in effect, a LIBNAME statement that points to a non-existent folder will take matters into its own hands and create that folder.

Here's a simple example, along with the log messages:

options dlcreatedir;
libname newdir "/u/sascrh/brand_new_folder";

NOTE: Library NEWDIR was created.
NOTE: Libref NEWDIR was successfully assigned as follows: 
      Engine:        V9 
      Physical Name: /u/sascrh/brand_new_folder

You might be thinking, "Hey, SAS libraries are for data, not for other junk like ODS results." Listen: we've just tricked the LIBNAME statement into making a folder for you -- you can use it for whatever you want. I won't tell.

In order to create a series of nested folders, you'll have to create each folder level in top-down order. For example, if you need a "results" and a "results/images" folder, you can do this:

%let outdir=%sysfunc(getoption(work));
/* create a results folder in the WORK area, with images subfolder */
options dlcreatedir;
libname res "&outdir./results";
libname img "&outdir./results/images";
/* clear the librefs - don't need them */
libname res clear;
libname img clear;

Or (and this is a neat trick) you can use a single concatenated LIBNAME statement to do the job:

libname res ("&outdir./results", "&outdir./results/images");
libname res clear;

NOTE: Libref RES was successfully assigned as follows: 
      Levels:           2
      Engine(1):        V9 
      Physical Name(1): /saswork/SAS_workC1960000554D_gsf0/results
      Engine(2):        V9 
      Physical Name(2): /saswork/SAS_workC1960000554D_gsf0/results/images

If you feel that folder creation is best left to the card-carrying professionals, don't worry! It is possible for a SAS admin to restrict use of the DLCREATEDIR option. That means that an admin can set the option (perhaps to NODLCREATEDIR to prohibit willy-nilly folder-making) and prevent end users from changing it. Just let them try, and they'll see:

13         options dlcreatedir;
                   ___________
                   36
WARNING 36-12: SAS option DLCREATEDIR is restricted by your Site 
Administrator and cannot be updated.

That's right -- DENIED! Mordac the Preventer would be proud. Job security: achieved!

Exact documentation for how to establish Restricted Options can be a challenge to find. You'll find it within the Configuration Guides for each platform in the Install Center. Here are quick links for SAS 9.3: Windows x64, Windows x86, and UNIX.

Share

About Author

Chris Hemedinger

Director, SAS User Engagement

+Chris Hemedinger is the Director of SAS User Engagement, which includes our SAS Communities and SAS User Groups. Since 1993, Chris has worked for SAS as an author, a software developer, an R&D manager and a consultant. Inexplicably, Chris is still coasting on the limited fame he earned as an author of SAS For Dummies

41 Comments

  1. As I was reading your blog post I was thinking, this may create some unorganized chaos in a production environment, potentially causing some angst for SAS Administrators. However you nicely covered that too. Great post!

  2. Bruno Mueller on

    To create directories there is is also the DCREATE function.

    The DLCREATEDIR option is a welcome addtion, as I get this question many times whether the LIBNAME statement will create the directories it needs.

    As always very good information

  3. Pingback: Using SAS and ODS PACKAGE to create ZIP files - The SAS Dummy

  4. While I was looking for the syntax for DCREATE, I ran into this blog. What a great new option!!! I'm also the site administrator and decided to stick with the vanilla install, which had the option set to nodlcreatedir.

    I tweaked my SAS script to turn on the option. I will only share with the more advanced programmers. I agree with Michelle it could be a mess.

    Thanks for the write-up.

  5. I was searching for this option and your blog came up, great tip. The documentation states that you can use this option on a libname statement but I can't get it to work (invalid option)...

    Anyway, I don't know if I should get this tip out to my users, because if they make a typo in there existing directory, that directory will be created...

    • Chris Hemedinger
      Chris Hemedinger on

      Ah, the burden of being a SAS admin! You can control this per-user via the restricted option mechanism, by seeding user-specific config folders. So give the option to the people you trust!

  6. Hi Experts,
    I have query regarding SAS catalog folder. I have created library (say jags), in this library I have created another catalog folder (say jagdish). Now i want to save my .sas files in catalog folder (i.e. jags\jagdish)
    Can you provide me code for this?

  7. Joel Stumpf on

    Just wanted say thanks, this post was very helpful! Your blog has saved me from opening many tracks with SAS over the last several years.

    • Chris Hemedinger
      Chris Hemedinger on

      Joel - you're welcome! Thanks for the kind words. I'm glad these are helpful to you.

  8. Paul Reynolds on

    I love this capability. However, it seems like it has a lower limitation on the character length of the path than just the libname function itself. It won't create a folder if the path is over a certain length, but if the folder already exists the libname will work fine. Any ideas? Thank you for any help.

    • Chris Hemedinger
      Chris Hemedinger on

      Paul, I'm not sure why that is. Have you tried using the DCREATE function for the longer path values to see if you can get that to work?

      • Paul Reynolds on

        DCREATE seems to work fine for the longer path names. The dlcreatedir works fine too until the path gets too long. Thanks.

        • Paul Reynolds on

          After re-reading your post for the 20 time, I finally actually saw the part about nested libraries. I think that is the issue. Sorry to bother.

          • Chris Hemedinger
            Chris Hemedinger on

            Thanks for reading my post 20 times. I often re-read classic books like Lord Of The Rings and always find something new. I'm going to pretend that you were aiming for a similar experience with my blog article.

  9. Very Nice information - could eliminate the pre-checking process for all libname paths.

    Thanks for posting

  10. I am a beginner in SAS and I love this blog because the code snippets work. However the folders that are created don't persist. In the university edition I am using via a virtual machine, I was able to create a folder that persists by using the recreate option that puts it in the SAS autoexec file using the GUI. However I could not yet create sub-folders that appear in the GUI. Though the code snippet here shows the sub-folder was created (in the log), it does not appear in the pane like the first level directory does.

    • Chris Hemedinger
      Chris Hemedinger on

      Go,

      I was able to get this to work.

      options dlcreatedir; libname newdir '/folders/myfolders/newdir';

      This creates a permanent folder (../myfolders/newdir) under the shared "my folders" folder that the SAS University Edition can access. That's the only place that you can create persistent files/data, as it's designated as "shared" between your PC and the SAS University Edition VM.

  11. I work on a team where multiple users share access to our folders. If I create a folder using the Windows File Explorer any user can write to the created folder. However, if a user creates a folder using DLCREATEDIR, only that user can write SAS datasets to that folder.

    Are you aware of any way to set the read-write permissions to a folder when being created with DLCREATEDIR?

    Thanks!

    • Chris Hemedinger
      Chris Hemedinger on

      Interesting! You mention Windows Explorer, but is your server on Unix? Maybe you need to set the umask values differently on server-startup. See this SAS Note.

      • Hey Chris....thank you for the tip! In the past, I would just use an X command to create a directory if it did not exist but after the SAS admins here turned the X command off, I was looking for alternative solutions and your tip solved the problem.

        This would make a great coders corner tip for a future conference if it hasn't been done already.

    • Mpho Nenguda on

      Hi There

      i have a similar problem where i am using the dcreate statement to create a directory in Unix but i am trying to find a way to set permissions recursively to that same folder.

      any idea on who to resolve this issue

  12. SUPRIYA BISWAS on

    I want to start blogging on analytics related to SAS, R, Excel, SQL. Could you please guide me how to start?

    • Chris Hemedinger
      Chris Hemedinger on

      The FDELETE function can delete directories -- but the directory must be empty first. So you would need code to list each file in the directory, delete each one with FDELETE, and then finally finish by deleting the empty directory. If you create the directory as part of the WORK area, no need to delete -- SAS will remove those when the session ends.

      options dlcreatedir;
      libname newfold "%sysfunc(getoption(work))/output";
      

  13. Hi, I tried to run the dccreate function in SAS 9.2, Enterprise Guide 5.1, but it comes with error

    ERROR 68-185: the function DCCREATE is unknown, or cannot be accessed.

    I ran the following code
    data _null_;
    newdir=dccreate('test','/opt/app/Lev2/usrdata/temp_test');
    run;
    please can you assist as I can't use other alternatives which needs XCMD to be enabled.

  14. Mark Cannella on

    Hey Chris, in 9.4, do you know of a snippet that when you run a libname statement, it will open the file folder location automatically so you don't have to go searching for it with the file path location?

    So a shared common area, but when the code is ran, you can see the opened area in the server file folder location on the left hand side instead of following a tree location that might be several folder steps in locating it.
    Thanks,
    Mark

    • Chris Hemedinger
      Chris Hemedinger on

      Mark, I don't. I don't know of a command that will cause the explorer window to navigate to the path, but you could research the EXPLORER command. (Assuming you're talking about SAS 9.4 windowing environment, not EG or SAS Studio).

  15. Hi,

    How to export data to this newly created folder and into excel file that is being created while proc export procedure ? Would you help me ?

    %Let path = C:\myfiles;
    %Let dirname= "dirname";
    %Let xlsxfile = "test.xlsx";

    data _null_;
    newdir=dcreate(&dirname, &path);
    run;

    data cars;
    set sashelp.cars;
    run;

    proc export
    data = cars
    outfile = &path&dirname&xlsxfile
    dbms= xlsx REPLACE;
    Sheet = "Success";
    run;

    • Chris Hemedinger
      Chris Hemedinger on

      Here's what I would do. Note that I removed quotes from the macro variables and quoted in the statement syntax instead.

      %Let path = C:\temp\dirname;
      %Let xlsxfile = test.xlsx;
       
      options dlcreatedir;
      libname folder "&path.";
      libname folder clear;
       
       
      data cars;
        set sashelp.cars;
      run;
       
      proc export
        data =  cars
        outfile = "&path./&xlsxfile."
        dbms= xlsx REPLACE;
        Sheet = "Success";
      run;

Back to Top