I've downloaded a sas dataset and a format catalog that goes with it. This is probably super basic but I can't seem to set up the libraries so that I can make use of the formats, and I can't open the dataset unless I use the NOFMTERR option. They are both in the same windows folder. Please help.
The following code should explain how to add a library (in this case the library mylib) to the FMTSEARCH option which dictates which libraries are searched for SAS formats:
/* Display the current fmtsearch option - librefs searched in order for formats */
%put %sysfunc(getoption(fmtsearch));
libname mylib 'windows-folder';
/* Append the library containing the format catalog */
options append=(fmtsearch=mylib);
/* Check the fmtsearch option again */
%put %sysfunc(getoption(fmtsearch));
Just point SAS to the library where your format catalog is, and this should resolve the format errors and allow you to display the formatted data.
For users of 9.1.3, you can directly alter the fmtsearch option. Here's a method of doing so most similar to #mjsqu's code above (which preserves the already-existing format options) and appends to the end.
* Store fmtsearch option value in macro variable;
%let fmtsearch=%sysfunc(getoption(fmtsearch));
*Append NEWLIB to the end (assuming NEWLIB is your library name);
*Uses SUBSTR to strip off the end parenthesis;
%let fmtsearch_new = %substr(&fmtsearch,1,%length(&fmtsearch.)-1) NEWLIB);
*Check new value;
%put &fmtsearch_new;
*Set fmtsearch option to new value;
options fmtsearch=&fmtsearch_new.;
*Check that option was set;
%put %sysfunc(getoption(fmtsearch));
Of course, this will re-append the value multiple times if you run this multiple times; that's not harmful, but might look odd. You could do some additional checking to see if it is already in the string and not re-add if it is.
Related
I have to perform statistical analysis on a file with hundreds of observations and 7 variables(columns)on SAS. I know that it is necessary to insert all the observations after "cards" or "datalines". But I can't write them all obviously. How can I do? Moreover, the given data file already is .sas7bdat.
Then, since (in my case) the multiple correspondence analysis requires only six of the seven variables, does this affect what I have to write in INPUT or/and in CARDS?
You only use CARDS when you're trying to manually write a data set. If you already have a SAS data set (sas7bdat) you can usually use that directly (there are some exceptions but likely don't apply here).
First create a libname to the folder where the file is:
libname myFiles 'path to fodler with sas file';
Then load it into your work library - this is a temporary space that is cleaned up when you're done so no files here are saved permanently.
This copies it over to that library - which is often faster.
data myFileName;
set myFiles.myFileName;
run;
You can just work with the file from that library by referencing it as myFiles.myFileName in your code.
proc means data=myFiles.myFileName;
run;
This should get you started, but you should take the SAS free e-course to understand the basics, it will save you time overall.
Just tell SAS to use the dataset. INPUT statement (and CARDS/DATALINES or INFILE statement) are for reading from text files.
proc corresp data='/my directory/mydataset.sas7bdat' .... ;
...
run;
You could also make a libref that points to the directory and use two level name to reference the dataset.
libname myfiles '/my directory/';
proc corresp data=myfiles.mydataset .... ;
...
run;
I'm working with data that seem to be split into nearly arbitrary sets from year to year. What I would like to do is to be able to start by concatenating all of the .sas7bdat files in a single library. How would I go about this?
Alternatively, if I know all of the possible names that files in the library might be assigned (but many are potentially missing from any given library), how can I get SAS to ignore missing files? For instance, say that I know all of the .sas7bdat files in my library have one of the names "set01", "set02", "set03" or "set04". If a particular library ("L") is missing one of these, then the data step:
DATA temp;
SET L.set01 L.set02 L.set03 L.set04;
RUN;
will produce an error. Assuming that I know that at least one of these exists, is there an option that will tell SAS to ignore the missing ones?
(I understand that these are two totally different questions, but either would solve my immediate problem.)
in SAS there is an easy way for SAS to automatically choose the datasets that start with some common name, you can use following statement:
data temp;
set L.set0: ; /*It will search for all datasets that start with set0 and will set only those which are available*/
run;
Does it answer your query?
Second approach
libname L "Y:\Test Data";
proc sql;
select strip("L."||memname) into :DSNAME separated by ' '
from dictionary.tables
where libname='L';
quit;
/* Main final DS*/
data want;
set &DSNAME;
run;
It will extract all Dataset names in L directory and will create macro variable DSNAME such as : L.set01 L.oth02 etc. , common names won't matter here..
I've scoured the internet but cannot seem to figure this out. My question is, if I have a sas7bdat file, how can I read a sas7bdat file in SAS studio so that I can work with it.
I've tried:
libname test 'C:\Users\name\Downloads\test.sas7bdat';
which gives me the error that library test does not exist and if I try the following, I know that I need an INPUT which I don't know of unless I can see into the file.
DATA test;
INFILE 'C:\Users\lees162\Downloads\test.sas7bdat';
RUN;
Is there something I'm missing?
Libref's that you create via the LIBNAME statement point to directories, not individual files.
libname test 'C:\Users\name\Downloads\';
INFILE is for reading raw data files. To reference an existing SAS dataset you use a SET statement (or MERGE,MODIFY,UPDATE statement).
set test.test ;
Note that you can skip defining a libref and just use the quoted physical name in the SET statement.
DATA test;
set 'C:\Users\lees162\Downloads\test.sas7bdat';
RUN;
Of course to use C:\ in the paths this is assuming that you are using SAS/Studio to point to full SAS running on your PC. If you are using SAS University Edition then it is running in a virtual machine and you will need to put the SAS dataset into a folder that is mapped to the virtual machine and then reference it in the SAS code with the name that the virtual machine uses for the directory.
So something like:
DATA test;
set '/folders/myfolders/test.sas7bdat';
RUN;
Libname is just pointing the location and once you have done that you can use that libname followed period and dataset in your set statement
libname test "C:\Users\name\Downloads";
DATA test;
set test.asl;
RUN;
One possible reason could be that you are using the SAS University edition (It doesn't support variable library address).
From one of the SAS community Q/A:
"When you are using the SAS University Edition, any libraries that you create must be assigned to a shared folder. You access your shared folder with this pathname: /folders/myfolders/. Always use '/' in the directory path, even in Windows operating environments"
After setting the directory address, proceed as instructed by Tom above in one of the answers.
Suppose you have the sas dataset at location. C:\Users\name\Downloads\test.sas7bdat
libname download 'C:\Users\name\Downloads';
proc sql;
select * from downloads.test;
run;
you can read your dataset like a table using the proc sql, in case you want to query the dataset, but if you want to modify the existing dataset then you can use the data setp as mentioned by #krian.
Say I have defined a macro function, and for some reason (e.g. a mistake), I deleted the code. I still have the macro though.
How can I retrieve the code I used to define it ?
To define the macro, I just executed:
%macro(param1,param2);
my code
%mend;
If you defined the macro with the source option specified and in a library you can retrieve it with the following:
%copy MACRO_NAME / source;
Official SAS answer, see original link below:
There is no way to retrieve the original source code from a stored compiled macro. You must always save the original code in another file so that you can modify it later.
Starting with SASĀ® 9.1, there is a new SOURCE option for the %MACRO statement. When used with the existing STORE option, the SOURCE option combines and stores the source of the compiled macro.
The compiled macro code becomes an entry in a SAS catalog in a permanent SAS data library. The compiled macro and the source code are stored together in the same SASMACR catalog. The SOURCE option requires that the STORE option and the SAS option MSTORED be set. You can use the SAS option SASMSTORE= to identify a permanent SAS data library. You can store a macro or call a stored compiled macro only when the SAS option MSTORED is in effect.
Note: The source code that is saved by the SOURCE option begins with the %MACRO keyword and ends with a semicolon following the %MEND statement. Now that you have a way to store the source code with the SOURCE option, you also need a way to retrieve this information. The answer is the new %COPY statement, which copies specified items from a SAS macro library.
For example:
libname test 'c:\';
options mstored sasmstore=test;
%macro test(arg) / store source des="test of the source option";
%put arg = &arg;
data one;
x=1;
run;
%mend test;
%copy test / source;
Source:
http://support.sas.com/kb/22/352.html
If you don't have the SOURCE option and your macro is relatively basic you could try using the MPRINT and SYMBOLGEN to get the log with the code but if you have conditional logic it'll be hard to recreate the code for sure.
options mprint symbolgen;
%my_macro(param1, param2);
We have hundreds of macros across several autocall libraries that I'd like to compile using the MSTORE facility.
The problem is that some of those libraries are used on other sites - and we don't want to add /STORE to every definition, as then it is required to use the MSTORED option.
I guess the answer is to add /* /STORE */ at the end of every %macro statement, so that the .sas program files can be updated with a regular expression (or some other text replacement technique) on every redeploy, but this seems like a messy workaround.
Is it possible / in some way supported, to compile regular (unmodified) autocall macros and store the definitions? Eg by %inc'ing each one and saving the work macro catalog, or something like that?
I won't say definitively that this isn't possible, but I can report that I tried to do the same thing some time ago and got stuck on the same point. I was also unable to find any way of doing this other than adding /store to every %macro statement.
I vaguely remember that I was able to upload the work.sasmacr catalogue from one session to another on the same machine (after first compiling a few autocall macros to populate it), but the other session didn't recognise the macro definitions from transferred catalogue even though the appropriate options were set for using stored compiled macros.
My motivation was different from yours - I was looking for a way to define a macro in one session and execute it in another without saving it in an autocall folder or %including it in both sessions - but the conclusion was the same.
What is the problem that you had?
First compile all of your autocall macros. Say you have a fileref named MYMACS that points to the directory with the source code.
%include mymacs(macro1,macro2,.....);
You might use a program to search for all of the source files so that you could automate generating the %include statement(s). Or you could use a datastep and copy all of the source files into a single temporary file and include that.
filename src temp;
data _null_;
infile "&inpath\*.sas" ;
file src ;
input;
put _infile_;
run;
%inc src ;
Then copy the WORK catalog to you a new location. Note that the name is different if you are running SAS on an application server. In that case try copying from WORK.SASMAC1 instead of WORK.SASMACR.
libname out base "&path";
proc catalog cat=work.sasmacr et=macro ;
copy out=out.sasmacr ;
run;
quit;
You can test if it worked by clearing your current work macro catalog, so you know SAS is not finding the macro there, and setting options to point to the new catalog of compiled macros.
proc catalog cat=work.sasmacr kill force ;
quit;
options mrecall mstored sasmstore=out ;
Then trying to run one of the copied compiled macros.
Now start up a new session and try using the compiled macros in that session.
Here was the approach I took for compilation (of course there are many alternative ways). The locations to query can be extracted from:
%put %sysfunc(getoption(sasautos));
The approach relies on macros being closed off with )/*/STORE SOURCE*/; as follows:
%macro some_macro(var1=x, var2=y
)/*/STORE SOURCE*/;
The SAS code has to be a program, as you can't create a stored compiled macro from within a macro.
/* set mstore options */
options mstored sasmstore=yourlib;
/* get list of macros */
/* taken from macrocore library */
/*https://github.com/sasjs/core/blob/main/base/mp_dirlist.sas*/
%mp_dirlist(path=/location/one,outds=in1)
%mp_dirlist(path=/location/two,outds=in2)
/* set up a temporary fileref */
filename tmp temp;
/**
* write each source macro to the fileref
* and switch on the STORE option
*/
data want;
set in1 in2;
infile dummy filevar=filepath end=last ;
file tmp;
do until(last);
file tmp;
input;
if _infile_=')/*/STORE SOURCE*/;' then put ')/STORE SOURCE;';
else put _infile_;
end;
run;
%inc tmp; /* compile macros */
filename tmp clear; /* clear ref */