| David Franklin, Blog | |
| 2003 Archive | |
| Back | dfranklinnh@gmail.com |
|
JanuaryWelcome to this page, the first of hopefully many pages with a SAS related tip of the month. At present there are no plans to have an archive of the tips, but that may change if people ask for it -- at present this page will be updated every month with a new tip. Some of the tips will be short, some will be long, and others will be in-between. To lead this new series, there will be just a simple tip, one that has been around since I started programming and cannot be stressed enough for the serious programmer. When you are coding, there will be pieces of code that you will see or use and think "that is interesting". Don't be afraid to copy, or print and paste, that code into a notebook and keep it handy -- you don't know when you are going to need it. You will be amazed at the number of times you will refer to it for that 'little trick'. FebruaryWhen creating a variable it is important to tell SAS what the variable type, length and optionally what its label is and any formats applied to it. The ATTRIB statement is useful for doing this although a combination of the LENGTH, LABEL, FORMAT and INFORMAT statements is also okay. MarchWhen using the SORT procedure try to restrict the number of variables that are in the dataset being sorted. This can be done by making liberal use of the KEEP= or DROP= data set options in the DATA= call of the SORT procedure. AprilDo you want to delete a dataset from a particular library, or possibly all datasets in a library? One way to do it is with the use of the DATASETS procedure, as shown in the following examples: *** Delete the single dataset CLASS in the library WORK;
proc datasets library=work nolist nodetails nowarn;
delete class /mt=data; *** Delete a single dataset;
quit;
run;
*** Delete all the datasets in the library WORK;
proc datasets library=work nolist nodetails nowarn kill mt=data;
quit;
run;
Note that in the first example, the DELETE statement will only work on datasets in the library specified by the LIBRARY option in the top line of the procedure call. The KILL option on the first line of the second example deletes all members of the library WORK, restricted to datasets by using the MT= option in the first line of the procedure call. MayThe INDEX functions are very useful in finding out if a character or word exists in the string. The documentation gives these functions with the following definition:
Now lets see how them in use with the following examples: 252 data _null_; 253 TextStr='Apt 56B, Whitehaven Mansions, Sandhurst Sq, London'; 254 255 *** The location of the first string '6B'; 256 FindINDEX=index(TextStr,'6B'); 257 258 *** The location of first 's' or 'a' (regardless of order)'; 259 FindINDEXC=indexc(TextStr,'sa'); 260 261 *** The location of first word 'Whitehaven'; 262 FindINDEXW=indexw(TextStr,'Whitehaven'); 263 264 put TextStr= / 265 FindINDEX= FindINDEXC= FindINDEXW=; 266 run; TextStr=Apt 56B, Whitehaven Mansions, Sandhurst Sq, London FindINDEX=6 FindINDEXC=16 FindINDEXW=10 JuneWant to share your datasets with your colleagues who don't have SAS? Consider asking them to install the free SASViewer available from the SAS Web Site at http://www.sas.com. JulyIf it is necessary to convert a unique list of values, separated by a space, within a variable to a macro parameter here is a piece of SAS code that will do this using SQL: PROC SQL;
SELECT DISTINCT var
INTO :macrovar SEPARATED BY ' '
FROM dset1
WHERE var1 IS NOT MISSING;
QUIT;
RUN;
AugustIn their basic form, the COMPRESS and COMPBL functions manipulate the blanks or spaces in a text string. The COMPBL function will remove multiple blanks in a string and replace them with a single blank it will also remove trailing and leading blanks from a string. The COMPRESS function will remove all blank spaces from a string, including the leading and trailing blanks. The COMPRESS function was enhances a few years ago to include characters that a used specified it was no longer restricted to blanks. Refer to the following examples of the functions use: 297 data _null_; 298 TextStr='1049 Park Avenue, New York, NY'; 299 TextCOMPBL = compbl(TextStr); 300 TextCOMPRESS = compress(TextStr); 301 TextCOMPRESS_withoutNumbers = compress(TextStr,'0123456789'); 302 put TextStr= / 303 TextCOMPBL = / 304 TextCOMPRESS = / 305 TextCOMPRESS_withoutNumbers =; 306 run; TextStr=1049 Park Avenue, New York, NY TextCOMPBL=1049 Park Avenue, New York, NY TextCOMPRESS=1049ParkAvenue,NewYork,NY TextCOMPRESS_withoutNumbers=Park Avenue, New York, NY SeptemberOccasionally SAS will not action a Windows operating system command when using the SYSTEM, CALL SYSTEM, X or macro equivalent statements. In order to circumvent this SAS suggests creating a DOS .BAT file with that command then having SAS call the .BAT file. The following example demonstrates the fix where what the program is asking for a list of .TXT files in a directory which will later be read it: rc=SYSTEM("DIR "||dirloc||"\*.txt /b>||"dirlist");
would be rewritten as rc=SYSTEM("DIRLSTX dirloc dirlist");
with the accompanying DIRLSTX.BAT file containing the text DIR %1\*.txt /b>%2
In the example dirloc is the directory location of the files that are of interest, and dirlist is the output file containing the list of .TXT files it found. From what I have read SAS has fixed this problem is the latest SAS version 9 release. OctoberSometimes a missing value needs to be coded, often for some form of frequency analysis. In the example below the missing value for gender is going to be set to '9' while male will remain '1' and female '2'. To make the change there are several solutions, three of which are given below: gender = min(gender,9); if gender = . then gender = 9; if missing(gender) then gender = 9; SAS provides many solutions to a single challenge, it is just selecting which is the best for the job on hand that is the most difficult part. NovemberHere is an oldie, but a good example of SAS code that I find useful. Using the following data find the Number of Observations, Mean, Standard Deviation, Median, Minimum and Maximum values for the following data, grouping by Gender and age groups 18-64 and 65-75:
** DATA **
SUBJECT AGE GENDER
001 35 M
002 70 M
003 65 M
004 40 F
005 66 F
006 36 F
** SAS PROGRAM **
PROC FORMAT;
VALUE agex
18-64='18-64'
65-75='65-75'
other='Unexpected';
RUN;
PROC MEANS DATA=demog N MEAN STD MEDIAN MIN MAX;
CLASS gender age;
VAR age;
FORMAT age agex.;
RUN;
Using the AGE variable both in the CLASS and VAR statements it is treated both as a category and analysis variable. Note that the median calculation came into the MEANS procedure in SAS version 7 - prior to that the median could be calculated using the UNIVARIATE procedure. DecemberThe way a statistic is calculated may be more important than the result it produces. Recently an example showed up when some statistics were being checked using Excel on results produced with SAS, specifically with the calculation of a first and third quartile, also known as the 25th and 75th percentile. For the data 1, 2, 3, 4, 5, 6, 7 and 8 the following results are calculated for the 25th percentile:
Why the difference? There actually is no standard for the calculation of percentile and it does depend on what a statistician is looking for. SAS has six methods of calculating the percentile, the two common ones being:
Excel, S-Plus and StarOffice Calc by comparison uses a different method, specifically:
Among the major statistical software packages only Excel, S-Plus and StarOffice Calc use this method. For those using Minitab or SPSS they use the SAS Method 4 for their calculation. The moral of this example is that you should know how your software calculates a statistic before blindly reporting the result. |