Q: KWord and AbiWord

KWord is used to open, edit, and print Microsoft Word document in Linux (e.g. Pascal, Fisher and Pearson server in the department install Linux system.).

To open a Microsoft Word document, type

kword filename.doc&

The interface of the KWord is quite similar to Microsoft Word.

It seems that the KWord could not save files as Microsoft Word document.

For more information, check the KWord webpage.

AbiWord is a Word processor which "will run on virtually any operating system". You can open, edit, and print Microsoft Word document by using AbiWord. It's simple and fast.

To open a Microsoft Word document by AbiWord, type

abiword filename.doc&

For more information, check the AbiWord webpage.

Q: OpenOffice.org

OpenOffice.org is a multi-platform open source office productivity suite. It includes the key desktop applications, such as a word processor, spreadsheet, presentation manager, and drawing program, with a user interface and feature set similar to other office suites. It has an ability to import documents in Microsoft formats such as *.doc or *.xls.

OpenOffice exists as ooffice on pearson on StatNet and as soffice on newton on StatNet

The components of the suite are called:

WRITER

text processor which can serve as a substitute for MS Word. The command file is normally called oowriter.

CALC

spreadsheet to substitute MS Excel. Command file: oocalc.

IMPRESS

presentation suite to take place of MS PowerPoint. Command file: ooimpress.

DRAW

image and diagrams editor. Command file: oodraw.

OpenOffice.org can also export text documents (such as imported from MSWord) and presentations (e.g. converted from MS PowerPoint) into PDF documents.

OpenOffice.org is being installed by default on most modern distributions of Linux and Solaris. However, it is available for Windows as well.

In StatNet, it is available on pascal server but cannot be used due to insufficient CPU speed and other resources (as of August 2004). It can also be run on undergraduate server ugrad.

Q: KSpread and Gnumeric (spreadsheet)

KSpread and Gnumeric can read Microsoft Excel files. The interface and the operation (e.g. short-cut key) of KSpread and Gnumeric are similar to those of Microsoft Excel. KSpread cannot save files as Microsoft Excel file format. Gnumeric can save files as Microsoft Excel (95) file format. Gnumeric can not read Microsoft Excel files which are created by higher version of Microsoft Excel than Microsoft Excel 95.

To open Microsoft Excel files, type

kspread filename.xls& or gnumeric filename.xls&

For more information, check webpages of

KSpread

and

Gnumeric

.

Q: How to use Unix text editor 'vim'?

To use the following features or short-cut keys, you may need to copy files .cppvim, .cvim, .fvim, .gvimrc, .htmlvim, .texvim, .viminfo, .vimrc from Dr. Harry Joe's home directory.


Go to the top

