Hi,
I sometimes work on my desktop and sometimes on my laptop. When I work on my laptop, I access files on the desk via the network, both the data and the jobs.
So when I am on the desktop I have this, accessing the data which is on desktop:
libname data1 "d:\data1";
libname data2 "d:\data2";
libname data3 "d:\data3";
libname data4 "d:\data4";
etc.
When I am on the laptop, I access the data on the desktop using the name for the desktop on the network:
libname data1 "\\SmithDT\data1";
libname data2 "\\SmithDT\data2";
libname data3 "\\SmithDT\data3";
libname data4 "\\SmithDT\data4";
What that means is every time I switch back and forth between the desktop and the laptop, I have to change or comment out the libname that is not correct. I would like be able to set it up where I only make one change, the drive name (depending on whether I am on the desktop or laptop), and have it concatenate with the subdirectory.
I have tried using %Let Drive="d:\" or %Let Drive="\\SmithDT" , and %Let SubDir="data", but then it does not seem possible to concatenate &Drive and &Subdir, because the ' becomes part of the value of the macro variable.
Thanks for any ideas, I'm using SAS 9.4
In macro code quotes are just like any other character (although strings inside of single quotes are not processed by the macro processor). So you should NOT include the quotes in the value of your macro variable.
%let top=D:;
libname data1 "&top\data1";
libname data2 "&top\data2";
libname data3 "&top\data3";
In regular SAS code you need quotes around strings so that the compiler knows you mean a sting literal and not a name or keyword. But the macro processor just looks for & and % triggers to know when it needs to take action so there is no need to add the quotes. Just add quotes into the code that you are using the macro variables (or macro code) to generate where SAS itself needs the quotes. Like the quotes around the path in the LIBNAME statement above.
Don't put quotes around the macro variable and that's all. You can also just add some conditional logic for the program to detect where you're running from and then conditionally run one set of the code.
%let drive =D:\;
libname data1 = "&drive.\data1";
You can also use the LIBNAME function in a data step which allows you to dynamically build your string.
In general, a lot of options to solve this issue.
Using a UNC path should work on both computers - libname data1 "\\SmithDT\data1"; - then you wouldn't need to change any code.
In macro code quotes are just like any other character (although strings inside of single quotes are not processed by the macro processor). So you should NOT include the quotes in the value of your macro variable.
%let top=D:;
libname data1 "&top\data1";
libname data2 "&top\data2";
libname data3 "&top\data3";
In regular SAS code you need quotes around strings so that the compiler knows you mean a sting literal and not a name or keyword. But the macro processor just looks for & and % triggers to know when it needs to take action so there is no need to add the quotes. Just add quotes into the code that you are using the macro variables (or macro code) to generate where SAS itself needs the quotes. Like the quotes around the path in the LIBNAME statement above.
thanks, I hadn't realized that yet.
You've had replies about how macro variables are just literal text that get resolved during program compilation.
You've also had the suggestion to use the UNC path for both scenarios.
If that doesn't work for some reason, you can try this approach:
%macro allocate_libraries;
%let computername=%sysget(COMPUTERNAME);
%if (&computername eq FOO) %then %do;
libname data1 "d:\data1";
libname data2 "d:\data2";
libname data3 "d:\data3";
libname data4 "d:\data4";
%end;
%else
%if (&computername eq BAR) %then %do;
libname data1 "\\SmithDT\data1";
libname data2 "\\SmithDT\data2";
libname data3 "\\SmithDT\data3";
libname data4 "\\SmithDT\data4";
%end;
%mend;
%allocate_libraries
Substitute FOO and BAR with your desktop and laptop computer names.
This assumes that you're running Base SAS (i.e. DMS) on both machines. If you're running EG, then COMPUTERNAME would be the name of the server.
I don't want to add confusion but you may want to be careful using the phrase "concatenated libname" as in your subject line as that sounds like you want to concatenate libraries, i.e. reference multiple storage areas with a single library name.
The libname does that by something such as
libname all ( "d:\data1" "d:\data2" "d:\data3" "d:\data4");
Not a good idea if you have multiple data sets with the same name but can be useful to reference data sets stored in separate locations without having to keep track of which set is in which library.
@Bahr wrote:
...
but actually, that may do what I wanted:
libname test ("\\Desktop\data" "d:\data\");
If that were on the laptop with access to the network, then it would
go to the Desktop via the network, but if it did not have access to
the network, then it would go to the second choice.
That's not going to work. If one of the paths is invalid then the libname will throw an error.
Thanks everyone for all of the very interesting solutions. They were useful not only for this particular issue but also for better understanding of the libname command and the %let macro.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.