Basic Operations:

  • vi is a Visual Editor. The name vi is for Visual. Visual editors are ones that let you see multiple lines of the document that you are editing as you edit it.
  • vi editor has two modes (command mode and insert mode). In the command mode, you can input commands. In the insert mode, you can edit files. To enter into command mode, type ESC key. To enter into insert mode from command mode, type character i.
  • u --- undo
  • ctrl+r --- Redo
  • :wq --- save the file and quit from vi
  • :q! --- quit from vi without saving the file
  • Cursor movement (all commands listed below are entered in the command mode and commands are case sensitive)
    • G --- move to the end of the file
    • 1G --- move to the beginning of the file
    • :n --- move to the n-th row of the file (n is a non-negative integer)
    • :0 --- move to the beginning of the file
    • :5000 --- move to the end of the file (where 5000 can be any number which is larger than the total row number of the file)
    • :-n -- move up n rows from the current row (n is a non-negative integer)
    • :-6 -- move up 6 rows from the current row
    • ^ --- move to the first character in the row
    • 0 --- (zero) move to the beginning of the row
    • $ --- move to the last character in the row
    • w --- move to the beginning of the next word
    • b --- move to the beginning of the previous word
    • 6w --- move forward to the beginning of the 6-th word from the current position
    • 8b --- move backward to the beginning of the 8-th word from the current position
    • Ctrl+f --- move to the next page
    • Ctrl+b --- move to the previous page
    • h --- move to the previous character
    • l --- move to the next character
    • k --- move to the previous line
    • j --- move to the next line
    • use arrow keys, or ctrl+arrow keys, or pageup or pagedown keys (in either command mode or insert mode)
    • ) --- forward sentence
    • ( --- backward sentence
    • } --- forward paragraph
    • { --- backward paragraph
    • ]] --- forward section
    • [[ --- backward section
  • select, copy, and paste
    • To select text, use mouse (you can first use the mouse to hightlight part of text, then use arrow keys or pageup or pagedown key to highlight more text)
    • To select text in a rectangle region
      1. type Ctrl+v
      2. hold the left-button of the mouse and drag the mouse to select the desired rectangle region
    • ggvG --- to select all text in the current window
    • yy --- to copy the current line to the clipborad
    • 6yy --- to copy 6 lines from the current line (include the current line) to the clipboard
    • p --- (small letter "p") to paste the content in the clipboard to the next line
    • P --- (captial letter "P") to paste the content in the clipboard to previous line
  • delete or change characters, words, or lines
    • x --- to delete the current character
    • ra --- to replace the current character with the character "a" (you can replace "a" with any other character)
    • dw --- to delete the current word
    • dj --- to delete the current line and the next line
    • d} --- to delete from the current character to the end of this paragraph
    • 6dw --- to delete 6 words from the current word (including the current word)
    • cw --- to delete the current word and enter into insert mode (change the current word)
    • 6cw --- to delete 6 words from the current word (including the current word) and enter into insert mode (change the 6 words)
    • dd --- to delete the current line and copy it into the clipboard
    • 6dd --- to delete 6 lines from the current line (include the current line) and copy them into the clipboard
    • d^ --- to deletes from current cursor position to the first character of the line.
    • d0 --- (0 is zero, not character O) to deletes from current cursor position to the beginning of the row.
    • d$ --- to delete from the current current cursor position to the end of the line
    • D --- same as d$
  • search and replacement
    • /abc --- to search the word "abc"
    • /abc efg.r --- to search the phrase "abc efg.r"
    • n --- to find next
    • N --- to find previous
    • :s/abc/ef/g --- to replace the word "abc" with the word "ef" in the range of the whole file
    • :3,10s/abc/ef/g --- to replace the word "abc" with the word "ef" from the 3rd line to the 10 line.
    • :1,$s/abc/ef/g --- to replace the word "abc" with the word "ef" from the first line to the last line. It is equivalent to :s/abc/ef/g.
  • windows operation
    • ctrl+w+s --- to split the current window horizontally (ctrl+w+s means that first hold ctrl key, then type "w" and "s" sequentially, finally release ctrl key)
    • ctrl+w+v --- to split the current window vertically(ctrl+w+s means that first hold ctrl key, then type "w" and "s" sequentially, finally release ctrl key)
    • ctrl+w+q --- to close the current window
    • ctrl+w+w --- to jump the cursor to the next window
    • ctrl+w+= --- to equalize the sizes of windows
  • file operation
    • :e abc.txt --- to edit (or create) the file "abc.txt" in the current window (you can use TAB to complete the command)
    • :w abc.txt --- to write the content in the current window to the file "abc.txt" (you can use TAB to complete the command)
    • :w --- to save the current file
    • :w >> abc.txt --- to append the contents of the buffer to the file abc.txt.
  • Escaping to Shell
    • :!cmd --- to execute a single unix command
    • :sh --- to escape to shell. By doing this, you can execute many unix command. You can return to gvim by typing Ctrl+D
  • Recovering lost files

    If the system crashes while you are editing with vi, you can recover the work you were doing to within a few changes.

    To recover the file, abc.txt say, type command

    vi -r abc.txt To get a list of the files which are saved for you, type command vi -r
  • Misc
    • J --- join the next line with the current line
    • % --- find the matched (round, squared, or curly) brackets (first put the cursor to one of the bracket, then type % to find it's counterpart bracket)
    • . --- the period "." is used to repeat the previous operation
    • o --- the small letter "o" is used to create a new line under the current line and enter into the insert mode
    • O --- the capital letter "O" is used to create a new line above the current and enter into the insert mode
    • i --- to put the cursor in the current cursor position and enter into the insert mode
    • a --- to put the cursor after the current character and enter into the insert mode
    • I --- to put the cursor before the first character of the current line and enter into the insert mode
    • A --- to put the cursor after the last character of the current line and enter into the insert mode
    • :set number --- to view the line number
    • :set nonumber --- to remove the line number
    • ctrl+G --- to show the state (e.g. file name, the number of lines of the file) of the file you are editing.
    • `` --- (two back quotes) to get back to a previous position.
    • ~ --- to switch the case of the character under the cursor.

Go to the top

Create short-cut keys:

You can create short-cut keys for gvim. For example, you can type ",l" to compile latex file in the current gvim window. To do that, type the following mappings in the .vimrc file in your home directory:

map ,l :!latex % map ,b :!bibtex %< map ,x :!xdvi %<.dvi & map ,p :!pdflatex % & map ,f :!xpdf %<.pdf & map ,a :!acroread %<.pdf & map ,g :!ghostview %<.ps &

Go to the top

Transform a table to LaTeX format

(

This entry is provided by Mark Robinson in Informal Computing Seminar - January 20, 2000.

)

A really useful tool ... suppose you have a bunch of numbers which you want to put into a table in latex. This is a quick way to do it. You want to transform: 0.41 -1.00 0.27 0.01 -0.99 0.64 -2.90 0.24 -0.33 0.02 1.37 0.47 into: begin{center} begin{tabular}{|cccccc|} hline 0.41 & -1.00 & 0.27 & 0.01 & -0.99 & 0.64 -2.90 & 0.24 & -0.33 & 0.02 & 1.37 & 0.47 hline end{tabular} end{center} To do this, type (while in command mode) ":43,44!table2tex.pl" (the breakdown ... the 43,44 says it will only work on lines 45 to 46 and the !table2tex.pl will make a call a the Perl program ... note that you must have this Perl program in your current directory or some directory covered in your PATH variable)

(

You can obtain the source code of the file table2tex.pl at Dr. Harry Joe's webpage http://hajek.stat.ubc.ca/~harry/local/tabl2ltx.html

)

Go to the top

Transform a table to HTML format

(

This entry is provided by Mark Robinson in Informal Computing Seminar - January 20, 2000.

)

Start: 0.41 -1.00 0.27 0.01 -0.99 0.64 -2.90 0.24 -0.33 0.02 1.37 0.47 Make a call to ":67,68!table2html.pl" will produce: <TABLE border=5 cellpadding=5 cellspacing=3> <TR> <TD> 0.41</TD><TD> -1.00</TD><TD> 0.27</TD><TD> 0.01</TD><TD> -0.99</TD><TD> 0.64</TD></TR> <TR> <TD> -2.90</TD><TD> 0.24</TD><TD> -0.33</TD><TD> 0.02</TD><TD> 1.37</TD><TD> 0.47</TD> </TR> </TABLE> which you can include in an HTML file.

The source code of the file table2html.pl is as follows:

#! /usr/local/bin/perl #convert table to html #entries are centered justified #add parameter to <TD>to get left or right justification # for example <TD align="left"> print "<TABLE border=5 cellPadding=5 cellSpacing=3>n"; $i=0; while(<>) { chop($_); $line=$_; $line=~ s/^s+//; @fields=split(/s+/,$line); if($i==0) { $n2=0; foreach $itm (@fields) {$n2++;} } print " <TBODY> <TR>n"; for($j=0;$j<$n2;$j++) { print " <TD>", $fields[$j], "</TD>"; } print "<TR>n"; $i++; } print "</TBODY></TABLE>n";

Go to the top

Format (Splus) Output

(

This entry is provided by Mark Robinson in Informal Computing Seminar - January 20, 2000.

)

Say you have output from S-plus which you want to format a little better ... say you want to get rid of the first and third and last column and make the rest of the columns have 1,2,3,4 decimals points respectively First, above the output, type something like "0 8.1 0 8.2 8.3 8.4 0" (the 0's signify getting rid of that column, the a.b format signifies a width of a with b decimal points) Set it up like the following: 0 8.1 0 8.2 8.3 8.4 0 [1] -1.35861443 0.30258917 -0.57190688 0.27911763 0.41829340 -0.33448098 [7] 0.14098338 0.26156014 -0.67817408 0.27750322 0.70046690 1.63321662 [13] -0.87113567 -1.09045095 1.79157953 -0.05500772 0.14935190 0.52317747 [19] 1.22088326 -0.93934903 -1.11713757 -0.59225728 -1.59756826 0.10786151 [25] 0.37489964 1.20734204 -0.25157383 -0.43282194 -0.22918384 0.29038264 [31] -0.72439167 -1.34276791 0.65337613 0.89718566 0.43414847 0.54969927 [37] 0.79278406 -1.20080351 -0.64851697 0.85754266 0.57609186 1.17390791 [43] 0.79725791 1.80341577 1.29116587 -1.90582760 -0.29568917 -1.19636474 [49] 0.02651639 -0.61876364 2.48667007 -0.36526389 0.34067777 0.94685260 [55] -0.30327891 -2.18308852 1.70048157 -0.22125863 -0.47901244 0.41492965 [61] -1.58239934 -1.70093696 1.28804581 -0.59947646 -0.57224725 0.15351164 [67] 0.58445247 0.92078516 -0.60084557 -0.48747232 -0.29188598 -0.06975106 [73] 1.26688431 -0.65137419 -0.26926444 0.92899189 0.01798242 -0.25006773 [79] 0.40696346 -1.05068278 0.78963162 0.94104497 -0.55190809 0.97130390 [85] 0.45307721 -0.47658350 0.61146376 0.14271527 -0.45779235 0.61202598 [91] -0.66847263 0.71141322 -0.55144940 -0.94407312 -0.89556232 -1.72122285 Call ":91,107!format.pl" and it should change the above to: -1.4 -0.57 0.279 0.4183 0.1 -0.68 0.278 0.7005 -0.9 1.79 -0.055 0.1494 1.2 -1.12 -0.592 -1.5976 0.4 -0.25 -0.433 -0.2292 -0.7 0.65 0.897 0.4341 0.8 -0.65 0.858 0.5761 0.8 1.29 -1.906 -0.2957 0.0 2.49 -0.365 0.3407 -0.3 1.70 -0.221 -0.4790 -1.6 1.29 -0.599 -0.5722 0.6 -0.60 -0.487 -0.2919 1.3 -0.27 0.929 0.0180 0.4 0.79 0.941 -0.5519 0.5 0.61 0.143 -0.4578 -0.7 -0.55 -0.944 -0.8956

The source code of the file format.pl is as follows

:

#! /usr/local/bin/perl # formatting a data file (and also can extract subset of columns) $argc=$#ARGV+1; #print $argc,"n"; if($argc==1 && $ARGV[0]=~ /-h/) { print "usage: format.pl [-f w.d w.d ... w.d filename]n"; print "where w.d = 0 for excluding columnn"; print " otherwise w.d = width and number of decimal placesn"; print "If no '-f' flag, then first line of file has w.d ...n"; exit(0); } #for($i=0;$i<$argc;$i++) { print $ARGV[$i], " "; } #print "n"; if($ARGV[0] =~ /-f/) { $file=$ARGV[$argc-1]; $tem=shift(@ARGV); $argc-=2; print "ncol= ", $argc,"n"; open(STDIN,"<" . $file); } else { $_=<STDIN>; $_=~s/^s+//; $_=~s/s+$//; @ARGV=split(/s+/,$_); $argc=$#ARGV+1; #print @ARGV,"n"; } while(<STDIN>) { chop($_); $_=~s/^s+//; $_=~s/s+$//; @fields = split(/s+/,$_); $nfield=$#fields+1; $ncol=$argc; if($nfield<$ncol) { $ncol=$nfield+1; } for($i=0;$i<$ncol;$i++) { if($ARGV[$i]>0) { $fmt="%" . $ARGV[$i] . "f"; printf($fmt,$fields[$i]); } } print "n"; }

Go to the top

How to change the fontsize of the text in gVim?

You can use -fn flag. For example:

gvim -fn -*-*-*-*-*-*-*-250-*-*-*-*-*-*

The sequence

-*-*-*-*-*-*-*-250-*-*-*-*-*-*

is obtained by running the command

xfontsel&

and select the popup menu ptSz. Click the select button to copy the sequence to the buffer. Then you can paste the sequence to the terminal after command:

gvim -fn

For VIM 6.0, you can change the font from the Edit menu. Then select Select Font submenu.

Go to the top

gVim file explorer

From the Window menu of VIM 6.0, select Split File Explorer submenu. A file explorer will show on the left panel of the VIM 6.0 window. Double click a text file name in the file explorer. The text file will be shown in the right panel.

Q: Examples of SAS code and SAS usage (by Harry Joe)

SAS usage (by Harry Joe)

SAS examples

Note that SAS/IML can be used in "interactive mode" (but not as nice a Splus/R), with

sas -nodms

from the Unix command line. Then type 'proc iml' and create variables, vectors or matrices. Type 'endsas' to end your interactive SAS session. Alternatively submit IML statements from the SAS program window, and look for the output in the SAS output window (error messages in SAS LOG window).

SAS Insight for interactive data analysis

Step 1: convert an ascii/text file to SAS binary format (extension is .ssd or .ssd01 in Unix).

libname tem '/home/faculty/hjoe/s445'; data tem.iris; infile 'iris.dat' firstobs=2; /* first line consists of variable names */ /* the default field delimiter is one or more spaces */ /* there are special data formats in SAS */ input sepallen sepalwid petallen petalwid species $; run;

The result in /home/faculty/hjoe/s445 is

-rw-r--r-- 1 hjoe faculty 16384 Dec 10 14:35 iris.ssd01

Step 2. Starting SAS/Insight. By default, SAS/Insight will only find .ssd01 files if they are in your ~/sasuser directory. If your .ssd01 files are elsewhere, do something like below with the PROC INSIGHT.

libname s545 '/home/faculty/hjoe/s545'; proc insight data=s545.aes; run;

These 4 lines can be in a SAS file, eg. startida.sas, and started with the Unix command

sas startida.sas

or they can be typed in the SAS Editor Window and submitted.

SAS Toolbar

To assess your SAS data (.ssd) files interactively from menus and SAS INSIGHT, SAS FSVIEW, SAS FSEDIT, SAS FSBROWSE etc., add the path/directory names using 'libname' in your '~/autoexec.sas' file. For example, if /home/faculty/hjoe/s445 contains

iris.ssd01

and /home/faculty/hjoe/sasdata contains

customer.ssd01 employee.ssd01 invoice.ssd01 product.ssd01

then put the following into autoexec.sas (in your home directory)

libname s445 '/home/faculty/hjoe/s445'; libname sasdata '/home/faculty/hjoe/sasdata';

By default, SAS starts with

libname sasuse '~/sasuser';

A number of menus from a spreadsheet/database view can be accessed from the toolbar. For example,

  • If you have a directory ~/sasuser in your home directory with a SAS file houses.ssd01, then typing fsview sasuser.houses will bring up data set with menus, from which some SQL can be done from the Search menu. Similarly, fsview sasdata.customer will open sasdata/customer.ssd01. For string variables, you can type 'Where' strings such as empname like 'S%' or empname like '___k' For SQL mistakes, note the "Undo last where" option in the Search menu.

  • Typing fsedit sasdata.customer allows you to edit your SAS data set and re-save. Note that the data comes up in a form with a line for each variable.
  • Typing fsbrowse sasdata.customer leads to the same format of the data set as 'fsedit' but no editing can be done.

  • Typing insight will bring up a menu of your libname's from which you can choose your data set, or if you want to bring up a specific data, type something like insight data=s445.iris

  • You can also bring up s445.iris by going to the Program Editor Window, choose the Globals menu, then Analyze, then Interactive Data Analysis. Then choose s445 as the library (from left panel) and the data set from the right panel, and click the Open button.

Forecast

Why do the smoothing forecasts generated by the Time Series Forecasting System differ from those generated by PROC FORECAST?

The specific methods used in the two approaches differ in two ways. First of all, the Time Series Forecasting System optimizes the smoothing weights for a particular time series while the default smoothing values of PROC FORECAST are constants that do not depend on the data series. (With PROC FORECAST, the user may specify the weights explicitly, overriding the default weights of PROC FORECAST.) Secondly, the Time Series Forecasting System uses a smoothing state initialization different than that of PROC FORECAST. For further details, see pages 225-235 of the SAS/ETS Software: Time Series Forecasting System, Version 6, First Edition and pages 443-450 of the SAS/ETS User's Guide, Version 6, Second Edition. This information is also found in the Version 7 SAS OnlineDoc.

Q: SAS Interactive Matrix Language (IML) Language

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

Go to top

Go back to Howto Home

  • Introduction

    The SAS IML language is a programming language which is used mainly to manipulate numeric and character matrices/vectors. Its grammar is quite similar to that of Splus/R.

    The SAS IML language is a supplement of SAS procedures. If you can use SAS procedures to solve your problems, then you do not need to use IML.

    The SAS IML language can input, create, and output SAS data sets. It also can input and output external files and can produce graphics.

    The SAS IML source code (statements) should be within the procedure proc iml;. Thus the statements cannot contain other SAS procedures (e.g. proc print).

    Go to top

    Go back to Howto Home

  • SAS/IML software

    The SAS/IML software provides a dynamic, interactive environment for programming by the SAS/IML language.

    To run the SAS/IML software,

    1. Login to statlab
    2. Type command sas&

      to run SAS

    3. In the window "SAS: PROGRAM EDITOR", type command: proc iml;
    4. Press the function key F3 to submit the above sas command.

      In the window "SAS: LOG", you will see "IML Ready".

      Now you can program by SAS/IML. The programming process is dynamic which is similar to Splus/R.

      • In Splus/R, you type your statement after the prompt ">". Once you finish typing the statement, you hit the "Enter" key to submit the statement.
      • In SAS, you type your statement in the window "SAS: PROGRAM EDITOR". Once you finish typing the statement, you hit "F3" key to submit the statement.
    5. In the window "SAS: PROGRAM EDITOR", type quit; and press F3 key to quit the SAS/IML interactive programming process.
    6. If you want to print the final results of the statement you submit, you can type reset print; in the window "SAS: PROGRAM EDITOR" before your statement. If you do not want this feature later, you can type reset noprint; to turn it off. The default value is noprint.
    7. In the window "SAS: PROGRAM EDITOR", type quit; and press F3 key to quit the SAS/IML interactive programming process.
    8. If you want to print the both intermediate and final results of the statement you submit, you can type reset printall; in the window "SAS: PROGRAM EDITOR" before your statement. If you do not want this feature later, you can type reset noprintall; to turn it off. The default value is noprintall.

    Like writing Splus/R programs, you also can first write SAS/IML source code in a file, then load it to the window "SAS: PROGRAM EDITOR" (Select File menu and Open submenu to load source code files). Then press F3 to submit it.

    The SAS/IML source code should begin with

    proc iml; and end with quit;

    Go to top

    Go back to Howto Home

  • Some tips of using SAS
    • SAS is NOT case-sensitive. So the name AB is the same as Ab, aB, or ab.
    • The length of names used in SAS can not exceed 8 characters. Names should begin with a letter or underscore. The remaining parts of names can contain letter, underscores and numbers.
    • A number can be expressed in scientific notation such as 1e-6.
    • If the string does not contain blanks and special characters, then you don't need to use quotes.

      If a character string contains blanks, special characters, the string must be enclosed by either single quote (') or double quote (").

      If the string contains quotes (e.g. Can't), then you have to double them (e.g. 'Can''t').

    • A missing value is denoted as a period ".".
    • Any SAS statement is ended with semicolon ";".
    • The comments of SAS programs are enclosed by the pair "/*" and "*/".

      For example,

      /* To print out final results, turn on PRINT */ reset print;
    • Short-cut keys
      KEY DESCRIPTION
      F1 Invoke the online help window.
      F2 Invoke the window to show the short-cut keys defined in SAS.
      F3 Submit SAS statements edited in the "SAS: PROGRAM EDITOR".
      F4 Recall SAS statements from the buffer to the "SAS: PROGRAM EDITOR".

    Go to top

    Go back to Howto Home

  • SAS/IML Basics

    The data objects of SAS/IML are matrices.

    Go to top

    Go back to Howto Home

    Go to top

    Go back to Howto Home

    • Defining a matrix

      A n by p matrix is a n by p table. That is, A n by p matrix has n rows and p columns.

      • The elements of a matrix should have the same type, i.e. either numeric or character, but not mixed.
      • Like Splus/R, the element (the ij-th element say) of a matrix (A say) is expressed by A[i, j]

        The i-th row is expressed by

        A[i,] and the j-th column is expressed by A[,j]

        The expression of the submatrix consisting of the 1, 3 rows and the 2, 4 columns of the matrix A is

        A[{1 3}, {2 4}] or A[{1, 3}, {2, 4}]

      • If A is a p by 1 column vector or a 1 by p row vector, then the i th variable is expressed as A[i]
      • You can not use the statements like the followings to show the values of submatrices/subvectors of a matrix/vector: print A[1, 2]; print A[1,]; print A[,1]; print A[{1 3}, {2 4}];

        You have to first assign the submatrices/subvectors to a variable, then print the variable:

        b1=A[1,2]; b2=A[1,]; b3=A[,1]; b4=A[{1 3}, {2 4}]; print b1, b2, b3, b4, A;
    • Matrix Operations (creation, combining, etc.)
      • To create a scalar (1 by 1 matrix), you don't need to use curly brackets "{}". For example, a=348; /* numeric value */ b="Tom"; /* character value */ c="Yes or No"; /* character value */ d=.; /* missing value */
      • To create a row vector, use curly brackets to enclose its elements. Elements are separated by blanks. For example, a={1.239 43.23 29}; b={"Tom" "Mark" "SAM"}; print a, b;

        The results look like:

        A 1.239 43.23 29 B Tom Mark SAM
      • To create a column vector, use curly brackets to enclose its elements. Elements are separated by commas. For example, a={1.239, 43.23, 29}; b={"Tom", "Mark", "SAM"}; print a, b;

        The results look like:

        A 1.239 43.23 29 B Tom Mark SAM
      • To create a matrix, type the elements by rows and separate each row with comma. For example, a={1 2, 3 4, 5 6}; print a;

        The result looks like:

        A 1 2 3 4 5 6
      • To create a identity matrix, use the SAS/IML inner function I. The syntax is: I(dimension)

        For example,

        I5=I(5); print I5;
      • To create a matrix whose elements are all equal, use the SAS/IML inner function J. The syntax is: J(nrow<,ncol<,value>>) where ncol and value are optional. By default, The statement J(nrow) produces a nrow by nrow matrix whose elements are all 1.

        For example,

        a=J(5); /* a 5x5 matrix whose elements are all 1. */ b=J(5, 3, 21); /* a 5x3 matrix whose elements are all 21. */ print a, b;
      • To create a block diagonal matrix, use the SAS/IML inner function BLOCK. The syntax is: BLOCK(matrix1,<,matrix2<,...,matrix15>)

        For example,

        a=J(1,3); /* a 1x3 matrix whose elements are all equal to 1. */ b=J(2,1,0.5); /* a 2x1 matrix whose elements are all equal to 0.5. */ c=block(a,b); print a, b, c;

        The results look like:

        A 1 1 1 B 0.5 0.5 C 1 1 1 0 0 0 0 0.5 0 0 0 0.5
      • Like in Splus/R, we can produce index vectors in SAS/IML by using the index operator ":". For example, a=1:6; /* produce {1, 2, 3, 4, 5, 6} */ b=90:85; /* produce {90, 89, 88, 87, 86, 85} */ c='a1':'a5'; /* produce {'a1', 'a2', 'a3', 'a4', 'a5'} */
      • SAS/IML have a function (DO function) like the function "seq" in Splus/R. The syntax for the function DO is DO(from, to, by);

        For example,

        a=DO(2, 3, 0.5); /* produce {2, 2.5, 3} */
      • The SAS/IML function "SHAPE" is similar to the Splus/R function "matrix". The syntax is SHAPE(matrix<,nrow<,ncol<,pad-value>>>);

        For example,

        a=SHAPE(1:10, 5, 2); /* produce a 5x2 matrix */ print a; The result is A 5 rows 2 cols (numeric) 1 2 3 4 5 6 7 8 9 10

        If the argument matrix does not provide enough elements to create nrow by ncol matrix, the function SHAPE will fill in the pad-value. For example,

        a=SHAPE(1:3, 5, 2, 0); /* the pad-value is 0 */ print a; The result of the above statements is A 1 2 3 0 0 0 0 0 0 0

        If no pad-value provides, then the function SHAPE will cycles back and repeats values to fill in. For example,

        a=SHAPE(1:3, 5, 2); /* No pad-value is provided */ print a; The result of the above statements is A 1 2 3 1 2 3 1 2 3 1

      • The SAS/IML operators "||" and "//" concatenates matrices horizontally and vertically respectively (They are similar to the Splus/R functions rbind and cbind respectively). For example, a=(1:3)||(4:6); print a; b=(1:3)//(4:6); print b; The results are A 1 row 6 cols (numeric) 1 2 3 4 5 6 B 2 rows 3 cols (numeric) 1 2 3 4 5 6
      • To change the values of an element of a matrix, just assign new value to the element. For example, a[3,9]=0.5;
      • To create a diagonal matrix, you can use the SAS/IML function DIAG. The syntax is DIAG(square matrix/vector); For example, b=diag({1 2 3}); b=diag({1 2, 3 4}); b=diag(3); /* is equivalent to b=3. */
    • Matrix Algebra (+, -, *, transpose, eigenvalues, etc.)

      • In SAS/IML, the basic matrix algebra such as "+, -, *" is simple. For example,

        STATEMENT DESCRIPTION
        c=(A+B); matrix addition
        c=(A-B); matrix subtraction
        c=(A*B); matrix multiplication
        c=(A#B); elementwise multiplication cij=aij*bij.
        c=(A**2); matrix power. A**2 = A*A. Thus, A should be a square matrix.
        c=(A##2); elementwise power. cij=aij*aij.
        c=(A/B); elementwise division. cij=aij/bij.
        c=(A<>B); elementwise maximum. cij=max(aij, bij).
        c=(A><B); elementwise miminmum. cij=min(aij, bij).
        c=(A>=B); elementwise greater than or equal to. cij=1 if aij>= bij. cij=0 if aij<bij;
        c=(A<=B); elementwise less than or equal to. cij=1 if aij<= bij. cij=0 if aij>bij;
        c=(A>B); elementwise greater than. cij=1 if aij> bij. cij=0 if aij<=bij;
        c=(A<B); elementwise less than. cij=1 if aij< bij. cij=0 if aij>=bij;
        c=(A^=B); elementwise not equal to. cij=1 if aij is not equal to bij. cij=0 if aij = bij;
        c=(A=B); elementwise equal to. cij=1 if aij=bij. cij=0 if aij is not equal to bij;
        c=(A#(A>0)); cij=aij if aij>0. cij=0 if aij<=0.

      • The following table lists some commonly used matrix algebra.

        STATEMENT DESCRIPTION
        t(A); or A`; Retrun the transpose of the matrix A. Note the quote is backquote.
        det(A); Return the determinant of the matrix A. Note the matrix A should be square matrix.
        trace(A); Return the trace of the matrix A. Note the matrix A should be square matrix.
        inv(A); Return the inverse of the matrix A. Note the matrix A should be square matrix.
        eigval(A); Return the eigen values of the symmetric matrix A.
        eigvec(A); Return a matrix whose columns correspond to the orthonormal eigenvectors of the symmetric matrix A.
        call eigen(vals, vecs, A); Calculate the eigen values and corresponding orthogonal eigen vectors of the symmetric matrix A. vals stores eigen values and the columns of the matrix vecsstore orthogonal eigen vectors.
        root(A); Performs the Cholesky decomposition of a symmetric and positive definite matrix A, where A=t(B)*B and B is an upper triangular matrix. The statement "root(A);" returns the matrix B.
        solve(A, b); Solves a system of linear equations, where A is a n by n nonsingular square matrix and b is a n by p matrix.
        nrow(A); Return the number of rows of the matrix A.
        ncol(A); Return the number of columns of the matrix A.

      • SAS/IML provides matrix subscript reduction operators to simplify matrix operation. The following table shows their usage:

        STATEMENT DESCRIPTION
        A[+, ]; Get a row vector {sum(A[,1], sum(A[,2],..., sum(A[,p])} whose elements are summation of each column of the matrix A.
        A[ ,+]; Get a column vector {sum(A[1,], sum(A[2,],..., sum(A[p,])} whose elements are summation of each row of the matrix A.
        A[#, ]; Get a row vector whose elements are product of each column of the matrix A.
        A[ ,#]; Get a column vector whose elements are product of each row of the matrix A.
        A[<>, ]; Get a row vector {max(A[,1], max(A[,2],..., max(A[,p])} whose elements are maximum of each column of the matrix A.
        A[ ,<>]; Get a column vector {max(A[1,], max(A[2,],..., max(A[p,])} whose elements are maximum of each row of the matrix A.
        A[><, ]; Get a row vector {min(A[,1], min(A[,2],..., min(A[,p])} whose elements are minimum of each column of the matrix A.
        A[ ,><]; Get a column vector {min(A[1,], min(A[2,],..., min(A[p,])} whose elements are minimum of each row of the matrix A.
        A[<:>, ]; Get a row vector whose elements are indices of the maximum of each column of the matrix A.
        A[ ,<:>]; Get a column vector whose elements are indices of the maximum of each row of the matrix A.
        A[>:<, ]; Get a row vector whose elements are indices of the minimum of each column of the matrix A.
        A[ ,>:<]; Get a column vector whose elements are indices of the minimum of each row of the matrix A.
        A[:, ]; Get a row vector whose elements are the mean of each column of the matrix A.
        A[ ,:]; Get a column vector whose elements are the mean of each row of the matrix A.
        A[##, ]; Get a row vector whose elements are the sum of squares of each column of the matrix A.
        A[ ,##]; Get a column vector whose elements are the sum of squares of each row of the matrix A.

        You can use these operators in both row and column. Row reduction is done first. You also can repeat reduction operators. The following table gives some examples.

        STATEMENT DESCRIPTION
        A[+,<>] Get the maximum of the sums of columns of the matrix A.
        A[{2 6},<>] Get the maximum of the rows of the submatrix A[{2 6},].
        A[ ,<>][+, ] Get the sum of the maximum of the rows of the matrix A.

        For vectors, we also can use these reduction operators. For example,

        A[+]; /* A[+] is equivalent to "A[+,];" if A is a column vector and is equivalent to "A;" if A is row vector. */
  • Modules

    SAS/IML is a programing language. You can define your own modules. There are two kinds of modules. One is function and the other is subroutine.

    Go to top

    Go back to Howto Home

    Go to top

    Go back to Howto Home

    • Functions

      The basic structure of a function in SAS/IML is:

      start function name (arguments); function body return(values of the the function); finish function name;

      For example,

      /* define a function */ start test (x,y); z=3; x=4; y=5; p=6; return(x+y-z-p); finish test; a=1; b=2; p = -0.2143; c=test(a, b); print a, b, p, c;

      The results are:

      A 4 B 5 p -0.2143 C 0

      • The variables (e.g. p and z in the above example) created within a function are local variables. They will not be available outside the function.

        Note that although a variable p is defined before calling the function test, the variable inside test is different from that defined outside test. SAS/IML allocate memories for them separately. For the variable inside test, its memory is temporary. This memory will be recycled after calling the function test.

      • The arguments (e.g. a and b in the above example) of a function are similar to the pointers in C language. If you change their values inside the function, the values remain changed outside the function. In the above example, the values of variables a and b are changed inside the function test. After calling the function test, the values of variables a and bremain changed.
      • A function can return only one data object. Although you can ``return'' more than one data object by defining output as arguments of the function, it's better to use subroutine instead of function in this case.
    • Subroutines

      Subroutines are similar to functions. The main differences are:

      • subroutines do not contain return statement.
      • To call subroutines, you have to use one of the following syntax: call subroutine name (arguments); or run subroutine name (arguments);

      The basic structure of a subroutine in SAS/IML is:

      start subroutine name (arguments); function body finish subroutine name;

      For example,

      /* define a subroutine */ start test2 (c, x,y); z=3; x=4; y=5; p=6; c=x+y-z-p; finish test2; a=1; b=2; p = -0.2143; call test2(c, a, b); print a, b, p, c;

      The results are:

      A 4 B 5 p -0.2143 C 0

    Note that

    • If the function name you defined is the same as the name of an inner function of SAS/IML, then SAS/IML will use the inner function instead of the function you defined.
    • The difference between run and call is how to deal with the case where the subroutine you defined has the same name as an inner subroutines. If you use run to call the subroutine you defined, SAS/IML will call the subroutine you defined. If you use call, SAS/IML will call the inner subroutine.
    • Functions and/or subroutines can be nested into other functions and/or subroutines.
    • If the arguments are used as output, then it's better to put them before those arguments which are used as input.
  • Flow Controls

    Like any other programming language, SAS/IML allows the user to control the path of the execution.

    Go to top

    Go back to Howto Home

    • Go to top

      Go back to Howto Home

    • IF-THEN/ELSE

      The syntax is

      IF expression THEN statement1; ELSE statement2;

      For example,

      if a[k] < mymax then ; /* null statement */ else mymax=a[k];

      Note that IF statements can be nested into other IF statements.

      Go to top

      Go back to Howto Home

    • Do groups

      • Iterative Do statement.

        The syntax is

        DO variable=start TO stop BY increment; statements; END;

        For example,

        DO i=1 to n by 1; a[i]=i; END;

        By default the increment is 1.

      • DO WHILE statement.

        The syntax is

        DO WHILE(expression); statements; END;

        The statements will be executed if the expression is true. For example,

        loop=2; a=1; do while(loop < 100); a=a//loop; /* concatenate vertically */ loop=loop+1; end;

        The above statements produce the column vector {1, 2, ..., 99}.

        Note that the "do while" statement evaluates the expression at the beginning of the loop.

      • DO UNTIL statement.

        The syntax is

        DO UNTIL(expression); statements; END;

        The statements will be executed if the expression is false. For example,

        loop=2; a=1; do until(loop < 100); a=a//loop; /* concatenate vertically */ loop=loop+1; end;

        The above statements produce the column vector {1, 2}.

        Note that "do until" statement evaluates the expression at the bottom of the loop so that the loop always execute at least once.

      • DO DATA statement.

        The "DO DATA" statement is used to read data from external files. It can also be used to process SAS data sets. The syntax is

        DO DATA; statements; END;

        For example,

        infile 'abc.txt'; /* open abc.txt */ do data; input x; /* read a data value */ y = y//x; end; print y;

    • Pause, Resume, Stop and Abort

      • PAUSE statement.

        The syntax is:

        PAUSE <message><*>;

        The "PAUSE" pause the execution of the program. You can enter more statements. Type "RESUME;" to continue execution at the place where the most recent PAUSE statement was executed.

        PAUSE must be used within a module.

        Examples:

        pause "variable x should be numeric! Assign correct value to x, then type RESUME;"; pause *; /* suppress printing any message. */
      • STOP statement.

        The syntax is

        STOP;

        The "STOP" statement is similar to PAUSE.

      • ABORT statement.

        The syntax is

        ABORT;

        The "ABORT" statement stops execution and exits from IML.

  • Read, edit and create SAS data sets

    SAS/IML can create matrices/vectors by reading data from SAS datasets. SAS/IML also can edit and create SAS data sets.

    Go to top

    Go back to Howto Home

    • Go to top

      Go back to Howto Home

    • Read SAS data sets

      To read a SAS data set, abc say, you need to

      1. open the data set by the "use" statement. For example, use abc;

        The syntax of the USE statement is

        USE SAS data set name <VAR variables> <WHERE(expression)>;

      2. read data into a matrix by using the "read" statement. The syntax of the read statement is READ <range> <VAR variables> <WHERE (expression)> <INTO name>; where range specifies which observations (rows) in the SAS data set you want to use. variables specifies which variables (columns) in the SAS data set you want to use

        For example,

        /* "point {1 3}" specifies that the 1st and 3rd observations (rows) of the data set will be read. x, y and sex are variables in the data set. */ read point {1 3} var {x y} where(sex="F") into a; /* "all" specifies that all observations (rows) of the data set will be read. */ read all var {x y} into a;
      3. To close a SAS data set in IML, type close test;

      To show the information of the data set, you can use "SHOW" and "LIST" statements. For example,

      show datasets; /* shows how many data sets are used in IML and which one is currently used */ show contents; /* shows the contents (e.g. type of variables) of the current used data set. */ list all; /* list all observations and all variables of the current used data set. */ list point {3 6} var {x} where(sex="F");

      Go to top

      Go back to Howto Home

    • Edit SAS data sets

      To edit SAS data sets, you need to

      1. use the "EDIT" statement to set the current used SAS data set for both input and output. The syntax of the EDITstatement is EDIT SAS data set name <VAR variables> <WHERE(expression)>;

        For example,

        edit test;

      2. find the observations you want to update by using the "FIND" statement. For example, /* find the row numbers of all observations for Tom and stores the row number into matrix pos. */ find all where(name="Tom") into pos; /* list the value of pos */ print pos; /* list the observation */ list point pos;

      3. update the values. For example, age=20; /* replace Tom's age with 20 */ score=90; /* replace Tom's score with 90 */ replace; /* update the values in the SAS data set */ list point pos; /* list the observation again to check if it is updated */

      You can delete the observations in the SAS data set by using the "DELETE" statement. For example,

      delete; /* delete the current observation */ delete point {1 3}; /* delete the 1st and 3rd observations */ delete all where (name="Tom"); /* delete all observations of Tom */
    • Create SAS data sets

      You can create SAS data sets from matrices. The syntax is as follows:

      CREATE SAS data set name FROM matrix name <[COLNAME=column-name ROWNAME=row-name]>;

      For example,

      a=1:100; create test2 from a [colname="id"]; append;
  • Import from and export to external files

    Go to top

    Go back to Howto Home

    • Go to top

      Go back to Howto Home

    • Import from external files

      The followings show steps to import an external file into SAS/IML:

      1. Assign an alias to the external file by using a FILENAME statement. For example, /* refer "testfile" to the external file "abc.txt". */ /* "testfile" is an alias of "abc.txt". */ filename testfile 'abc.txt';
      2. Open the external file for input by using an INFILE statement. For example, infile testfile;
      3. Set the length of any character variables. For example, name='1':'8'; /* name="12345678"; */ sex='1';
      4. Create a new SAS data set. For example, /* the name of the new SAS data set is "test". */ create test var {name sex score};
      5. Read data by using the "DO DATA" statement and the "INPUT" statement. For example, do data; input name $ sex $ score; append; end;
      6. Close the external file by using the "CLOSEFILE" statement. For example, closefile testfile;
    • Export to external files

      To write a matrix to an external file, you can follow the steps below:

      1. Assign an alias to the external file by using a FILENAME statement. For example, /* refer "testfile" to the external file "abc.txt". */ /* "testfile" is an alias of "abc.txt". */ filename testfile 'abc.txt';
      2. Open the external file for output by using an FILE statement. For example, file testfile;
      3. Output the matrix to the external file by using DO loop and the "PUT" statement. For example, n=nrow(A); p=ncol(A); do i=1 to n; do j=1 to p; /* Output A[i,j] using SAS format 6.4. There are 2 space between A[i,j] and A[i,j+1]. @ instruct IML to put a hold on the current record (row) so that IML can write more to the same record (row). */ put (A[i,j]) 6.4 +2 @; end; /* the symbol "/" instruct IML to start a new record (row) */ put /; end;

      4. Close the external file by using the "CLOSEFILE" statement. For example, closefile testfile;
  • Graphics

    You can draw plots in SAS/IML. To draw a plot in SAS/IML, you can follow the steps below.

    1. Start graphics. /* This is similar to Splus/R function x11() or motif(). But after call gstart, no window will popup. */ call gstart;
    2. Start a new graph. /* instruct IML to erase old graph instead of plotting new graphs on the old graph. */ call gopen;
    3. Define display window. /* define the coordinates of the lower-left and upper-right corners. The range of the data should within this area. Otherwise, IML will not draw data points outside this area. */ x1=0; y1=0; x2=200; y2=200; call gwindow({x1 y1 x2 y2});
    4. Draw points. /* Draw scatter plot of y versus x. Points have diamond shape and green color. */ call gpoint(x, y, "diamond", "green"); /* Connect points by solid green line. */ call gdraw(x, y, 1, "green");
    5. Display the graph. /* A graph window will popup and shows the graph you specified above. */ call gshow;
    Note that
    • By default, the graph does not show border and axes. You have to specify them by the "GPOLY", "GXAXIS" and "GYAXIS" statements.
    • You can add labels in the graph by using the "GSET", "GTEXT" and "GVTEXT" statements.
    • To add title, you can use the "GSCENTER" statement.
    Details can be found in the reference book which is in the computing room of the department.
  • Misc. (loading and storing matrices, etc.)

    To save memory, you can first store matrices into library storage, then release these matrices. If you want to use these matrices again, you can load them from library storage.

    To store matrices, use the "STORE" statement. For example,

    store a b; /* store matrices a and b */

    To release the memory of matrices, use the "FREE" statement. For example,

    free a b;

    To show which matrices in the library storage, use the "SHOW" statement. For example,

    show storage;

    To load matrices from the library storage, use the "LOAD" statement. For example,

    load a b;

Reference:

SAS IML Software: Usage and Reference, Version 6, First Edition. SAS Institute Inc., Cary, NC, USA, 1990.

Q: SAS online for teaching

You can use SAS software online for teaching, provided by SAS.
Detail how to setup and running provided by Dr. Harry Joe: http://www.ugrad.stat.ubc.ca/~hjoe/sas

Q: How to read SAS data files int Splus?

Method 1. 

If you are using SAS version 6.12 in Unix... 


Step 1 
Output SAS data to the desired directory as usual. The file extension using SAS version 6.12 should be .ssd01. Suppose a SAS data file named myfile.ssd01 is located under /home/user/data/

Step 2 
In Splus 3.4 or above, use the function sas.get(). For example, if you want to name the data set as "mydata" in Splus, type the following at the Splus prompt: 

      mylibrary <- "/home/user/data/" 
      mydata <- sas.get(mylibrary,"myfile") 

For more detail, do help(sas.get)

OR 

In Splus 5 or above, use the function importData(). For example, if you want to name the data set as "mydata" in Splus, type the following at the Splus prompt: 

      mydata <- importData("/home/user/data/myfile.ssd01",type="SAS1") 

For more detail, do help(importData)

If you are using SAS version 7 in Unix... 

Step 1 
Output SAS data to the desired directory as usual. The file extension using SAS version 7 should be .sas7bdat. Suppose a SAS data file named myfile.sas7bdat is located under /home/user/data/

Step 2 
In Splus 5 or above, use the function importData(). For example, if you want to name the data set as "mydata" in Splus, type the following at the Splus prompt: 

      mydata <- importData("/home/user/data/myfile.sas7bdat",type="SAS7") 

For more detail, do help(importData)

If you are using SAS version 8 in Unix... see Method 2. 


Method 2 (recommended). Create a transport file from SAS (this works for SAS version 6.12 or above) 

Step 1 
In the SAS code, include the following line when defining SAS libraries: 

      libname sasdata xport "/home/user/data/file.tpt"; 
 

  • "libname" and "xport" are required in the syntax
  • "sasdata" is the user-defined library name
  • "/home/user/data/file.tpt" is the full path name of the transport file (Note the .tpt extension!). "file.tpt" is the file you want to output from SAS and later to be read into Splus


Don't forget to name the file to be outputted in a SAS procedure as "sasdata.file.tpt" in the SAS code!

Step 2 
In Splus 5 or above, use the function importData(). For example, if you want to name the data set as "mydata" in Splus, type the following at the Splus prompt: 

      mydata <- importData("/home/user/data/file.tpt",type="SAS_TPT") 

For more detail, do help(importData)

Note: 
1. Splus 3.4 does not have the importData() function. 
2. The sas.get() function may not read data files created by SAS of version 7 or above. 
3. The importData() function may not read data files from SAS of version 8 even though the file suffix can be the same as version 7 files (.sas7bdat). 
4. For Splus 4+ in Windows, use the import.data() function instead.

Q: Examples with SQL and databases (by Harry Joe)

Examples with SQL and databases (by Harry Joe)

Q: SAS Macro Language

SAS Macro Language


Go back to Howto Home


  • Introduction

    The macro facility is a powerful tool for extending and customizing the SAS System. It is particularly useful if you are to repeat some common tasks in the input data step, etc. Writing a macro in SAS is like writing a function in Splus. With the macro facility, you can assign a name to a character strings or groups of SAS programming statements. When you want to run those programming statements, you can just refer to the name assigned.

    When you use a macro facility name in a SAS program, the macro facility generates SAS statements and commands as needed. The rest of the SAS System receives those statements and uses them in the same way it uses the ones you enter in the standard manner.

    The macro facility has two components:

    1. The macro processor - the portion of the SAS System that does the work. 
    2. The macro language - the syntax that you use to communicate with the macro processor.

    When the SAS System compiles program text, two delimiters trigger macro processor activity:

       &name     refers to a macro variable. The form &name is called a macro variable reference.

       %name     refers to a macro.

    Go to top

    Go back to Howto Home

  • Macro Definition

    The syntax for defining a macro is as follows:    

    %macro macro-name;
    macro-definition 
    %mend macro-name;
     

    Note that in defining a macro, you need to give it a distinct name. You will also need to begin and end the macro with the %macro and %mend statements, respectively. The macro-name specified in the %mend statment must match the macro-name in the %macrostatement. Examples of macros will follow in the later sections.

    Go to top

    Go back to Howto Home

  • Defining Macro Variables

    Macro variables are an efficient way of substituting text strings in SAS code. One way of defining a macro variable is by using the %letstatement to assign the macro variable to a name, and a value.

    For example,

    %let subject=Statistics;



    subject is the macro variable name and Statistics is its value. Assigning a text string to a macro variable does not require quotation marks to embrace the string, as opposed to the standard way of text string assignment to non-macro variables in SAS.

    Later, when you want to create a title for the data set you use for the Statistics 200 course, you would like the text Statistics to appear. To refer to the variable subject, precede the variable name with an ampersand (&) (for macro variable reference):

    title "Data for &subject 200 class";



    The macro processor resolves the reference to the macro variable subject, and the statement becomes

    title "Data for Statistics 200 class;
     
  • An important note: the macro processor resolves macro variables references within DOUBLE quotation marks but NOT within single quotation marks.

    Go to top

    Go back to Howto Home

  • Commenting in Macros

    There are two ways of inserting comments in Macros:

    1. begin with /* and end with */ 
    2. begin with a %* and end with a ;

    An example:


    %macro comment;
      
    /* the first type of commenting */

    %let myvar=abc;

    %* the second type of commenting;
    %let myvar2=xyz;

    %mend comment;

    Go to top

    Go back to Howto Home

  • Invoking a Macro

    The general rule for invoking a macro is to precede the name of the macro with a percent sign (%). Unlike typing a SAS statement, the statement for macro invocation does NOT end in a semicolon.

    In the previous section, we have defined a macro named comment. To invoke the macro, simply do



        %comment
     

    Go to top

    Go back to Howto Home

  • Passing Information into a Macro Using Parameters

    Here we will see the similarity between a macro and a user-defined function in other programming language such as Splus.

    Suppose we are interested in defining a macro which takes in the x and y variables and plot a graph of y versus x. The following macro myplot will do the job:

    %macro myplot(x=,y=);

      proc plot;

    plot &y * &x; 

    title "plot of &y versus &x";

    run;

    %mend myplot;
     

    A macro variable defined in parentheses in a %macro statement is a macro parameter. Macro parameters allow you to pass information into a macro. They are like input arguments in routines in Splus, C/C++, etc.

    To invoke the macro myplot in the above example, you must provide values for the two parameters x and y. Say, you want a graph of income versus age, then do:



        %myplot(x=age,y=income)
     

    where the variables age and income already exist in a SAS data set. The macro processor matches the values specified in the macro call to the parameters in the macro definition. Macro execution produces the following code:


      proc plot;

    plot income * age; 

    title "plot of income versus age";

    run;
     

    Go to top

    Go back to Howto Home

  • Generating Repetitive Pieces of Text Using %DO Loops

    To generate repetitive pieces of text, one can make use of an iterative %DO loop. Suppose you want to list of a series of data sets or variables whose names share a certain pattern. The following macro can reduce the amount of typing in listing the data sets or variables:



    %macro names(name=,count=);


      %do n=1 %to &count;

        
    &name&n

    %end;

    %mend names;
    Say, you are to list 5 data sets named data1, data2, data3, data4 and data5 in your data step, you can do:

      data %names(name=data,count=5);
     

    Macro execution produces the following code:


      data data1 data2 data3 data4 data5;
     

    Note that to concatenate the text string passed to the macro parameter name and the number passed to the macro parameter count, we only need to juxtapose the macro variable references &name and &count.

    However, to concatenate a text string passed to a macro parameter and another text string (the second is not through a macro parameter), we may need the period character (.). See the section of Combining Macro Variable Reference with Text for more detail.

    Go to top

    Go back to Howto Home

  • Combining Macro Variable Reference with Text

    Let us first look at the following piece of SAS code with the use of macros:



    %let name=sales;

    data AB&name.dat;

    set save.&name; 

    if units>100;

    run;
     

    Macro execution produces the following code:


    data ABsalesdat;

    set save.sales;

    if units>100;

    run;
     

    The student who wrote the above code was planning to create a data set named ABsalesdat which was a subset of the data saved in savesales where the units variable in savesales was larger than 100. But the macro execution of his code did not produce his desired output. In particular, save.sales was shown instead of the desired savesales.

    Here is the trick for concatenating text and macro variables:

    1. To precede a text string "string1" with another string assigned to a macro variable mystring, simply juxtapose the first text string (without quotation) with the macro variable reference &mystring, i.e., do

        string1&mystring

    2. To add a suffix "sufstring" to a text string assigned to a macro variable mystring, you will need the period character (.), i.e., do

        &mystring.sufstring

    You can combine the two rules to concatenate more than 2 text strings involving a macro variable. In the above example, execution of AB&name.dat produces a string that precedes the text string "AB" with the macro variable reference &name, which is followed by the suffix "dat". However, the execution of save.&name interprets "." as part of the string "save." and thus concatenates it to the string "sales" from resolving the macro variable reference &name.

    Go to top

    Go back to Howto Home

  • Referencing Macro Variables Indirectly

    Let us consider the following macro:

    %let city1=New York;

    %let city2=Boston;

    %let city3=Seattle;

    %let city4=Las Vegas;

    %macro listcity(count=);
    %do n=1 %to &count;
    &city&n

    %end;

    %mend listcity;
     

    The above macro listcity was written by a student who wanted to save some typing when listing names of US cities. Unfortunately, when he calls the macro to list the first three cities using

      %listcity(count=3)

    SAS macro processor gives an error message saying "macro variable city is not resolved." To understand what has gone wrong, we need to know how the SAS macro processor interprets

      &city&n.

    The macro execution will try to concatenate the two macro variable references &city and &n, while the student wants the concatenation of the text string "city" and the macro variable reference &n completed before the processor references the resulting variables city1city2 and city3.

    To solve the problem, precede &city&n by another ampersand sign (&), i.e.

      &&city&n

    The double ampersands && will be first interpreted as a single & (this & will be kept aside and wait for referencing at a later time), and the concatenation of the text string "city" and the macro variable reference &n will be done prior to referencing the variables city1city2and city3.

    Go to top

    Go back to Howto Home

  • Scope of Macro Variables

    Let us consider the following macro:



    %let datanew=inventory;

    %macro conditn;

    %let dataold=sales;

    %let cond=cases > 0;

    %mend conditn;

    %macro name; 
    %let datanew=report;
    %let dataold= warehse;

    %conditn
    data &datanew;
    set &dataold;

    if &cond;

    run;


    %mend name;
     

    The very first %let statement defines the datanew variable globally. In contrast, all %let statements within macros will define variables locally unless a variable has already been defined in an open code (i.e., not within other macros) prior to its definition within a macro. In the above, the variable datanew reappears in the macro named name. Since this variable is defined earlier in an open code, it remains global throughout the code. The variables dataold and cond are local.

    When we invoke the macro name using

        %name

    the SAS macro processor will give an error message saying "The macro variable cond is not resolved." The problem behind is related to the scope of the macro variables. When the macro name is invoked, the first %let statement assigns the text string "report" to the global datanew variable (it replaces the original assigned string "inventory" by "report"). The second %let statement defines a local variable named dataold and assigns it a value of the text string "warehse". Next, the macro conditn is invoked. Within this macro, the variable cond is defined locally, and the value of the variable dataold is reassigned to the text string "sales". However, after the execution of the statement %conditn, the variable cond no longer exists (because it is local within the macro conditn only!!), so in the if statement in the later data step, the macro variable cond cannot be resolved. The other two variables datanew and dataold in the data step can be resolved because they still exist within the scope of the macro name.

    Indeed, the SAS macro processor interprets the above code upon the invocation of the macro name as follows:

    data report; 
        set sales; 
        if &cond; <-- this gives an error! 
    run;

    Go to top

    Go back to Howto Home

  • Forcing a Macro Variable to be Local

    Sometimes it might be useful to force a variable local within a macro if a (global) variable of the same name has been defined earlier in an open code, e.g. you might not want to alter the value of a global variable throughout the code. Of course, by avoiding the use of a variable name same as that of some global variable, we will not have problems of accidental alteration of the values of global variables.

    The following shows an example when a local definition is necessary:

    %let n=North State Industries;

    %macro namelst(name,number); 
        %do n=1 %to &number; 
            &name&n 
        %end; 
    %mend namelst;

    proc print; 
        var %namelst(dept,5); 
        title "Quarterly Report for &n"; 
    run;

    The macro namelst makes use of a %DO loop (as discussed earlier) for generating repetitive pieces of text (in here, the repetitive pieces are name1name2 and so on).  The variable n is global, as defined in the first %let statement. Within the macro namelst, the variable nserves as a counter. However, when the macro namelst is invoked later in the proc print step, the value of n changes during the execution of the %DO loop. In particular, it is the value of the global variable n that is changed. So in the title statement where referencing the variable n is required, the SAS macro processor will print a title

        "Quarterly Report for 6".

    The macro variable reference 6 is the result of running the %DO loop five times after the invocation of the macro namelst
    One can imagine the desired title should be "Quarterly Report for North State Industries", which can be obtained by forcing the variable n local within the macro namelst. The %local statement is used to keep a variable local; just add the line

        %local n;

    before the %DO loop in the macro namelst. The value of the global variable n (the text string "North State Industries") will not be affected by the change of values of the locally defined variable n within the macro.

    Go to top

    Go back to Howto Home

  • Creating Global Macro Variables

    The %local statement allows one to create local macro variables. Similarly, the %global statement creates a global macro variable if a variable with the same name does not already exist.

    Referring to the example we gave earlier when we discussed the scope of macro variables, the macro variable cond is not resolved during the execution of the data step within the macro name. This is because the variable cond is defined locally within the macroconditn and it does not exist after the execution of this macro. To avoid problems in referencing the macro variable cond in the data step, we can use the %global statement in defining the macro conditn, as follows:



    %macro conditn;

    %global cond;

    %let dataold=sales;
    %let cond=cases > 0;

    %mend conditn;
    Invoking the macro name generates the below statements:


    data report;


    set sales;

    if cases>0;

    run;
     

    Note: You CANNOT use the %global statement to make an existing local variable global!

    If you want to put the data step outside the macro name, then all the macro variables have to be global for the macro processor to resolve the references. You cannot add the macro variable dataold to the %global statement within the macro conditn since the %letstatement in the macro name has already created dataold as a local variable to name by the time conditn begins to execute.

    Go to top

    Go back to Howto Home

Reference:

SAS Macro Language: Reference, First Edition. SAS Institute Inc., Cary, NC, USA, 1997.

Pages