Combining Data Sets Using a One-to-One Match Merge Combining Data Sets Using a One-to-Many Match Merge Merging Summary Statistics with the Original Data Combining a Grand Total with the Original Data Updating a Master Data Set with Transactions Using SAS Data Set Options 186 180

182

184

Tracking and Selecting Observations with the IN= Option Writing Multiple Data Sets Using the OUTPUT Statement

188 190

Making Several Observations from One Using the OUTPUT Statement 192 Changing Observations to Variables Using PROC TRANSPOSE Using SAS Automatic Variables 196 194

10.11 Error: Invalid Option, Error: The Option Is Not Recognized, or Error: Statement Is Not Valid 272 10.12 Note: Variable Is Uninitialized or Error: Variable Not Found 10.13 SAS Truncates a Character Variable 276 274

10.14 SAS Stops in the Middle of a Job 278 10.15 SAS Runs Out of Memory or Disk Space 280

Appendices
A B C D E F Where to Go from Here 284 286

Getting Help from SAS Technical Support An Overview of SAS Products Coming to SAS from SPSS 291 288

Coming to SAS from a Programming Language Coming to SAS from SQL 302

298

Index 309

Acknowledgments
As hard as we have worked on this book, we could never have done it alone. Many people at SAS helped make this book what it is. To our many hard-working reviewers: Carole Beam, Janice Bloom, Brent Cohen, Vicki Leary, Elizabeth Maldonado, Allison McMahill, Sandy McNeill, Randy Poindexter, Morris Vaughan, and Deanna Warner, we say, “Thanks for hanging in there with us.” To our copyeditor, Mary Beth Steinbach, and our designer, Kris Rinne, “Thanks for making us look good.” To our production specialist, Karen Perkins, “Thanks for rectifying all those wayward footnotes, mysterious font errors, and uncooperative images.” And last but not least we would like to thank—faster than a speeding deadline, stronger than Microsoft Word, able to leap tall drafts in a single bound—our editor, Stephenie Joyner. Outside the walls of SAS many other people also contributed to this book. In particular we would like to thank our readers. We love meeting you at conferences even if we seem a little shy. Without you, of course, there would be no reason to keep writing. To her co-workers—Tim Allis, Dana Drennan, Paul Grant, and Steve Nichols—Lora would like to say, “Thanks for being so flexible when I needed to take time off to write.” Most of all we would like to thank our families for their understanding and support.

x

The Little SAS Book

Introducing SASâ Software
SAS software is used by people all over the world—in 118 countries, at over 40,000 sites, by more than 3.5 million users. SAS (pronounced sass) is both a company and software. When people say SAS, they sometimes mean the software running on their computers and sometimes mean the company. People often ask what SAS stands for. Originally the letters S-A-S stood for Statistical Analysis System (not to be confused with Scandinavian Airlines System, San Antonio Shoemakers, or the Society for Applied Spectroscopy). SAS products have become so diverse that a few years back SAS officially dropped the name Statistical Analysis System, now outgrown, and became simply SAS.

SAS products The roots of SAS software reach back to the 1970s when it started out as a software package for statistical analysis, but SAS didn’t stop there. By the mid-1980s SAS had already branched out into graphics, online data entry and compilers for the C programming language. In the 1990s the SAS family tree grew to include tools for visualizing data, administering data warehouses, and building interfaces to the World Wide Web. In the new century, SAS has continued to grow with products for cleansing messy data, and analyzing genetic data. Appendix C, “An Overview of SAS Products,” lists the products available at the time this book was written. Just as AT&T is now more than telephones and telegraphs, SAS is more than statistics. While SAS has a diverse family of products, most of these products are integrated; that is, they can be put together like building blocks to construct a seamless system. For example, you might use SAS/ACCESS software to read data stored in an external database such as Oracle, analyze it using SAS/ETS software (business planning, forecasting, and decision support), and then forward the results in e-mail messages to your colleagues, all in a single computer program.

Operating environments SAS software runs in a wide range of operating environments. You can take a program written on a personal computer and run it on a mainframe after changing only the file-handling statements specific to each operating environment. And because SAS programs are as portable as possible, SAS programmers are as portable as possible too. If you know SAS in one operating environment, you can switch to another operating environment without having to relearn SAS. Licensing SAS products Most SAS software is licensed. Licensing software is like leasing it; once a year you pay your rent. Licensing has one important advantage when compared with buying: you automatically get each new release without an extra charge. Since SAS software is continually being improved and new versions released, licensing is helpful. SAS Learning Edition This modestly priced edition of SAS can be purchased (not licensed). Designed for students and business professionals who are new to SAS, this is a full-featured edition of SAS with some limitations. SAS Learning Edition is limited to 1,000 observations, expires on a specific date, and does not include live technical support. SASware Ballot SAS puts a high percentage of its revenue into research and development, and each year SAS users help determine how that money will be spent by voting on the SASware Ballot. The ballot is a list of suggestions for new features and enhancements. All SAS users are eligible to vote and thereby influence the future development of SAS software. You can even make your own suggestions for the SASware Ballot by mailing them to SAS or by sending e-mail to suggest@sas.com. For further information about the SASware Ballot see support.sas.com/techsup/news/sasware.html.

Introduction

xi

About This Book
Who needs this book This book is for all new SAS users in business, government, and academia, or for anyone who will be conducting data analysis using SAS. You need no prior experience with SAS software, but if you have some experience you may still find this book useful for learning techniques you missed or for reference. What this book covers This book introduces you to the SAS language with lots of practical examples, clear and concise explanations, and as little technical jargon as possible. Most of the features covered here come from Base SAS software, which contains the core of features used by all SAS programmers. One exception is Chapter 8 which includes some procedures from SAS/STAT software. Other exceptions appear in Chapters 2 and 9 which cover importing and exporting data from other types of software; some methods require SAS/ACCESS for PC File Formats software.
We have tried to include every feature of Base SAS software that a beginner is likely to need. Some of you will be surprised that certain topics, such as macros, are included because macros are normally considered advanced. But they appear here because sometimes new users need them. However, that doesn’t mean that you need to know everything in this book. On the contrary, this book is designed so you can read just those sections you need to solve your problems. Even if you read this book from cover to cover, you may find yourself returning to refresh your memory as new programming challenges arise.

What this book does not cover To use this book you need no prior knowledge of SAS, but you must know something about your local computer and operating environment. The SAS language is virtually the same from one operating environment to another, but some differences are unavoidable. For example, every operating environment has a different way of storing and accessing files. Also, some operating environments have more of a capacity for interactive computing than others. Your employer may have rules limiting the size of files you can print. This book addresses operating environments as much as possible, but no book can answer every question about your local system. You must have either a working knowledge of your operating environment or someone you can turn to with questions.
This book is not a replacement for the SAS Help and Documentation, or the many SAS manuals. Sooner or later you’ll need to go to these sources to learn details not covered in this book. The exact documentation available to you depends on which version of SAS you use. Starting with SAS 9, the SAS OnlineDoc has been combined with the system help accessed via the Help menu, giving you more detailed documentation at your fingertips. You can also purchase SAS OnlineDoc on a separate CD. We cover only a few of the many SAS statistical procedures. Fortunately, the statistical procedures share many of the same statements, options, and output, so these few can serve as an introduction to the others. Once you have read Chapter 8, we think that other statistical procedures will feel familiar. Unfortunately, a book of this type cannot provide a thorough introduction to statistical concepts such as degrees of freedom, or crossed and nested effects. There are underlying assumptions about your data that must be met for the tests to be valid. Experimental design and careful

xii

The Little SAS Book

selection of the models are critical. Interpretation of the results can often be difficult and subjective. We assume that readers who are interested in statistical computing already know something about statistics. People who want to use statistical procedures but are unfamiliar with these concepts should consult a statistician, seek out an introductory statistics text, or, better yet, take a course in statistics.

Modular sections Our goal in writing this book is to make learning SAS as easy and enjoyable as possible. Let’s face it¾SAS is a big topic. You may have already spent some time scratching your head in front of a shelf full of SAS manuals, or staring at a screen full of online documentation until your eyes become blurry. We can’t condense all of SAS into this little book, but we can condense topics into short, readable sections.
This entire book is composed of two-page sections, each section a complete topic. This way, you can easily skip over topics which do not apply to you. Of course, we think every section is important, or we would not have included it. You probably don’t need to know everything in this book, however, to complete your job. By presenting topics in short digestible sections, we believe that learning SAS will be easier and more fun¾like eating three meals a day instead of one giant meal a week.

Graphics Wherever possible, graphic illustrations either identify the contents of the section or help explain the topic. A box with rough edges indicates a raw data file, and a box with nice smooth edges indicates a SAS data set. The squiggles inside the box indicate data—any old data—and a period indicates a missing value. The arrow between boxes of these types means that the section explains how to get from data that look like the one box to data that look like the other. Some sections have graphics which depict printed output. These graphics look like a stack of papers with headers printed at the top of the page.

raw data file

SAS data set
Obs 1 2 3 4

SAS output
Lions Tigers Bears

data

Introduction

xiii

Typographical conventions SAS doesn’t care whether your programs are written in uppercase or lowercase, so you can write your programs any way you want. In this book, we have used uppercase and lowercase to tell you something. The statements on the left below show the syntax, or general form, while the statements on the right show an example of actual statements as they might appear in a SAS program.
Syntax PROC PRINT DATA = data-set-name; VAR variable-list; Example PROC PRINT DATA = bigcats; VAR Lions Tigers;

Notice that the keywords PROC PRINT, DATA, and VAR are the same on both sides and that the descriptive terms data-set-name and variable-list on the syntax side have been replaced with an actual data set name and variable names in the example. In this book, all SAS keywords appear in uppercase letters. A keyword is an instruction to SAS and must be spelled correctly. Anything written in lowercase italics is a description of what goes in that spot in the statement, not what you actually type. Anything in lowercase or mixed case letters (and not in italics) is something that the programmer has made up such as a variable name, a name for a SAS data set, a comment, or a title. See section 1.2 for further discussion of the significance of case in SAS names.

Indention This book contains many SAS programs, each complete and executable. Programs are formatted in a way which makes them easy for you to read and understand. You do not have to format your programs this way, as SAS is very flexible, but attention to some of these details will make your programs easier to read. Easy-to-read programs are time-savers for you, or the consultant you hire at $100 per hour, when you need to go back and decipher the program months or years later.
The structure of programs is shown by indenting all statements after the first in a step. This is a simple way to make your programs more readable, and it’s a good habit to form. SAS doesn’t really care where statements start or even if they are all on one line. In the following program, the INFILE and INPUT statements are indented, indicating that they belong with the DATA statement: * Read animals’ weights from file. Print the results.;
DATA animals; INFILE ’c:\MyRawData\Zoo.dat’; INPUT Lions Tigers; PROC PRINT DATA = animals; RUN;

Last, we have tried to make this book as readable as possible and, we hope, even enjoyable. Once you master the contents of this small book you will no longer be a beginning SAS programmer.

What’s New
This third edition of The Little SAS Book: A Primer includes features added since SAS 7—and there are a lot of them. When we wrote the second edition, the basic structure of the Output Delivery System (ODS) was in place, but few of its features were. Since then, flesh has been added to the bones and ODS now has a multitude of destinations and options. So, we have added a new chapter devoted entirely to ODS. Exporting data is another greatly expanded topic. In previous editions we had a few scattered sections describing how to get data out of SAS for use in other applications, but the number of ways and number of types of files you can create has grown to the point that we felt a need to give these topics a chapter all their own. Other new topics are sprinkled throughout the book. For the first time we have included PROC REPORT. In addition, we’ve expanded our coverage of the SAS Explorer window, the IMPORT and EXPORT Wizards, Dynamic Data Exchange (DDE), direct-referencing of SAS data sets, and PROC TABULATE. We’ve added more system options, and a section on advanced input with the @’character’ column pointer and the colon modifier. Most of the features in this edition are available with SAS 8.2; a few are new with SAS 9 or SAS 9.1. We have tried to point out whenever a feature is new. So unless otherwise noted, you can assume that everything in this book is available in SAS 8.2. Here, listed by section, are the new topics:

The Output Delivery System
Section 5.1 5.2 5.3 5.4-5.6 5.7 5.8-5.10 5.11 5.12 Feature Basic concepts for understanding ODS. ODS TRACE and ODS SELECT statements allow you to choose which parts of output will be printed. ODS OUTPUT statement allows you to save results from SAS procedures as SAS data sets. HTML, RTF, and PRINTER output can be created using ODS statements. Titles and footnotes can be customized using the COLOR=, BCOLOR=, HEIGHT=, JUSTIFY=, FONT=, BOLD, and ITALIC options. STYLE= option in PROC PRINT, PROC REPORT, and PROC TABULATE allows you to control almost any aspect of the appearance of your output. Traffic-lighting draws attention to important values in reports by determining the style of a cell based on its value. Table of selected style attributes shows some of the most popular features that you can control.

Introduction

xv

Exporting data
Section 9.1 9.2 9.4 9.6 9.7 Feature Choices for exporting data are outlined. Export Wizard is now the topic of a complete section. PROC EXPORT can write files in Microsoft Excel or Microsoft Access formats. ODS HTML and CSV can be used to create data for other applications. (ODS CSV is new with SAS 9.) Cross-Environment Data Access allows SAS to read SAS data sets created in other operating environments.

PROC REPORT
Section 4.17 4.18 4.19 4.20 4.21 Feature PROC REPORT allows you to create both detail and summary reports. DEFINE statement in PROC REPORT allows you to specify options for individual variables determining how they will be used in the report. GROUP and ACROSS usage types can be used to create summary groups in rows or columns. BREAK and RBREAK statements add summary breaks to PROC REPORT output. Statistics can be requested in a COLUMN statement in PROC REPORT.

More on PROC TABULATE
Section 4.14 4.15 4.16 Feature FORMAT=, BOX=, and MISSTEXT= options in PROC TABULATE enhance the appearance of your output. Changing headers in a TABLE statement in PROC TABULATE creates a more customized look. FORMAT= option in a TABLE statement in PROC TABULATE allows you to specify multiple formats for data cells.

Also new with this edition
Section 1.5, 8.9 1.10 Feature SAS Enterprise Guide provides a graphical user interface to many of the features of SAS including statistical procedures. HTML output can be easily created by changing a setting in the Preferences window. HTML results appear in the Results Viewer window.

xvi

The Little SAS Book

1.11, 1.12 1.13

SAS Explorer window allows you to create new SAS libraries and display SAS data sets and their properties in a point-and-click environment. ORIENTATION=, RIGHTMARGIN=, LEFTMARGIN=, TOPMARGIN=, and BOTTOMMARGIN= system options give you more control over how your output looks. Import Wizard is now the topic of a complete section. @’character’ column pointer and colon modifier make it possible to read messy raw data such as web logs. Dynamic Data Exchange is now the topic of a complete section. Direct-referencing of permanent SAS data sets is now the topic of a complete section. Names for user-defined formats can be up to 32 characters long, beginning with SAS 9.

2.3 2.10 2.18 2.21 4.7

1

‘‘ ’’

An honest tale speeds best being plainly told.
WILLIAM SHAKESPEARE, KING RICHARD III

1.1 The SAS Language
Many software applications are either menu driven, or command driven (enter a command¾see the result). SAS is neither. With SAS, you use statements to write a series of instructions called a SAS program. The program communicates what you want to do and is written using the SAS language. There are some menu-driven front ends to SAS, for example SAS Enterprise Guide software, which make SAS appear like a point-and-click program. However, these front ends still use the SAS language to write programs for you. You will have much more flexibility using SAS if you learn to write your own programs using the SAS language. Maybe learning a new language is the last thing you want to do, but be assured that although there are parallels between SAS and languages you know (be they English or FORTRAN), SAS is much easier to learn.

SAS programs A SAS program is a sequence of statements executed in order. A statement gives information or instructions to SAS and must be appropriately placed in the program. An everyday analogy to a SAS program is a trip to the bank. You enter your bank, stand in line, and when you finally reach the teller’s window, you say what you want to do. The statements you give can be written down in the form of a program:
I would like to make a withdrawal. My account number is 0937. I would like $200. Give me five 20s and two 50s.

Note that you first say what you want to do, then give all the information the teller needs to carry out your request. The order of the subsequent statements may not be important, but you must start with the general statement of what you want to do. You would not, for example, go up to a bank teller and say, “Give me five 20s and two 50s.” This is not only bad form, but would probably make the teller’s heart skip a beat or two. You must also make sure that all the subsequent statements belong with the first. You would not say, “I want the largest box you have” when making a withdrawal from your checking account. That statement belongs with “I would like to open a safe deposit box.” A SAS program is an ordered set of SAS statements like the ordered set of instructions you use when you go to the bank.

SAS statements As with any language, there are a few rules to follow when writing SAS programs. Fortunately for us, the rules for writing SAS programs are much fewer and simpler than those for English.
The most important rule is

Every SAS statement ends with a semicolon.
This sounds simple enough. But while children generally outgrow the habit of forgetting the period at the end of a sentence, SAS programmers never seem to outgrow forgetting the semicolon at the end of a SAS statement. Even the most experienced SAS programmer will at least occasionally forget the semicolon. You will be two steps ahead if you remember this simple rule.

Chapter 1: Getting Started Using SAS Software

3

Layout of SAS programs There really aren’t any rules about how to format your SAS program. While it is helpful to have a neat looking program with each statement on a line by itself and indentions to show the various parts of the program, it isn’t necessary.
¨ ¨ ¨ ¨ SAS statements can be in upper- or lowercase. Statements can continue on the next line (as long as you don’t split words in two). Statements can be on the same line as other statements. Statements can start in any column.

So you see, SAS is so flexible that it is possible to write programs so disorganized that no one can read them, not even you. (Of course, we don’t recommend this.)

Comments To make your programs more understandable, you can insert comments into your programs. It doesn’t matter what you put in your comments¾SAS doesn’t look at it. You could put your favorite cookie recipe in there if you want. However, comments are usually used to annotate the program, making it easier for someone to read your program and understand what you have done and why.
There are two styles of comments you can use: one starts with an asterisk (*) and ends with a semicolon (;). The other style starts with a slash asterisk (/*) and ends with an asterisk slash (*/). The following SAS program shows the use of both of these style comments:
* Read animals’ weights from file; DATA animals; INFILE ’c:\MyRawData\Zoo.dat’; INPUT Lions Tigers; PROC PRINT DATA = animals; /* Print the results */ RUN;

Since some operating environments interpret a slash asterisk (/*) in the first column as the end of a job, be careful when using this style of comment not to place it in the first column. For this reason, we chose the asterisk-semicolon style of comment for this book.

Errors People who are just learning a programming language often get frustrated because their programs do not work correctly the first time they write them. To make matters worse, SAS errors often come up in bright red letters, and for the poor person whose results turn out more red than black, this can be a very humbling experience. You should expect errors. Most programs simply don’t work the first time, if for no other reason than you are human. You forget a semicolon, misspell a word, have your fingers in the wrong place on the keyboard. It happens. Often one small mistake can generate a whole list of errors. Don’t panic if you see red.

4

The Little SAS Book

1.2

SAS Data Sets
Before you run an analysis, before you write a report, before you do anything with your data, SAS must be able to read your data. Before SAS can analyze your data, the data must be in a 1 special form called a SAS data set. Getting your data into a SAS data set is usually quite simple as SAS is very flexible and can read almost any data. Once your data have been read into a SAS data set, SAS keeps track of what is where and in what form. All you have to do is specify the name and location of the data set you want, and SAS figures out what is in it.

Variables and observations Data, of course, are the primary constituent of any data set. In traditional SAS terminology the data consist of variables and observations. Adopting the terminology of relational databases, SAS data sets are also called tables, observations are also called rows, and variables are also called columns. Below you see a rectangular table containing a small data set. Each line represents one observation, while Id, Name, Height, and Weight are variables. The data point Charlie is one of the values of the variable Name and is also part of the second observation.
Variables (Also Called Columns) Id 1 2 Observations (Also Called Rows) 3 4 5 6 53 54 55 56 57 58 Name Susie Charlie Calvin Lucy Dennis Height 42 46 40 46 44 43 Weight 41 55 35 52 . 50

Data types Raw data come in many different forms, but SAS simplifies this. In SAS there are just two data types: numeric and character. Numeric fields are, well, numbers. They can be added and subtracted, can have any number of decimal places, and can be positive or negative. In addition to numerals, numeric fields can contain plus signs (+), minus signs (-), decimal points (.), or E for scientific notation. Character data are everything else. They may contain numerals, letters, or special characters (such as $ or !) and can be up to 32,767 characters long. If a variable contains letters or special characters, it must be character data. However, if it contains only numbers, then it may be numeric or character. You should base your decision on how you will 2 use the variable. Sometimes data that consist solely of numerals make more sense as character data than as numeric. ZIP codes, for example, are made up of numerals, but it just doesn’t make sense to add, subtract, multiply, or divide ZIP codes. Such numbers make more sense as character data. In the previous data set, Name is obviously a character variable, and Height and Weight are numeric. Id, however, could be either numeric or character. It’s your choice.

1

There are exceptions. If your data are in a format written by another software product, you may be able to read your data directly without creating a SAS data set. For database management systems and spreadsheets, you may be able to use SAS/ACCESS software. See chapter 2 for more information. For SPSS you can use the SPSS data engine. See appendix D. If disk space is a problem, you may also choose to base your decision on storage size. You can use the LENGTH statement, discussed in section 10.15, to control the storage size of variables.

2

Chapter 1: Getting Started Using SAS Software

5

Missing data Sometimes despite your best efforts, your data may be incomplete. The value of a particular variable may be missing for some observations. In those cases, missing character data are represented by blanks, and missing numeric data are represented by a single period (.). In the preceding data set, the value of Weight for observation 5 is missing, and its place is marked by a period. The value of Name for observation 6 is missing and is just left blank. Size of SAS data sets Prior to SAS 9.1, SAS data sets could contain up to 32,767 variables. Beginning with SAS 9.1, the maximum number of variables in a SAS data set is limited by the resources available on your computer¾but SAS data sets with more than 32,767 variables cannot be used with earlier versions of SAS. The number of observations, no matter which version of SAS you are using, is limited only by your computer’s capacity to handle and store them. Rules for SAS names You make up names for the variables in your data and for the data sets themselves. It is helpful to make up names that identify what the data represent, especially for variables. While the variable names A, B, and C might seem like perfectly fine, easy-to-type names when you write your program, the names Sex, Height, and Weight will probably be more helpful when you go back to look at the program six months later. Follow these simple rules when making up names for variables and data set members:
¨ ¨ ¨ ¨ Names must be 32 characters or fewer in length.
3

Names must start with a letter or an underscore ( _ ). Names can contain only letters, numerals, or underscores ( _ ). No %$!*@, please. Names can contain upper- and lowercase letters.
4

This last point is an important one. SAS is insensitive to case so you can use uppercase, lowercase or mixed case¾whichever looks best to you. SAS doesn’t care. The data set name heightweight is the same as HEIGHTWEIGHT or HeightWeight. Likewise, the variable name BirthDate is the same as BIRTHDATE and birThDaTe. However, there is one difference for variable names. SAS remembers the case of the first occurrence of each variable name and uses that case when printing results. That is why, in this book, we use mixed case for variable names but lowercase for other SAS names.

Documentation stored in SAS data sets In addition to your actual data, SAS data sets contain information about the data set such as its name, the date that you created it, and the version of SAS you used to create it. SAS also stores information about each variable, including its name, type (numeric or character), length (or storage size), and position within the data set. This information is sometimes called the descriptor portion of the data set, and it makes SAS data sets self-documenting.

Beginning with SAS 9, format names can also be 32 characters long, and informat names can be 31 characters (including the $ for character values). Prior to SAS 9, format names could be 8 characters while informat names could be 7 characters (also including the $). Librefs and filerefs must be 8 characters or fewer in length, and member names for versioned data sets must be 28 characters or fewer.
4

3

It is possible to use special characters, including spaces, in variable names if you use the system option VALIDVARNAMES=ANY and a name literal of the form ‘variable-name’N. See the SAS Help and Documentation for details.

6

The Little SAS Book

1.3

The Two Parts of a SAS Program
SAS programs are constructed from two basic building blocks: DATA steps and PROC steps. A typical program starts with a DATA step to create a SAS data set and then passes the data to a PROC step for processing. Here is a simple program that converts miles to kilometers in a DATA step and prints the results with a PROC step:

DA

TA

PROC
DATA and PROC steps are made up of statements. A step may have as few as one or as many as hundreds of statements. Most statements work in only one type of step¾in DATA steps but not PROC steps, or vice versa. A common mistake made by beginners is to try to use a statement in the wrong kind of step. You’re not likely to make this mistake if you remember that DATA steps read and modify data while PROC steps analyze data, perform utility functions, or print reports. DATA steps start with the DATA statement, which starts, not surprisingly, with the word DATA. This keyword is followed by a name that you make up for a SAS data set. The DATA step above produces a SAS data set named DISTANCE. In addition to reading data from external, raw data files, DATA steps can include DO loops, IF-THEN/ELSE logic, and a large assortment of numeric and character functions. DATA steps can also combine data sets in just about any way you want, including concatenation and match-merge. Procedures, on the other hand, start with a PROC statement in which the keyword PROC is followed by the name of the procedure (PRINT, SORT, or MEANS, for example). Most SAS procedures have only a handful of possible statements. Like following a recipe, you use basically the same statements or ingredients each time. SAS procedures do everything from simple sorting and printing to analysis of variance and 3D graphics. Other SAS procedures perform utility functions such as importing data files and data entry. A step ends when SAS encounters a new step (marked by a DATA or PROC statement), a RUN 1 statement, or, if you are running in batch mode, the end of the program. RUN statements tell SAS to run all the preceding lines of the step and are among those rare, global statements that are not part of a DATA or PROC step. In the program above, SAS knows that the DATA step has ended when it reaches the PROC statement. The PROC step ends with a RUN statement, which coincides with the end of the program.

1

If you use SAS long enough, you may run into an exception. Steps can also terminate with a QUIT, STOP, or ABORT statement.

Chapter 1: Getting Started Using SAS Software

7

While a typical program starts with a DATA step to input or modify data and then passes the data to a PROC step, that is certainly not the only pattern for mixing DATA and PROC steps. Just as you can stack building blocks in any order, you can arrange DATA and PROC steps in any order. A program could even contain only DATA steps or only PROC steps. To review, the table below outlines the basic differences between DATA and PROC steps:
DATA steps begin with DATA statements read and modify data create a SAS data set PROC steps begin with PROC statements perform specific analysis or function produce results or report

As you read this table, keep in mind that it is a simplification. Because SAS is so flexible, the differences between DATA and PROC steps are, in reality, more blurry. The table above is not meant to imply that PROC steps never create SAS data sets (many do), or that DATA steps never produce reports (they can). Nonetheless, you will find it much easier to write SAS programs if you understand the basic functions of DATA and PROC steps.

8

The Little SAS Book

1.4

The DATA Step’s Built-in Loop
DATA steps read and modify data, and they do it in a way that is flexible, giving you lots of control over what happens to your data. However, DATA steps also have an underlying structure, an implicit, built-in loop. You don’t tell SAS to execute this loop: SAS does it automatically. Memorize this:

DATA steps execute line by line and observation by observation.
This basic concept is rarely stated explicitly. Consequently, new users often grow into old users before they figure this out on their own. The idea that DATA steps execute line by line is fairly straightforward and easy to understand. It means that, by default, SAS executes line one of your DATA step before it executes line two, and line two before line three, and so on. That seems common sense, and yet new users frequently run into problems because they try to use a variable before they create it. If a variable named Z is the product of X and Y, then you better make sure that the statements creating X and Y come before the statements creating Z. What is not so obvious is that while DATA steps execute line by line, they also execute observation by observation. That means SAS takes the first observation and runs it all the way through the DATA step (line by line, of course) before looping back to pick up the second observation. In this way, SAS sees only one observation at a time. Imagine a SAS program running in slow motion: SAS reads observation number one from your input data set. Then SAS executes your DATA step using that observation. If SAS reaches the end of the DATA step without encountering any serious errors, then SAS writes the current observation to a new, output data set and returns to the beginning of the DATA step to process the next observation. After the last observation has been written to the output data set, SAS terminates the DATA step and moves on to the next step, if there is one. End of slow motion; please return to normal megahertz. This diagram illustrates how an observation flows through a DATA step: input data set observation 1 observation 2 observation 3 DATA step line 1 line 2 line 3 line 4 line 5 output data set observation 1 observation 2 observation 3

Chapter 1: Getting Started Using SAS Software

9

SAS reads observation number one and processes it using line one of the DATA step, then line two, and so on until SAS reaches the end of the DATA step. Then SAS writes the observation in the output data set. This diagram shows the first execution of the line-by-line loop. Once SAS finishes with the first observation, it loops back to the top of the DATA step and picks up 1 observation two. When SAS reaches the last observation, it automatically stops. Here is an analogy. DATA step processing is a bit like voting. When you arrive at your polling place, you stand in line behind other people who have come to vote. When you reach the front of the line you are asked standard questions: “What is your name? Where do you live?” Then you sign your name, and you cast your vote. In this analogy, the people are observations, and the voting process is the DATA step. People vote one at a time (or observation by observation). Each voter’s choices are secret, and peeking at your neighbor’s ballot is definitely frowned upon. In addition, each person completes each step of the process in the same order (line by line). You cannot cast your vote before you give your name and address. Everything must be done in the proper order.

1

If this seems a bit too structured, don’t worry. You can override the line-by-line and observation-by-observation structure in a number of ways. For example, you can use the RETAIN statement, discussed in section 3.9, to make data from the previous observation available to the current observation. You can also use the OUTPUT statement, discussed in sections 6.11 and 6.12, to control when observations are written to the output data set.

10

The Little SAS Book

1.5

Choosing a Mode for Submitting SAS Programs
So far we have talked about writing SAS programs, but simply writing a program does not give you any results. Just like writing a letter to your representative in Congress does no good unless you mail it, a SAS program does nothing until you submit or execute it. You can execute a SAS program several ways, but not all methods are available for all operating environments. Check in the SAS Help and Documentation for your operating environment or with your SAS Support Consultant to find out which methods are available to you. The method you choose for executing a SAS program will depend on your preferences and on what is most appropriate for your application and your environment. If you are using SAS at a large site with many users, then ask around and find out which is the most accepted method of executing SAS. If you are using SAS on your own personal computer, then choose the method that suits you.

SAS windowing environment If you type SAS at your system prompt, or click on the SAS icon, you will most likely get into the SAS windowing environment. In this interactive environment, you can write and edit SAS programs, submit programs for processing, and view and print your results. In addition, there are many SAS windows for performing different tasks such as managing SAS files, customizing the interface, accessing SAS Help, and importing or exporting data. Exactly what your windowing environment looks like depends on the type of computer or terminal you are using, the operating environment on the computer, and what options are in effect when you start up SAS. If you are using a personal computer, then the SAS windowing environment will look similar to other programs on your computer, and many of the features will be familiar to you. SAS Enterprise Guide If you have SAS Enterprise Guide 1 software, which runs only under Windows, you may choose to submit your programs from within SAS Enterprise Guide. To do this, use the Insert menu to open a Code window where you can either enter your SAS program or open an existing SAS program. Then you can choose to run your code on the local machine, or on a remote server where SAS is installed. To run your SAS program on a remote server, you must have SAS Integration Technologies software installed. Also, SAS Enterprise Guide can write SAS code for you through its extensive menu system. Noninteractive mode Noninteractive mode is where your SAS program statements are in a file on your system, and you start up SAS specifying that you want to execute that file. SAS immediately starts to process your file and ties up your computer, or window, until it is finished. The results are usually placed in a file or files, and you are returned to your system prompt. Noninteractive mode is useful in many situations. This mode is good if you want your program to execute immediately, but you do not want
Beginning with SAS 9, SAS Enterprise Guide software is included with Base SAS software, but is installed separately. SAS Enterprise Guide software is also available with SAS Version 8, but is licensed separately.
1

Chapter 1: Getting Started Using SAS Software

11

to or cannot use a windowing environment. Noninteractive mode is usually started by typing SAS at your system prompt (shown here as $), followed by the filename containing your program statements:
$ SAS MyFile.sas

Batch or background mode With batch or background mode, your SAS program is in a file. You submit the file for processing with SAS. Your SAS program may start executing immediately, or it could be put in a queue behind other jobs. Batch processing is used a lot on mainframe computers, which are capable of executing many processes at one time. You can continue to work on your computer while your job is being processed, or better yet, you can go to the baseball game and let the computer work in your absence. Batch processing is usually less expensive than other methods and is especially good for large jobs which can be set up to execute at off hours when the rates are at their lowest. When your job is complete, the results will be placed in a file or files, which you can display or print at any time.
Batch processing may not be available for your operating environment. Check the SAS Help and Documentation for your operating environment to see if it is available, then check with your SAS Support Consultant to find out how to submit SAS programs for batch processing. Even sites with the same operating environment may have different ways of submitting jobs in batch mode.

Remote submit If you have SAS/CONNECT software, it is possible to write and develop your SAS programs on one system, then submit them for processing on another. Using this method, you write your program on your local machine, establish a connection to the remote machine, and run the program on the remote machine. Then the results are delivered back to your local machine. You might want to do this if your remote machine is much more powerful than your local machine, and you are running very large programs. Also, you might need to access large or shared data files on the remote machine. Check with your SAS Support Consultant to find out if this is an option at your site.

Interactive line mode This mode is mentioned only because you might see it in the SAS documentation, and you might get into it by accident. In interactive line mode, you are prompted for SAS statements one line at a time. There is no easy way to correct mistakes once you have entered them, so unless you are an excellent typist, and an excellent programmer, interactive line mode is exceedingly frustrating.
If you do find yourself in this mode (you will know when you get a 1? as a prompt), you can get out by typing ENDSAS; and pressing ENTER. For example
1? ENDSAS;

Seek assistance from your SAS Support Consultant to find out why you got into line mode and how to avoid it in the future.

12

The Little SAS Book

1.6

Windows and Commands in the SAS Windowing Environment
It used to be that SAS looked pretty much the same on all platforms, and you couldn’t change its appearance. But now SAS adopts the look and feel of your operating environment, and there are many ways in which you can customize your SAS environment. This is good for you because many aspects of the SAS windowing environment will be familiar, and if you don’t like the default view, you can change it. It makes writing about it more difficult, because we can’t tell you exactly what your SAS session will look like and how it will behave. However, there are many common elements between the various operating environments, and you will probably already be familiar with those elements which are different.

The SAS Windows
There are five basic SAS windows: the Results and Explorer windows, and three programming windows: Editor, Log, and Output. It is possible to bring up SAS without all these windows, and sometimes the windows are not immediately visible (for example, in the Windows operating environment, the Output window comes up behind the Editor and Log windows), but all these windows do exist in your SAS session. There are also many other SAS windows that you may use for tasks such as getting help, changing SAS system options, and customizing your SAS session. The following figure shows the default view for a Microsoft Windows SAS session, with pointers to the five main SAS windows.

Editor This window is a text editor. You can use it to type in, edit, and submit SAS programs as well as edit other text files such as raw data files. In Windows operating environments, the default editor is the Enhanced Editor. The Enhanced Editor is syntax sensitive and color codes your programs making it easier to read and find mistakes. The Enhanced Editor also allows you to collapse and expand the various steps in your program. For other operating environments, the default editor is the Program Editor whose features vary with the version of SAS and operating environment.

Chapter 1: Getting Started Using SAS Software

13

Log The Log window contains notes about your SAS session, and after you submit a SAS program, any notes, errors, or warnings associated with your program as well as the program statements themselves will appear in the Log window.

Output If your program generates any printable results, then they will appear in the Output window. Results The Results window is like a table of contents for your Output window; the results tree lists each part of your results in an outline form.

The SAS Commands
There are SAS commands for performing a variety of tasks. Some tasks are probably familiar, such as opening and saving files, cutting and pasting text, and accessing Help. Other commands are specific to the SAS System, such as submitting a SAS program, or starting up a SAS application. You may have up to three ways to issue commands: menus, the toolbar, or the SAS command bar (or command line). The following figure shows the location of these three methods of issuing SAS commands in the Windows operating environment default view.

Pull-down Menus

SAS Command Bar

Toolbar

Menus Most operating environments will have pull-down menus located either at the top of each window, or at the top of your screen. If your menus are at the top of your screen, then the menus will change when you activate the different windows (usually by clicking on them). You may also have, for each window, context-sensitive pop-up menus that appear when you press the right or center button of your mouse.

Toolbar The toolbar, if you have one, gives you quick access to commands that are already accessible through the pull-down menus. Not all operating environments have a toolbar. SAS command bar The command bar is a place that you can type in SAS commands. In some operating environments the command bar is located with the toolbar (as shown here); in other operating environments you may have a command line with each of the SAS windows (usually indicated by Command=>). Most of the commands that you can type in the command bar are also accessible through the pull-down menus or the toolbar. Controlling your windows The Window pull-down menu gives you choices on how the windows are placed on your screen. You can also activate any of the programming windows by selecting it from the Window pull-down menu, typing the name of the window in the command line area of your SAS session, or simply clicking on the window.

14

The Little SAS Book

1.7

Submitting a Program in the SAS Windowing Environment
Naturally after going to the trouble of writing SAS programs, you want to see some results. As we have already discussed, there are several ways of submitting SAS programs. If you use the SAS windowing environment, then you can edit and submit programs, and see results all within the windowing environment.

Getting your program into the editor The first thing you need to do is get your program into the Editor window. You can either type your program into the editor, or you can bring the program into the Editor window from a file. The commands for editing in the editor and for opening files should be familiar. SAS tries to follow conventions that are common for your operating environment. For example, to open a file in the editor, you can select Open from the File pull-down menu. For some operating environments you may have an Open icon on the toolbar, and you may also have the option of pasting your file into the editor from the clipboard. Submitting your program Once your program appears in the editor, you execute it using the SUBMIT command. Depending on your operating environment, you have a few choices on how to execute the SUBMIT command.
Use the Submit icon on the toolbar. Make the Editor window active and enter SUBMIT in the command line area of your SAS session. Make the Editor window active and select Submit from the Run pull-down menu.

The figure to the right shows a program in the Enhanced Editor in the Windows operating environment ready to be submitted using the Submit icon on the toolbar.

Chapter 1: Getting Started Using SAS Software

15

Viewing the SAS Log and Output If you are using the Enhanced Editor (Windows operating environment), after you submit your program, the program remains in the Enhanced Editor window and the results of your program go into the Log and Output windows. If you are using the Program Editor (all other operating environments) then your results also go into the Log and Output windows, but your program disappears from the Program Editor window. At first it may be a shock for you to see your program disappear in front of your eyes. Don’t worry; the program you spent so long writing is not gone forever. If your program produced any output, then you will also get new entries in the Results window. The Results window is like a table of contents for your SAS output and is discussed in more detail in section 1.9. This figure is an example of what your screen might look like after you submit a program from the Enhanced Editor.
You may not see all three of the programming windows (Editor, Log, and Output) at the same time. In some operating environments, the windows are placed one on top of the other. You can bring a window to the top by clicking on it, typing its name in the command line area, or selecting it from the Window menu.

Getting your program back
Unfortunately for most of us, our programs do not run perfectly every time. If you have an error in your program, you will most likely want to edit the program and run it again. If you are using the Program Editor window, you will need to get your program back in the Program Editor window using the RECALL command. You have two choices for executing the RECALL command. Make the Program Editor the active window, then enter RECALL in the command line area of your SAS session.

Make the Program Editor the active window, then select Recall Last Submit from the Run pull-down menu.

The RECALL command will bring back the last block of statements you submitted. If you use the RECALL command again, it will insert the block of statements submitted before the last one, and so on and so on, until it retrieves all the statements you submitted.

16

The Little SAS Book

1.8

Reading the SAS Log
Every time you run a SAS job, SAS writes messages in your log. Many SAS programmers ignore the SAS log and go straight to the output. That’s understandable, but dangerous. It is possible¾and sooner or later it happens to all of us¾to get bogus results that look fine in the output. The only way to know they are bad is to check the SAS log. Just because it runs doesn’t mean it’s right.

Where to find the SAS log The location of the SAS log varies depending on the operating environment you use, the mode you use (SAS windowing environment, noninteractive, or batch), and local settings. If you submit a program in the windowing environment, you will, by default, see the SAS log in your Log window as in the following figure.
If you submit your program in batch or noninteractive mode, the log will be written to a file that you can view or print using your operating environment’s commands for viewing and printing. The name given to the log file is generally some permutation of the name you gave the original program. For example, if you named your SAS program Marathon.sas, then it is a good bet that your log file will be Marathon.log. At some installations the log and output files are written to a single file, so don’t be surprised if you find them together.

What the log contains People tend to think of the SAS log as either a rehash of their program or as just a lot of gibberish. OK, we admit, there is some technical trivia in the SAS log, but there is also plenty of important information. Here is a simple program that converts miles to kilometers and prints the result:
* Create a SAS data set named distance; * Convert miles to kilometers; DATA distance; Miles = 26.22; Kilometers = 1.61 * Miles; * Print the results; PROC PRINT DATA = distance; RUN;

The SAS log above is a blow-by-blow account of how SAS executes the program.  It starts with notes about the version of SAS and your SAS site number.

 It contains the original program statements with line numbers added on the left.  The DATA step is followed by a note containing the name of the SAS data set created
(WORK.DISTANCE), and the number of observations (1) and variables (2). A quick glance is enough to assure you that you did not lose any observations or accidentally create a lot of unwanted variables.

 Both DATA and PROC steps produce a note about the computer resources used. At first you probably won’t care in the least. But if you run on a multi-user system or have long jobs with large data sets, these statistics may start to pique your interest. If you ever find yourself wondering why your job takes so long to run, a glance at the SAS log will tell you which steps are the culprits. If there were error messages, they would appear in the log, indicating where SAS got confused and what action it took. You may also find warnings and other types of notes which sometimes indicate errors and other times just provide useful information.

18

The Little SAS Book

1.9

Viewing Your Results in the Output Window
How you view or print your output depends on how you submit your program. If you submit your program in the SAS windowing environment, then your output will, by default, go to the Output window. If you choose another way to submit your program, either batch or non-interactive, then your output will probably be in a file on your computer. Use your operating environment’s commands to view and print the output file (also called the listing). For example, if you execute your SAS program in non-interactive mode on a UNIX system, then your output will be in a file with an extension .lst. To view the file, you can use either the cat or more commands, and to print the file you would use your system’s command for printing files (usually you would type either lp or lpr).

The Output window After submitting your program in the SAS windowing environment, your results will go to the Output window. If you have the SAS Explorer option turned on (some operating environments have this turned on by default, while others do not), then you will also see a listing of the different parts of your output in your Results window. The following figure shows what your Output window might look like after submitting a simple program under Windows. Printing or saving the contents of the Output window If you want to print or save the entire contents of the Output window, first make the Output window active by clicking in it, then select either Print or Save As from the File pull-down menu. If you are not using a personal computer, then your environment may not be set up for printing from within SAS. If you cannot print from within SAS, then save the output to a file and use your system’s command for printing files.

The Results window
When you have a lot of output, the Results window can be very helpful. The Results window is like a table of contents for your output. It lists each procedure that produces output, and if you open, or expand, the procedure in the Results tree, you can see each part of the procedure output. The following figure shows what your screen might look like if you ran the ANOVA (Analysis of Variance) procedure.

Chapter 1: Getting Started Using SAS Software

19

There is one entry in the Results window for the ANOVA procedure. Notice that in the Output window, you see the end of the procedure’s output. If you expand the ANOVA procedure in the results tree, by clicking on the plus (+) signs, then you will see all the different parts of the ANOVA output. Double click on the output you want to see, and it will appear at the top of the Output window. The following figure shows what your Output window would look like after you double click on the Overall ANOVA item in the Results window.

Printing or saving parts of the output Using the
Results window, it is possible to print or save just the parts of the output you want. First highlight the item you want in the Results window, then bring up the context-sensitive menu. In the Windows operating environment you do this with the right mouse button; in other operating environments, it may be the middle or right mouse button. Then select either Print or Save As from the pop-up menu. You may also be able to print or save from the File pull-down menu once you highlight the output part you want. If your SAS environment is not set up for printing from within SAS, then save your results to a file and use your operating environment’s command for printing files.

20

The Little SAS Book

1.10 Creating HTML Output
If you are using the SAS windowing environment, then you can create output in Hypertext 1 Markup Language (HTML) format with just a few clicks of your mouse.

The Preferences window To turn on HTML output (in Windows, UNIX, or OpenVMS2), select Options-Preferences from the Tools menu. This opens the Preferences window. Click on the Results tab to bring it to the front. Here is what the Results portion of the Preferences window looks like in Windows:

When you first open this window, you will see a check next to Create Listing. Listing is the default type of output, and it is what you see in the Output window if you are using the SAS windowing environment, or in the output or listing file if you are running in batch mode. You can turn on HTML output by clicking in the box next to Create HTML. To turn off the listing or HTML output, just click to un-check it. In the Preferences window, you can also select a style for HTML output by clicking on the arrow next to the Style box and scrolling through the list of styles provided with SAS. When you are done with the Preferences window, click on the OK button.

The Results Viewer and Results windows Once you have turned on HTML output, then every time you run a program, your output will automatically appear in the Results Viewer window. The following figure shows what you see after running two simple procedures: MEANS and PRINT. Two windows are showing: the Results Viewer window displaying the HTML output, and the Results window listing all the pieces of output in tree form.

If you are not using the SAS windowing environment, you can still produce HTML output by using ODS statements (see chapter 5). In addition, SAS Enterprise Guide allows you to create HTML output in a way that is similar to the one shown in this section with the added bonus that you can also produce RTF and PDF output. 2 If you are using OS/390 or z/OS, you will need to modify your registry settings in order to generate HTML interactively. Contact your site’s SAS Support Consultant for more information.

1

Chapter 1: Getting Started Using SAS Software

21

Results window

Results Viewer window

The Results Viewer window only shows you one piece of output at a time, but you can tell that SAS ran both procedures by looking at the list in the Results window. You can expand the list by clicking on plus (+) signs, or collapse it by clicking on minus (-) signs. Since both the listing and HTML output were turned on, each procedure produced two pieces of output: one for listing, and one for HTML. You can display any piece of output by double clicking its name in the Results window. To save a piece of output in a file, make the Results Viewer window active by clicking on it, then click on the File menu, and choose Save As…. To print a piece of output, select Print from the File menu. The preceding screen used the DEFAULT style which is the default for HTML output. To see the same output with a different style, just choose a different style in the Preferences window, and rerun your program. Here is the output from the same program using the D3D style.

22

The Little SAS Book

1.11 SAS Data Libraries
Before you can use a SAS data set, you have to tell SAS where to find it. You do that by setting up a SAS library. A SAS library is simply a location where SAS data sets (as well as other types of SAS files) are stored. Depending on your operating environment, a SAS library might be a folder or directory on your computer, or it might be a physical location like a hard drive, floppy disk, or CD. To set up a library, all you have to do is make up a name for your library and tell SAS where it is. There are several ways to do this including using the LIBNAME statement (covered in sections 2.19 to 2.20) and using the New Library window in the SAS Windowing Environment. When you start the SAS windowing environment, you see the basic SAS windows including the SAS Explorer window on the left. (If the Explorer window is under the Results window, click on its tab to bring it forward.) If you double-click on the Libraries icon, Explorer will open the Active Libraries window showing all the libraries that are currently defined. To go back to the previous window within Explorer, choose Up one level from the View menu, or click in the Explorer window to make it active and then click on the Up One Level button on the toolbar.

The Active Libraries window When you open the Active Libraries window, you will see at least three libraries: Sashelp, Sasuser, and Work. You may have other libraries for specific SAS products (such as the Maps library for SAS/GRAPH software), or libraries that have been set up by you or someone you work with. The Sashelp library contains information that controls your SAS session along with sample SAS data sets. The Work library is a temporary storage location for SAS data sets. It is also the default library. If you create a SAS data set without specifying a library, SAS will put it in the Work library, and then delete it when you end your session. If you make changes to the default settings for the SAS windowing environment, this information will be stored in the Sasuser library. You can also store SAS data sets, SAS programs, and other SAS files in the Sasuser library. However, many people prefer to create a new library for their SAS files.

Chapter 1: Getting Started Using SAS Software

23

Creating a new library You can create new SAS libraries using the New Library window. To open this window, either left click in the Active Libraries window (to make it active) and choose New from the File menu, or right click in the Active Libraries window and choose New from the pop-up menu.

In the New Library window, type the name of the library you want to create. This name is called a libref which is short for library reference. A libref must be eight characters or fewer; start with a letter or underscore; and contain only letters, numerals, or underscores. In this window, the name Mylib has been typed in as the libref. In the Path field, enter the complete path to the folder or directory where you want your data sets to be stored, or choose the Browse… button to navigate to the location. If you don’t want to define your library reference every time you start up SAS, then check the Enable at startup box. Click OK and then your new library reference will appear in the Active Libraries window. Here is the Active Libraries window showing the newly created Mylib library.

24

The Little SAS Book

1.12 Viewing Data Sets with SAS Explorer
In addition to listing your current libraries and creating new libraries, you can also use SAS Explorer to open SAS data sets for viewing and editing, or to list information about their contents such as the date the data set was created and the names of variables. Start by double-clicking on the Libraries icon in the Explorer window as shown in section 1.11. This will open the Active Libraries window showing all the libraries that are currently defined on your system. If you double-click on a library, SAS will open a Contents window showing you all the files (including SAS data sets) and folders in that particular library. To go back to the previous window within Explorer, choose Up one level from the View menu, or click in the Explorer window to make it active and then click on the Up One Level button toolbar. on the

The Contents window This window shows the contents of a library. SAS data sets are represented by an icon showing a little table of data and a red ball, so the library shown on the right contains three data sets named Customers, Models, and Orders. If you double-click on a data set, SAS will open a Viewtable window showing that data set. (If you don’t yet have any SAS data sets of your own, you can view sample data sets that are provided with SAS in the Sashelp library. The Class data set in the Sashelp library is a good one to view.)

The Viewtable window This window
(discussed in more detail in section 2.2) allows you to create, browse, and edit data sets. This picture shows the data set named Models from the Mylib library.

Chapter 1: Getting Started Using SAS Software

25

Listing the properties of a SAS data set In addition to viewing the data in a SAS data set, you can use the SAS Explorer window to list information about a data set. To list the properties of a particular SAS data set, right-click on its icon, and select Properties from the pop-up menu.

SAS will open a Properties window for that data 1 set . This window displays information about the data set such as the date it was created and the number of rows (or observations).

If you choose Columns, SAS displays information about the columns (or variables) in that data set. The information shown in the Properties window is similar to the information produced by the CONTENTS procedure described in section 2.22.

The Properties windows shown here are from SAS 9 in the Windows operating environment. If you are using a different version of SAS, or if you are using a different operating environment, your windows may have a different look.

1

26

The Little SAS Book

1.13 Using SAS System Options
System options are parameters you can change that affect SAS¾how it works, what the output looks like, how much memory is used, error handling, and a host of other things. SAS makes many assumptions about how you want it to work. This is good. You do not want to specify every little detail each time you use SAS. However, you may not always like the assumptions SAS makes. System options give you a way to change some of these assumptions. Not all options are available for all operating environments. A list of options specific to your operating environment appears in the SAS Help and Documentation. You can see a list of system options and their current values by opening the SAS System Options window or by using the OPTIONS procedure. To use the OPTIONS procedure, submit the following SAS program and view the results in the SAS log:
PROC OPTIONS; RUN;

There are four ways to specify system options. Some options can be specified using only some of these methods. The SAS Help and Documentation for your operating environment tells you which methods are valid for each system option: 1. Your system administrator (this could be you if you are using a PC) can create a SAS configuration file which contains settings for the system options. This file is accessed by SAS every time SAS is started. Specify system options at the time you start up SAS from your system’s prompt (called the invocation). Change selected options in the SAS System Options window if you are using the SAS windowing environment. Use the OPTIONS statement as a part of your SAS program.

2. 3. 4.

The methods are listed here in order of increasing precedence; method 2 will override method 1, method 3 will override method 2, and so forth. If you are using the SAS windowing environment, methods 3 and 4, the SAS System Options window and OPTIONS statement, will override each other¾so whichever was used last will be in effect. Only the last two methods are covered here. The first two methods are very system dependent; to find out more about these methods see the SAS Help and Documentation for your operating environment.

OPTIONS statement The OPTIONS statement is part of a SAS program and affects all steps that follow it. It starts with the keyword OPTIONS and follows with a list of options and their values. For example
OPTIONS LINESIZE = 80 NODATE;

The OPTIONS statement is one of the special SAS statements which do not belong to either a PROC or a DATA step. This global statement can appear anywhere in your SAS program, but it usually makes the most sense to let it be the first line in your program. This way you can easily see which options are in effect. If the OPTIONS statement is in a DATA or PROC step, then it affects that step and the following steps. Any subsequent OPTIONS statements in a program override previous ones.

Chapter 1: Getting Started Using SAS Software

27

The SAS System Options window
You can view and change SAS system options through the SAS System Options window. Open it either by typing OPTIONS in the command line area on your screen, or by selecting it from the Tools pull-down menu. To change the value of an option, first locate the option by clicking on the appropriate category on the left side of the screen. A list of options and their current values will appear on the right side of the screen. Right click on the option itself to modify the value or set it to the default.

Common options The following are some common system options you might want to use:
CENTER | NOCENTER DATE | NODATE LINESIZE = n NUMBER | NONUMBER ORIENTATION = PORTRAIT ORIENTATION = LANDSCAPE PAGENO = n PAGESIZE = n RIGHTMARGIN = n LEFTMARGIN = n TOPMARGIN = n BOTTOMMARGIN = n YEARCUTOFF = yyyy Controls whether output are centered or left-justified. Default: CENTER. Controls whether or not today’s date will appear at the top of each page of output. Default: DATE. Controls the maximum length of output lines. Possible values for n are 64 to 256. Default varies. Controls whether or not page numbers appear on each page of SAS output. Default: NUMBER. Specifies the orientation for printing output. Default: PORTRAIT Starts numbering output pages with n. Default is 1. Controls the maximum number of lines per page of output. Possible values for n are 15 to 32767. Default varies. Specifies size of margin (such as 0.75in or 2cm) to be used for printing output. Default: 0.00in.

Specifies the first year in a hundred-year span for interpreting two-digit dates. Default: 1920.

2

‘‘ ’’ ‘‘

Practice is the best of all instructors.
PUBLIUS SYRUS, CIRCA 42 B.C

We all learned by doing, by experimenting (and often failing), and by asking questions.

’’

JAY JACOB WIND

From Bartlett’s Familiar Quotations 13th edition, by John Bartlett, copyright 1955 by Little Brown & Company. Public domain. From the SAS L Listserv, March 15, 1994. Reprinted by permission of the author.

Using Permanent SAS Data Sets with LIBNAME Statements Using Permanent SAS Data Sets by Direct Referencing Listing the Contents of a SAS Data Set 72 70

68

30

The Little SAS Book

2.1 Methods for Getting Your Data into SAS
Data come in many different forms. Your data may be handwritten on a piece of paper, or typed into a raw data file on your computer. Perhaps your data are in a database file on your personal computer, or in a database management system (DBMS) on the mainframe computer at your office. Wherever your data reside, there is a way for SAS to use them. You may need to convert your data from one form to another, or SAS may be able to use your data in their current form. This section outlines several methods for getting your data into SAS. Most of these methods are covered in this book, but a few of the more advanced methods are merely mentioned so that you know they exist. We do not attempt to cover all methods available for getting your data into SAS, as new methods are continually being developed, and creative SAS users can always come up with clever methods that work for their own situations. But there should be at least one method explained in this book that will work for you. Methods for getting your data into SAS can be put into four general categories: ¨ ¨ ¨ ¨ entering data directly into SAS data sets creating SAS data sets from raw data files converting other software’s data files into SAS data sets reading other software’s data files directly.

Naturally, the method you choose will depend on where your data are located, and what software tools are available to you.

Entering data directly into SAS data sets Sometimes the best method for getting your data into SAS is to enter the data directly into SAS data sets through your keyboard.
¨ The Viewtable window, discussed in section 2.2, is included with Base SAS software. Viewtable allows you to enter your data in a tabular format. You can define variables, or columns, and give them attributes such as name, length, and type (character or numeric). SAS Enterprise Guide software, a Windows only application, has a data entry window that is very similar to the Viewtable window. As with Viewtable, you can define variables and give them attributes. SAS/FSP software, short for Full Screen Product, allows you to design custom data entry screens. It also has the capability for detecting data entry errors as they happen. The SAS/FSP product is licensed separately from Base SAS software.

¨

¨

Creating SAS data sets from raw data files Much of this chapter is devoted to reading raw data files (also referred to as text, ASCII, sequential, or flat files). You can always read a raw data file since the DATA step is an integral part of Base SAS software. And, if your data are not already in a raw data file, chances are you can convert your data into a raw data file. There are two general methods for reading raw data files:
¨ The DATA step is so versatile that it can read almost any type of raw data file. This method is covered in this chapter starting with section 2.4.

Chapter 2: Getting Your Data into SAS ¨

31

The Import Wizard, covered in section 2.3 and its cousin the IMPORT procedure, covered in section 2.16, are available for UNIX, OpenVMS, and Windows operating environments. These are simple methods for reading particular types of raw data files including comma-separated values (CSV) files, and other delimited files.

Converting other software’s data files into SAS data sets Each software application has its own form for data files. While this is useful for software developers, it is troublesome for software users—especially when your data are in one application, but you need to analyze them with another. There are several options for converting data from applications into SAS data sets:
¨ The IMPORT procedure and the Import Wizard can be used to convert Microsoft Excel, Lotus, dBase, and Microsoft Access files into SAS data sets if you have SAS/ACCESS for PC File Formats software installed on your computer. This is covered in sections 2.3 and 2.17. If you don’t have SAS/ACCESS software, then you can always create a raw data file from your application and read the raw data file with either the DATA step or the IMPORT procedure. Many applications can create CSV files, which are easily read using the Import Wizard or IMPORTprocedure (covered in sections 2.3 and 2.16) or the DATA step (covered in section 2.15). Dynamic Data Exchange (DDE), covered in section 2.18, is available only for those working in the Windows operating environment. To use DDE, you must have the other Windows application (Microsoft Excel for example) running on your computer at the same time as SAS. Then using DDE and the DATA step, you can convert data into SAS data sets.

¨

¨

Reading other software’s data files directly Under certain circumstances you may be able to read data without converting to a SAS data set. This method is particularly useful when you have many people updating data files, and you want to make sure that you are using the most current data.
¨ The SAS/ACCESS products allow you to read data without converting your data into SAS data sets. There are SAS/ACCESS products for most of the popular database management systems including ORACLE, DB2, INGRES, and SYBASE. This method of data access is not covered in this book. We already mentioned using SAS/ACCESS for PC Files Formats software to convert several PC file types to SAS data sets, but you can also use the Excel and Access engines to read these types of files directly without converting. See the SAS Help and Documentation for more information on these engines. There are also data engines that allow you to read data directly but are part of Base SAS software. The SPSS engine is covered in Appendix D. There are also engines for OSIRIS, old versions of SAS data sets, and SAS data sets in transport format. Check the SAS Help and Documentation for your operating environment for a complete list of available engines.

¨

¨

Given all these methods for getting your data into SAS, you are sure to find at least one method that will work for you—probably more.

32

The Little SAS Book

2.2

Entering Data with the Viewtable Window
The Viewtable window which is part of Base SAS software is an easy way to create new data sets, or browse and edit existing data sets. True to its name, the Viewtable window displays tables (another name for data sets) in a tabular format. To open the Viewtable window, select Table Editor from the Tools menu. An empty Viewtable window will appear.
1

This table contains no data. Instead you see rows (or observations) labeled with numbers and columns (or variables) labeled with letters. You can start typing data into this default table, and SAS will automatically figure out if your columns are numeric or character. However, it’s a good idea to tell SAS about your data so each column is set up the way you want. You do this with the Column Attributes window.

Column Attributes window The letters at the tops of columns are default variable names. By right-clicking on a letter, you can choose to open a Column Attributes window for that column. This window contains default values which you can replace with the values you desire. When you are satisfied with the values, click on Apply. To switch to a new column, click on that column in the Viewtable window. When you are finished changing column attributes click on Close.

If you are using a non-graphical monitor, then SAS uses FSVIEW to display your tables, so you also need SAS/FSP software which is licensed separately.

1

Chapter 2: Getting Your Data into SAS

33

Entering data Once you have defined your columns you are ready to type in your data. To move the cursor, click on a field, or use tab and arrow keys. Here is a table with column attributes defined and data entered. Saving your table To save a table, select Save As… from the File menu. Select a library, and then specify the member name of your table. The libraries displayed correspond to locations (such as directories) on your computer. If you want to save your table in a different location, you can add another library by clicking on the New Library icon. Type in a name for the new library and its path. Then click on OK. Specify the member name by typing it in the Member Name field. Opening an existing table To browse or edit an existing table, first select Table Editor from the Tools menu to open the Viewtable window. Then select Open from the File menu. Click on the library you want and then on the table name. If the table you want to open is not in any of the existing libraries, click on the New Library icon. Type in a name for the new library and its path. Then click on OK. To switch from browse mode (the default) to edit mode, select Edit Mode from the Edit menu. You can also open an existing table by navigating to it in the SAS Explorer window, and double clicking on it.

Other features The Viewtable window has many other features including sorting, printing, adding and deleting rows, and viewing multiple rows (the default, called Table View) or viewing one row at a time (called Form View). You can control these features using either menus or icons. Using your table in a SAS program Tables that you create in Viewtable can be used in programs just as tables created in programs can be used in Viewtable. For example, if you saved your table in the SASUSER library and named it COFFEE, you could print it with this program:
PROC PRINT DATA=Sasuser.coffee; RUN;

34

The Little SAS Book

2.3

Reading Files with the Import Wizard
Using the Import Wizard , you can read a variety of data file types into SAS by simply answering 2 a few questions. The Import Wizard will scan your file to determine variable types and will, by default, use the first row of data for the variable names. The Import Wizard can read all types of delimited files including comma-separated values (CSV) files which are a common file type for moving data between applications. And, if you have SAS/ACCESS for PC File Formats 3 software, then you can also read a number of popular PC file types . Start the Import Wizard by choosing Import Data… from the File menu.
1

Select the type of file you are importing by choosing from the list of standard data sources such as comma-separated values (*.csv) files.

Now, specify the location of the file that you want to import. By default, SAS uses the first row in the file as the variable names for the SAS data set, and starts reading data in the second row. The Options… button takes you to another screen where you can change this default action.

1

The Import Wizard is available in the Windows, UNIX, and OpenVMS operating environments.

By default the Import Wizard will scan the first 20 rows for delimited files and the first 8 rows for Microsoft Excel files. If you have all missing data in these rows, then the Import Wizard (and the IMPORT procedure) may not read the file correctly. See sections 2.16 and 2.17 for more information. Under the Windows operating environment, you can read Microsoft Excel, Microsoft Access, Lotus, and dBase files (if you are running Microsoft Windows 64-Bit Edition, then you cannot read Microsoft Access or Microsoft Excel 97, Excel 2000, or Excel 2002 files). Under the UNIX operating environment, you can read dBase files, and starting with SAS 9.1, UNIX users can also read Microsoft Excel and Microsoft Access files.
3

2

Chapter 2: Getting Your Data into SAS

35

The next screen asks you to choose the SAS library and member name for the SAS data set that will be created. If you choose the WORK library, then the SAS data set will be deleted when you exit SAS. If you choose a different library, then the SAS data set will remain even after you exit SAS. There is no way to define a library from within the Import Wizard, so make sure your library is defined before entering the Import Wizard. You can define libraries using the New Library window discussed in section 1.11 (or using a LIBNAME statement as discussed in section 2.20). After choosing a library, enter a member name for the SAS data set.

In the last window, the Import Wizard gives you the option of saving the PROC IMPORT statements used for importing the file.

For some types of files, the Import Wizard asks additional questions. For example, if you are importing Microsoft Access files, then you will be asked for the database name and the table you want to import. You will also be given an opportunity to enter user ID and password information if applicable.

Using imported data in a SAS program Data that you import through the Import Wizard can be used in any SAS program. For example, if you saved your data in the WORK library and named it FLOWERS, you could print it with this program:
PROC PRINT DATA=WORK.flowers; RUN;

Or, since WORK is the default library, you could also use:
PROC PRINT DATA=flowers; RUN;

36

The Little SAS Book

2.4 Telling SAS Where to Find Your Raw Data
If your data are in raw data files (also referred to as text, ASCII, sequential, or flat files), using the DATA step to read the data gives you the most flexibility. The first step toward reading raw data files is telling SAS where to find the raw data. Your raw data may be either internal to your SAS program, or in a separate file. Either way, you must tell SAS where to find your data. A raw data file can be viewed using simple text editors or system commands. For PC users, raw data files will either have no program associated with them, or they will be associated with simple editors like Microsoft Notepad. In some operating environments, you can use commands to list the file, such as the cat or more commands in UNIX. Spreadsheet files are examples of data files that are not raw data. If you try using a text editor to look at a spreadsheet file, you will probably see lots of funny special characters you can’t find on your keyboard. It may cause your computer to beep and chirp, making you wish you had that private office down the hall. It looks nothing like the nice neat rows and columns you see when you use your spreadsheet software to view the same file.

Internal raw data If you type raw data directly in your SAS program, then the data are internal to your program. You may want to do this when you have small amounts of data, or when you are testing a program with a small test data set. Use the DATALINES statement to indicate internal data. The DATALINES statement must be the last statement in the DATA step. All lines in the SAS program following the DATALINES statement are considered data until SAS encounters a semicolon. The semicolon can be on a line by itself or at the end of a SAS statement which follows the data lines. Any statements following the data are part of a new step. If you are old enough to remember punching computer cards, you might like to use the CARDS statement instead. The CARDS statement and the DATALINES statement are synonymous. The following SAS program illustrates the use of the DATALINES statement. (The DATA statement simply tells SAS to create a SAS data set named USPRESIDENTS, and the INPUT statement tells SAS how to read the data. The INPUT statement is discussed in sections 2.5 through 2.15.)
* Read internal data into SAS data set uspresidents; DATA uspresidents; INPUT President $ Party $ Number; DATALINES; Adams F 2 Lincoln R 16 Grant R 18 Kennedy D 35 ; RUN;

External raw data files Usually you will want to keep data in external files, separating the data from the program. This eliminates the chance that data will accidentally be altered when you are editing your SAS program. Use the INFILE statement to tell SAS the filename and path, if appropriate, of the external file containing the data. The INFILE statement follows the DATA statement and must precede the INPUT statement. After the INFILE keyword, the

Suppose the following data are in a file called President.dat in the directory MyRawData on the C drive (Windows):
Adams Lincoln Grant Kennedy F 2 R 16 R 18 D 35

The following program shows the use of the INFILE statement to read the external data file:
* Read data from external file into SAS data set; DATA uspresidents; INFILE ’c:\MyRawData\President.dat’; INPUT President $ Party $ Number; RUN;

The SAS log Whenever you read data from an external file, SAS gives some very valuable information about the file in the SAS log. The following is an excerpt from the SAS log after running the previous program. Always check this information after you read a file as it could indicate problems. A simple comparison of the number of records read from the infile with the number of observations in the SAS data set can tell you a lot about whether SAS is reading your data correctly.
NOTE: The infile ’c:\MyRawData\President.dat’ is: File Name=c:\MyRawData\President.dat, RECFM=V,LRECL=256 NOTE: 4 records were read from the infile ’c:\MyRawData\President.dat’. The minimum record length was 13. The maximum record length was 13. NOTE: The data set WORK.USPRESIDENTS has 4 observations and 3 variables.

Long records In some operating environments, SAS assumes external files have a record length of 256 or less. (The record length is the number of characters, including spaces, in a data line.) If your data lines are long, and it looks like SAS is not reading all your data, then use the LRECL= option in the INFILE statement to specify a record length at least as long as the longest record in your data file.
INFILE ’c:\MyRawData\President.dat’ LRECL=2000;

Check the SAS log to see that the maximum record length is as long as you think it should be.

38

The Little SAS Book

2.5 Reading Raw Data Separated by Spaces
If the values in your raw data file are all separated by at 1 least one space, then using list input (also called free formatted input) to read the data may be appropriate. List input is an easy way to read raw data into SAS, but with ease come a few limitations. You must read all the data in a record—no skipping over unwanted values. Any missing data must be indicated with a period. Character data, if present, must be simple: no embedded spaces, and no values greater than eight characters in 2 length. If the data file contains dates or other values which need special treatment, then list input may not be appropriate. This may sound like a lot of restrictions, but a surprising number of data files can be read using list input. The INPUT statement, which is part of the DATA step, tells SAS how to read your raw data. To write an INPUT statement using list input, simply list the variable names after the INPUT keyword in the order they appear in the data file. Generally, variable names must be 32 characters or fewer, start with a letter or an underscore, and contain only letters, underscores, or numerals. If the values are character (not numeric) then place a dollar sign ($) after the variable name. Leave at least one space between names, and remember to place a semicolon at the end of the statement. The following is an example of a simple list style INPUT statement.
INPUT Name $ Age Height;

This statement tells SAS to read three data values. The $ after Name indicates that it is a character variable, whereas the Age and Height variables are both numeric.

Example Your hometown has been overrun with toads this year. A local resident, having heard of frog jumping in California, had the idea of organizing a toad jump to cap off the annual town fair. For each contestant you have the toad’s name, weight, and the jump distance from three separate attempts. If the toad is disqualified for any jump, then a period is used to indicate missing data. Here is what the data file ToadJump.dat looks like:
Lucky 2.3 1.9 . 3.0 Spot 4.6 2.5 3.1 .5 Tubs 7.1 . . 3.8 Hop 4.5 3.2 1.9 2.6 Noisy 3.8 1.3 1.8 1.5 Winner 5.7 . . .

This data file does not look very neat, but it does meet all the requirements for list input: the character data are eight characters or fewer and have no embedded spaces, all values are separated by at least one space, and missing data are indicated by a period. Notice that the data for Noisy have spilled over to the next data line. This is no problem since, by default, SAS will go to the next data line to read more data if there are more variables in the INPUT statement than there are values in the data line.
1 2

SAS can read files with other delimiters such as commas or tabs using list input. See sections 2.14 and 2.15. It is possible to override this constraint using the LENGTH statement, discussed in section 10.13, which can change the length of character variables from the default of 8 to anything between 1 and 32,767.

The variables ToadName, Weight, Jump1, Jump2, and Jump3 are listed after the keyword INPUT in the same order as they appear in the file. A dollar sign ($) after ToadName indicates that it is a character variable; all the other variables are numeric. A PROC PRINT statement is used to print the data values after reading them to make sure they are correct. The PRINT procedure, in its simplest form, prints the values for all variables and all observations in a SAS data set. The TITLE statement after the PROC PRINT tells SAS to put the text enclosed in quotation marks on the top of each page of output. If you had no TITLE statement in your program, SAS would put the words “The SAS System” at the top of each page. The output will look like this:
SAS Data Set Toads Toad Name Lucky Spot Tubs Hop Noisy Winner 1

Obs 1 2 3 4 5 6

Weight 2.3 4.6 7.1 4.5 3.8 5.7

Jump1 1.9 2.5 . 3.2 1.3 .

Jump2 . 3.1 . 1.9 1.8 .

Jump3 3.0 0.5 3.8 2.6 1.5 .

Because SAS had to go to a second data line to get the data for Noisy’s final jump, the following note appears in the SAS log:
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.

If you find this note in your SAS log when you didn’t expect it, then you may have a problem. If so, look in section 10.4 which discusses this note in more detail.

40

The Little SAS Book

2.6

Reading Raw Data Arranged in Columns
Some raw data files do not have spaces (or other delimiters) between all the values or periods for missing data—so the files can’t be read using list input. But if each of the variable’s values is always found in the same place in the data line, then you can use column input as long as all the values are character or standard numeric. Standard numeric data contain only numerals, decimal points, plus and minus signs, and E for scientific notation. Numbers with embedded commas or dates, for example, are not standard. Column input has the following advantages over list input: ¨ ¨ ¨ ¨ spaces are not required between values missing values can be left blank character data can have embedded spaces you can skip unwanted variables.

Survey data are good candidates for column input. Most answers to survey questionnaires are single digits (0 through 9). If a space is entered between each value, then the file will be twice the size and require twice the typing of a file without spaces. Data files with street addresses, which often have embedded blanks, are also good candidates for column input. The street Martin Luther King Jr. Boulevard should be read as one variable not five, as it would be with list input. Data which can be read with column input can often also be read with formatted input or a combination of input styles (discussed in sections 2.7, 2.8, and 2.9). With column input, the INPUT statement takes the following form: after the INPUT keyword, list the first variable’s name. If the variable is character, leave a space; then place a $. After the $, or variable name if it is numeric, leave a space; then list the column or range of columns for that variable. The columns are positions of the characters or numbers in the data line and are not to be confused with columns like those you see in a spreadsheet. Repeat this for all the variables you want to read. The following shows a simple INPUT statement using column style:
INPUT Name $ 1-10 Age 11-13 Height 14-18;

The first variable, Name, is character and the data values are in columns 1 through 10. The Age and Height variables are both numeric, since they are not followed by a $, and data values for both of these variables are in the column ranges listed after their names.

Example The local minor league baseball team, the Walla Walla Sweets, is keeping records about concession sales. A ballpark favorite are the sweet onion rings which are sold at the concession stands and also by vendors in the bleachers. The ballpark owners have a feeling that in games with lots of hits and runs more onion rings are sold in the bleachers than at the concession stands. They think they should send more vendors out into the bleachers when the game heats up, but need more evidence to back up their feelings.

Chapter 2: Getting Your Data into SAS

41

For each home game they have the following information: name of opposing team, number of onion ring sales at the concession stands and in the bleachers, the number of hits for each team, and the final score for each team. The following is a sample of the data file named Onions.dat. For your reference, a column ruler showing the column numbers has been placed above the data:
----+----1----+----2----+----3----+----4 Columbia Peaches 35 67 1 10 2 1 Plains Peanuts 210 2 5 0 2 Gilroy Garlics 151035 12 11 7 6 Sacramento Tomatoes 124 85 15 4 9 1

Notice that the data file has the following characteristics, all making it a prime candidate for column input. All the values line up in columns, the team names have embedded blanks, missing values are blank, and in one case there is not a space between data values. (Those Gilroy Garlics fans must really love onion rings.) The following program shows how to read these data using column input:
* Create a SAS data set named sales; * Read the data file Onions.dat using column input; DATA sales; INFILE ’c:\MyRawData\Onions.dat’; INPUT VisitingTeam $ 1-20 ConcessionSales 21-24 BleacherSales 25-28 OurHits 29-31 TheirHits 32-34 OurRuns 35-37 TheirRuns 38-40; * Print the data to make sure the file was read correctly; PROC PRINT DATA = sales; TITLE ’SAS Data Set Sales’; RUN;

The variable VisitingTeam is character (indicated by a $) and reads the visiting team’s name in columns 1 through 20. The variables ConcessionSales and BleacherSales read the concession and bleacher sales in columns 21 through 24 and 25 through 28, respectively. The number of hits for the home team, OurHits, and the visiting team, TheirHits, are read in columns 29 through 31 and 32 through 34, respectively. The number of runs for the home team, OurRuns, is read in columns 35 through 37, while the number of runs for the visiting team, TheirRuns, is in columns 38 through 40. The output will look like this:
SAS Data Set Sales Concession Bleacher Our Their Our Their Sales Sales Hits Hits Runs Runs 35 210 15 124 67 . 1035 85 1 2 12 15 10 5 11 4 2 0 7 9 1 2 6 1 1

Reading Raw Data Not in Standard Format
Sometimes raw data are not straightforward numeric or character. For example, we humans easily read the number 1,000,001 as one million and one, but your trusty computer sees it as a character string. While the embedded commas make the number easier for us to interpret, they make the number impossible for the computer to recognize without some instructions. In SAS, informats are used to tell the computer how to interpret these types of data.

01/01/60 1,002 01/03/60 2,012 02/01/60 4,336

0 1002 2 2012 31 4336

Informats are useful anytime you have non-standard data. (Standard numeric data contain only numerals, decimal points, minus signs, and E for scientific notation.) Numbers with embedded commas or dollar signs are examples of non-standard data. Other examples include data in hexadecimal or packed decimal formats. SAS has informats for reading these types of data as well. Dates are perhaps the most common non-standard data. Using date informats, SAS will convert conventional forms of dates like 10-31-2003 or 31OCT03 into a number, the number of days since January 1, 1960. This number is referred to as a SAS date value. (Why January 1, 1960? Who knows? Maybe 1960 was a good year for the SAS founders.) This turns out to be extremely useful when you want to do calculations with dates. For example, you can easily find the number of days between two dates by subtracting one from the other. There are three general types of informats: character, numeric, and date. A table of selected SAS informats appears in section 2.8. The three types of informats have the following general forms: Character
$informatw.
1

Numeric informatw.d Date informatw. The $ indicates character informats, INFORMAT is the name of the informat, w is the total width, and d is the number of decimal places (numeric informats only). The period is very important part of the informat name. Without a period, SAS may try to interpret the informat as a variable name, which by default, cannot contain any special characters except the underscore. Two informats do not have names: $w., which reads standard character data, and w.d, which reads standard numeric data. Use informats by placing the informat after the variable name in the INPUT statement; this is called formatted input. The following INPUT statement is an example of formatted input:
INPUT Name $10. Age 3. Height 5.1 BirthDate MMDDYY10.;

The columns read for each variable are determined by the starting point and the width of the informat. SAS always starts with the first column; so the data values for the first variable, Name, which has an informat of $10., are in columns 1 through 10. Now the starting point for the second variable is column 11, and SAS reads values for Age in columns 11 through 13. The values for the third variable, Height, are in columns 14 through 18. The five columns include the decimal place and the decimal point itself (150.3 for example). The values for the last variable, BirthDate, start in column 19 and are in a date form.

The following program reads these data. Please note there are many ways to input these data, so if you imagined something else, that’s OK.
* Create a SAS data set named contest; * Read the file Pumpkin.dat using formatted input; DATA contest; INFILE ’c:\MyRawData\Pumpkin.dat’; INPUT Name $16. Age 3. +1 Type $1. +1 Date MMDDYY10. (Score1 Score2 Score3 Score4 Score5) (4.1); * Print the data set to make sure the file was read correctly; PROC PRINT DATA = contest; TITLE ’Pumpkin Carving Contest’; RUN;

The variable Name has an informat of $16., meaning that it is a character variable 16 columns wide. Variable Age has an informat of three, is numeric, three columns wide, and has no decimal places. The +1 skips over one column. Variable Type is character, and it is one column wide. Variable Date has an informat MMDDYY10. and reads dates in the form 10-31-2003 or 10/31/2003, each 10 columns wide. The remaining variables, Score1 through Score5, all require the same informat, 4.1. By putting the variables and the informat in separate sets of parentheses, you only have to list the informat once. Here are the results:

Notice that these dates are printed as the number of days since January 1, 1960. Section 4.5 discusses how to format these values into readable dates.

44

The Little SAS Book

2.8

Selected Informats
Definitions of commonly used informats along with the width range and default width. Informat Character $CHARw. $HEXw. $w. Reads character data—does not trim leading or trailing blanks Converts hexadecimal data to character data Reads character data—trims leading blanks
2 1

Check the SAS Help and Documentation for a complete list of informats. SAS date values are the number of days since January 1, 1960. Time values are the number of seconds past midnight, and datetime values are the number of seconds past midnight January 1, 1960.

The EBCDIC character set is used on most IBM mainframe computers, while the ASCII character set is used on most other computers. So, depending on the computer you are using, you will get one or the other. These values cannot be printed.

4

46

The Little SAS Book

2.9

Mixing Input Styles
Each of the three major input styles has its own advantages. List style is the easiest; column style is a bit more work; and formatted style is the hardest of the three. However, column and formatted styles do not require spaces (or other delimiters) between variables and can read embedded blanks. Formatted style can read special data such as dates. Sometimes you use one style, sometimes another, and sometimes the easiest way is to use a combination of styles. SAS is so flexible that you can mix and match any of the input styles for your own convenience.

You could write the INPUT statement for these data in many ways—that is the point of this section. The following program shows one way to do it:
* Create a SAS data set named nationalparks; * Read a data file Park.dat mixing input styles; DATA nationalparks; INFILE ’c:\MyRawData\Park.dat’; INPUT ParkName $ 1-22 State $ Year @40 Acreage COMMA9.; PROC PRINT DATA = nationalparks; TITLE ’Selected National Parks’; RUN;

Sometimes programmers run into problems when they mix input styles. When SAS reads a line of raw data it uses a pointer to mark its place, but each style of input uses the pointer a little differently. With list style input, SAS automatically scans to the next non-blank field and starts reading. With column style input, SAS starts reading in the exact column you specify. But with formatted input, SAS just starts reading—wherever the pointer is, that is where SAS reads. Sometimes you need to move the pointer explicitly, and you can do that by using the column pointer, @n, where n is the number of the column SAS should move to.

Chapter 2: Getting Your Data into SAS

47

In the preceding program, the column pointer @40 tells SAS to move to column 40 before reading the value for Acreage. If you removed the column pointer from the INPUT statement, as shown in the following statement, then SAS would start reading Acreage right after Year:
INPUT ParkName $ 1-22 State $ Year Acreage COMMA9.;

Because Acreage was read with formatted input, SAS started reading right where the pointer was. Here is the data file with a column ruler for counting columns at the top and asterisks marking the place where SAS started reading the values of Acreage:
----+----1----+----2----+----3----+----4----+----5 Yellowstone ID/MT/WY 1872 * 4,065,493 Everglades FL 1934 * 1,398,800 Yosemite CA 1864 * 760,917 Great Smoky Mountains NC/TN 1926 * 520,269 Wolf Trap Farm VA 1966 * 130

The COMMA9. informat told SAS to read nine columns, and SAS did that even when those columns were completely blank. The column pointer, @n, has other uses too and can be used anytime you want SAS to skip backwards or forwards within a data line. You could use it, for example, to skip over unneeded data, or to read a variable twice using different informats.

48

The Little SAS Book

2.10 Reading Messy Raw Data
Sometimes you need to read data that just don’t line up in nice columns or have pre-dictable lengths. When you have these types of messy files, ordinary list, column, or formatted input simply aren’t enough. You need more tools in your bag: tools like the @‘character’ column pointer and the colon modifier.

The @‘character’ column pointer In section 2.9 we showed you how you can use the @ column pointer to move to a particular column before reading data. However, sometimes you don’t know the starting column of the data, but you do know that it always comes after a particular character or word. For these types of situations, you can use the @‘character’ column pointer. For example, suppose you have a data file that has information about dog ownership. Nothing in the file lines up, but you know that the breed of the dog always follows the word Breed:. You could read the dog’s breed using the following INPUT statement:
INPUT @’Breed:’ DogBreed $;

The colon modifier The above INPUT statement will work just fine as long as the dog’s breed name is 8 characters or less (the default length for a character variable). So if the dog is a Shepherd you’re fine, but if the dog is a Rottweiler, all you will get is Rottweil. If you assign the variable an informat in the INPUT statement such as $20. to tell SAS that the variable’s field is 20 characters, 1 then SAS will read for 20 columns whether or not there is a space in those columns. So the DogBreed variable may include unwanted characters which appear after the dog’s breed on the 2 data line. If you only want SAS to read until it encounters a space , then you can use a colon modifier on the informat. To use a colon modifier, simply put a colon (:) before the informat (e.g. :$20. instead of $20.).
For example, given this line of raw data,
My dog Sam Breed: Rottweiler Vet Bills: $478

the following table shows the results you would get using different INPUT statements: Statements
INPUT @’Breed:’ DogBreed $; INPUT @’Breed:’ DogBreed $20.; INPUT @’Breed:’ DogBreed :$20.;

Value of variable DogBreed
Rottweil Rottweiler Vet Bill Rottweiler

It is also possible to define a variable’s length in a LENGTH or INFORMAT statement instead of in an INPUT statement. When a variable’s length is defined before the INPUT statement, then SAS will read until it encounters a space or reaches the length of the variable—the same behavior as using the colon modifier. The INFORMAT statement is covered in section 2.21 and the LENGTH statement is covered in section 10.13. A space is the default delimiter. This method works for files with other delimiters as well. See sections 2.14 and 2.15 for more information on reading delimited data.
2

We are interested in the date the files were accessed and the filename. You can see that because the IP address is not always the same number of characters, the date does not line up in the same column all the time. Also, not only does the filename not line up in columns, but the length of the filename is highly variable. Here is a SAS program that can read this file:
DATA weblogs; INFILE 'c:\MyWebLogs\dogweblogs.txt'; INPUT @'[' AccessDate DATE11. @'GET' File :$20.; PROC PRINT DATA = weblogs; TITLE ‘Dog Care Web Logs’; RUN;

This INPUT statement uses @‘[‘ to position the column pointer to read the date, then uses @‘GET’ to position the column pointer to read the filename. Because the filename is more than 8 characters, but not always the same number of characters, an informat with a colon modifier :$20. is used to read the filename. Here are the results of this program:
Dog Care Web Logs Obs 1 2 3 4 5 6 7 8 AccessDate3 15134 15134 15134 15134 15134 15134 15135 15135 File /rover.jpg /grooming.html /Icons/brush.gif /H_poodle.gif /bath.gif /lobo.gif /statemnt.htm /Icons/leash.gif 1

Notice that these dates are printed as the number of days since January 1, 1960. Section 4.5 discusses how to format these values into readable dates.

3

50

The Little SAS Book

2.11 Reading Multiple Lines of Raw Data per Observation
1 2 3
In a typical raw data file each line of data represents one observation, but sometimes the data for each observation are spread over more than one line. Since SAS will auto1 matically go to the next line if it runs out of data before it has 2 read all the variables in an INPUT statement, you could just let 3 SAS take care of figuring out when to go to a new line. But if you know that your data file has multiple lines of raw data per observation, it is better for you to explicitly tell SAS when to go to the next line than to make SAS figure it out. That way you won’t get that suspicious SAS-went-to-a-new-line note in your log. To tell SAS when to skip to a new line, you simply add line pointers to your INPUT statement. The line pointers, slash (/) and pound-n (#n), are like road signs telling SAS, “Go this way.” To read more than one line of raw data for a single observation, you simply insert a slash into your INPUT statement when you want to skip to the next line of raw data. The #n line pointer performs the same action except that you specify the line number. The n in #n stands for the number of the line of raw data for that observation; so #2 means to go to the second line for that observation, and #4 means go to the fourth line. You can even go backwards using the #n line pointer, reading from line 4 and then from line 3, for example. The slash is simpler, but #n is more flexible.

#3

Example A colleague is trying to plan his next summer vacation, but he wants to go someplace where the weather is just right. He obtains data from a meteorology database. Unfortunately, he has not quite figured out how to export from this database and makes a rather odd file.
The file contains information about temperatures for the month of July for Alaska, Florida, and North Carolina. (If your colleague chooses the last state, maybe he can visit SAS headquarters.) The first line contains the city and state, the second line lists the normal high temperature and normal low (in degrees Fahrenheit), and the third line contains the record high and low:
Nome AK 55 44 88 29 Miami FL 90 75 97 65 Raleigh NC 88 68 105 50

Chapter 2: Getting Your Data into SAS

51

The following program reads the weather data from a file named Temperature.dat:
* Create a SAS data set named highlow; * Read the data file using line pointers; DATA highlow; INFILE ’c:\MyRawData\Temperature.dat’; INPUT City $ State $ / NormalHigh NormalLow #3 RecordHigh RecordLow; PROC PRINT DATA = highlow; TITLE ’High and Low Temperatures for July’; RUN;

The INPUT statement reads the values for City and State from the first line of data. Then the slash tells SAS to move to column 1 of the next line of data before reading NormalHigh and NormalLow. Likewise, the #3 tells SAS to move to column 1 of the third line of data for that observation before reading RecordHigh and RecordLow. As usual, there is more than one way to write this INPUT statement. You could replace the slash with #2 or replace #3 with a slash. This note appears in the log:
NOTE: 9 records were read from the infile ’c:\MyRawData\Temperature.dat’. The minimum record length was 5. The maximum record length was 10. NOTE: The data set WORK.HIGHLOW has 3 observations and 6 variables.

Notice that while nine records were read from the infile, the SAS data set contains just three observations. Usually this would set off alarms in your mind, but here it confirms that indeed three data lines were read for every observation just as planned. You should always check your log, particularly when using line pointers. The output looks like this:
High and Low Temperatures for July Normal High 55 90 88 Normal Low 44 75 68 Record High 88 97 105 Record Low 29 65 50 1

Obs 1 2 3

City Nome Miami Raleigh

State AK FL NC

52

The Little SAS Book

2.12 Reading Multiple Observations per Line of Raw Data
There ought to be a Murphy’s law of data: whatever form data can take, it will. Normally SAS assumes that each line of raw data represents no more than one observation. When you have multiple observations per line of raw data, you can use double trailing at signs (@@) at the end of your INPUT statement. This linehold specifier is like a stop sign telling SAS, “Stop, hold that line of raw data.” SAS will hold that line of data, continuing to read observations until it either runs out of data or reaches an INPUT statement that does not end with a double trailing @.

@@

Example Suppose you have a colleague who is planning a vacation and has obtained a file containing data about rainfall (in inches) for the three cities he is considering. The file contains the name of each city, the state, average rainfall for the month of July, and average number of days with measurable precipitation in July. The raw data look like this:
Nome AK 2.5 15 Miami FL 6.75 18 Raleigh NC . 12

Notice that in this data file the first line stops in the middle of the second observation. The following program reads these data from a file named Precipitation.dat and uses an @@ so SAS does not automatically go to a new line of raw data for each observation:
* Input more than one observation from each record; DATA rainfall; INFILE ’c:\MyRawData\Precipitation.dat’; INPUT City $ State $ NormalRain MeanDaysRain @@; PROC PRINT DATA = rainfall; TITLE ’Normal Total Precipitation and’; TITLE2 ’Mean Days with Precipitation for July’; RUN;

Chapter 2: Getting Your Data into SAS

53

These notes will appear in the log:
NOTE: 2 records were read from the infile ’c:\MyRawData\Precipitation.dat’ The minimum record length was 18. The maximum record length was 28. NOTE: SAS went to a new line when INPUT statement reached past the end of a line. NOTE: The data set WORK.RAINFALL has 3 observations and 4 variables.

While only two records were read from the raw data file, the RAINFALL data set contains three observations. The log also includes a note saying SAS went to a new line when the INPUT statement reached past the end of a line. This means that SAS came to the end of a line in the middle of an observation and continued reading with the next line of raw data. Normally these messages would indicate a problem, but in this case they are exactly what you want. The output looks like this:
Normal Total Precipitation and Mean Days with Precipitation for July Normal Rain 2.50 6.75 . Mean DaysRain 15 18 12 1

Obs 1 2 3

City Nome Miami Raleigh

State AK FL NC

54

The Little SAS Book

2.13 Reading Part of a Raw Data File
A A B A B

A A A

At some time you may find that you need to read a small fraction of the records in a large data file. For example, you might be reading U.S. census data and want only female heads-of-household who have incomes above $225,000 and live in Walla Walla, Washington. You could read all the records in the data file and then throw out the unneeded ones, but that would waste time.

Luckily, you don’t have to read all the data before you tell SAS whether to keep an observation. Instead, you can read just enough variables to decide whether to keep the current observation, then end the INPUT statement with an at sign (@), called a trailing at. This tells SAS to hold that line of raw data. While the trailing @ holds that line, you can test the observation with an IF statement to see if it’s one you want to keep. If it is, then you can read data for the remaining variables with a second INPUT statement. Without the trailing @, SAS would automatically start reading the next line of raw data with each INPUT statement. The trailing @ is similar to the column pointer, @n, introduced in section 2.9. By specifying a number after the @ sign, you tell SAS to move to a particular column. By using an @ without specifying a column, it is as if you are telling SAS, “Stay tuned for more information. Don’t touch that dial!” SAS will hold that line of data until it reaches either the end of the DATA step, or an INPUT statement that does not end with a trailing @.

Example You want to read part of a raw data file containing local traffic data for freeways and surface streets. The data include information about the type of street, name of street, the average number of vehicles per hour traveling that street during the morning, and the average number of vehicles per hour for the evening. Here are the raw data: freeway surface surface surface freeway freeway surface surface 408 Martin Luther King Jr. Blvd. Broadway Rodeo Dr. 608 808 Lake Shore Dr. Pennsylvania Ave. 3684 1590 1259 1890 4583 2386 1590 1259 3459 1234 1290 2067 3860 2518 1234 1290

Suppose you want to see only the freeway data at this point so you read the raw data file, Traffic.dat, with this program:
* Use a trailing @, then delete surface streets; DATA freeways; INFILE ’c:\MyRawData\Traffic.dat’; INPUT Type $ @; IF Type = ’surface’ THEN DELETE; INPUT Name $ 9-38 AMTraffic PMTraffic; PROC PRINT DATA = freeways; TITLE ’Traffic for Freeways’; RUN;

Chapter 2: Getting Your Data into SAS

55

Notice that there are two INPUT statements. The first reads the character variable Type and then ends with an @. The trailing @ holds each line of data while the IF statement tests it. The second INPUT statement reads Name (in columns 9 through 38), AMTraffic, and PMTraffic. If an observation has a value of surface for the variable Type, then the second INPUT statement never executes. Instead SAS returns to the beginning of the DATA step to process the next observation and does not add the unwanted observation to the FREEWAYS data set. (Do not pass go, do not collect $200.) When you run this program, the log will contain the following two notes, one saying that eight records were read from the input file and another saying that the new data set contains only three observations:
NOTE: 8 records were read from the infile ’c:\MyRawData\Traffic.dat’. The minimum record length was 47. The maximum record length was 47. NOTE: The data set WORK.FREEWAYS has 3 observations and 4 variables.

The other five observations had a value of surface for the variable Type and were deleted by the IF statement. The output looks like this:
Traffic for Freeways Obs 1 2 3 Type freeway freeway freeway Name 408 608 808 AMTraffic 3684 4583 2386 PMTraffic 3459 3860 2518 1

Trailing @ versus double trailing @ The double trailing @, discussed in the previous section, is similar to the trailing @. Both are line-hold specifiers; the difference is how long they hold a line of data for input. The trailing @ holds a line of data for subsequent INPUT statements, but releases that line of data when SAS returns to the top of the DATA step to begin building the next observation. The double trailing @ holds a line of data for subsequent INPUT statements even when SAS starts building a new observation. In both cases, the line of data is released if SAS reaches a subsequent INPUT statement that does not contain a line-hold specifier.

56

The Little SAS Book

2.14 Controlling Input with Options in the INFILE Statement
So far in this chapter, we have seen ways to use the INPUT statement to read many different types of raw data. When reading raw data files, SAS makes certain assumptions. For example, SAS starts reading with the first data line and, if SAS runs out of data on a line, it automatically goes to the next line to read values for the rest of the variables. Most of the time this is OK, but some data files can’t be read using the default assumptions. The options in the INFILE statement change the way SAS reads raw data files. The following options are useful for reading particular types of data files. Place these options after the filename in the INFILE statement.

FIRSTOBS= The FIRSTOBS= option tells SAS at what line to begin reading data. This is useful if you have a data file that contains descriptive text or header information at the beginning, and you want to skip over these lines to begin reading the data. The following data file, for example, has a description of the data in the first two lines:
Ice-cream sales data for the summer Flavor Location Boxes sold Chocolate 213 123 Vanilla 213 512 Chocolate 415 242

The following program uses the FIRSTOBS= option to tell SAS to start reading data on the third line of the file:
DATA icecream; INFILE ’c:\MyRawData\Sales.dat’ FIRSTOBS = 3; INPUT Flavor $ 1-9 Location BoxesSold; RUN;

OBS= The OBS= option can be used anytime you want to read only a part of your data file.
It tells SAS to stop reading when it gets to that line in the raw data file. Note that it does not necessarily correspond to the number of observations. If, for example, you are reading two raw data lines for each observation, then an OBS=100 would read 100 data lines, and the resulting SAS data set would have 50 observations. The OBS= option can be used with the FIRSTOBS= option to read lines from the middle of the file. For example, suppose the ice-cream sales data had a remark at the end of the file that was not part of the data.
Ice-cream sales data for the summer Flavor Location Boxes sold Chocolate 213 123 Vanilla 213 512 Chocolate 415 242 Data verified by Blake White

MISSOVER By default, SAS will go to the next data line to read more data if SAS has reached the end of the data line and there are still more variables in the INPUT statement that have not been assigned values. The MISSOVER option tells SAS that if it runs out of data, don’t go to the next data line. Instead, assign missing values to any remaining variables. The following data file illustrates where this option may be useful. This file contains test scores for a self-paced course. Since not all students complete all the tests, some have more scores than others.
Nguyen Ramos Robbins 89 76 91 82 67 72 80 76 86 76 65 79

The following program reads the data for the five test scores, assigning missing values to tests not completed:
DATA class102; INFILE ’c:\MyRawData\Scores.dat’ MISSOVER; INPUT Name $ Test1 Test2 Test3 Test4 Test5; RUN;

TRUNCOVER You need the TRUNCOVER option when you are reading data using column or formatted input and some data lines are shorter than others. If a variable’s field extends past the end of the data line, then, by default, SAS will go to the next line to start reading the variable’s value. This option tells SAS to read data for the variable until it reaches the end of the data line, or the last column specified in the format or column range, whichever comes first. The next file contains addresses and must be read using column or formatted input because the street names have embedded blanks. Note that the data lines are all different lengths:
John Garcia Sylvia Chung Martha Newton 114 1302 45 Maple Ave. Washington Drive S.E. 14th St.

This program uses column input to read the address file. Because some of the addresses stop before the end of the variable Street’s field (columns 22 through 37), you need the TRUNCOVER option. Without the TRUNCOVER option, SAS would try to go to the next line to read the data for Street on the first and third records.
DATA homeaddress; INFILE ’c:\MyRawData\Address.dat’ TRUNCOVER; INPUT Name $ 1-15 Number 16-19 Street $ 22-37; RUN;

TRUNCOVER is similar to MISSOVER. Both will assign missing values to variables if the data line ends before the variable’s field starts. But when the data line ends in the middle of a variable field, TRUNCOVER will take as much as is there, whereas MISSOVER will assign the variable a missing value.

58

The Little SAS Book

2.15 Reading Delimited Files with the DATA Step
,, , , , , , ,
Delimited files are raw data files that have a special character separating data values. Many programs can save data as delimited files, often with commas or tab characters for delimiters. SAS gives you two options for the INFILE statement that make it easy to read delimited data files: the DLM= option and the DSD option.

The DLM= option If you read your data using list input, the DATA step expects your file to have spaces between your data values. The DELIMITER=, or DLM=, option in the INFILE statement allows you to read data files with other delimiters. The comma and tab characters are common delimiters found in data files, but you could read data files with any delimiter character by just enclosing the delimiter character in quotation marks after the DLM= option (i.e., DLM=’&’).

Example The following file is comma-delimited where students’ names are followed by the number of books they read for each week in a summer reading program:
Grace,3,1,5,2,6 Martin,1,2,4,1,3 Scott,9,10,4,8,6

If the same data had tab characters between values instead of commas, then you could use the following program to read the file. This program uses the DLM=’09’X option. In ASCII, 09 is the hexadecimal equivalent of a tab character, and the notation ‘09’X means a hexadecimal 09. If your computer uses EBCDIC (IBM mainframes) instead of ASCII, then use DLM=’05’X.
DATA reading; INFILE ’c:\MyRawData\Books.txt’ DLM = ’09’X; INPUT Name $ Week1 Week2 Week3 Week4 Week5; RUN;

By default, SAS interprets two or more delimiters in a row as a single delimiter. If your file has missing values, and two delimiters in a row indicate a missing value, then you will also need the DSD option in the INFILE statement.

The DSD option The DSD (Delimiter-Sensitive Data) option for the INFILE statement does three things for you. First, it ignores delimiters in data values enclosed in quotation marks. Second, it does not read quotation marks as part of the data value. Third, it treats two delimiters in a row as a missing value. The DSD option assumes that the delimiter is a comma. If your delimiter is not a comma then you can use the DLM= option with the DSD option to specify the delimiter. For example, to read a tab-delimited ASCII file with missing values indicated by two consecutive tab characters use
INFILE ’file-specification’ DLM=’09’X DSD;

Chapter 2: Getting Your Data into SAS

59

CSV files Comma-separated values files, or CSV files, are a common type of file that can be read with the DSD option. Many programs, such as Microsoft Excel, can save data in CSV format. These files have commas for delimiters and consecutive commas for missing values; if there are commas in any of the data values, then those values are enclosed in quotation marks.

Example The following example illustrates how to read a CSV file using the DSD option. Jerry’s Coffee Shop employs local bands to attract customers. Jerry keeps records of the number of customers for each band, for each night they play in his shop. The band’s name is followed by the date and the number of customers present at 8 p.m., 9 p.m., 10 p.m., and 11 p.m.
Lupine Lights,12/3/2003,45,63,70, Awesome Octaves,12/15/2003,17,28,44,12 "Stop, Drop, and Rock-N-Roll",1/5/2004,34,62,77,91 The Silveyville Jazz Quartet,1/18/2004,38,30,42,43 Catalina Converts,1/31/2004,56,,65,34

Notice that one group’s name has embedded commas, and is enclosed in quotation marks. Also, the last group has a missing data point for the 9 p.m. hour as indicated by two consecutive commas. Use the DSD option in the INFILE statement to read this data file. It is also prudent, when using the DSD option, to add the MISSOVER option if there is any chance that you have missing data at the end of your data lines (as in the first line of this data file). The MISSOVER option tells SAS that if it runs out of data, don’t go to the next data line to continue reading. Here is the program that will read this data file:
DATA music; INFILE ’c:\MyRawData\Bands.csv’ DLM = ’,’ DSD MISSOVER; INPUT BandName :$30. GigDate :MMDDYY10. EightPM NinePM TenPM ElevenPM; PROC PRINT DATA = music; TITLE ’Customers at Each Gig’; RUN;

Notice that for BandName and GigDate we use colon modified informats. The colon modifier tells SAS to read for the length of the informat (30 for BandName and 10 for GigDate), or until it encounters a delimiter, whichever comes first. Because the names of the bands are longer than the default length of 8 characters, we use the :$30. informat for BandName to read up to 30 characters. Here are the results of the PROC PRINT:
Customers at Each Gig Gig Date1 16042 16054 16075 16088 16101 Eight PM 45 17 34 38 56 Nine PM 63 28 62 30 . Ten PM 70 44 77 42 65 1 Eleven PM . 12 91 43 34

Notice that these dates are printed as the number of days since January 1, 1960. Section 4.5 discusses how to format these values into readable dates.

60

The Little SAS Book

2.16 Reading Delimited Files with the IMPORT Procedure
,, , , , , , ,
We suspect that by now you have realized that with SAS there is usually more than one way to accomplish the same result. In section 2.15 we showed you how to read delimited data files using the DATA step; now we are going to show you how to read delimited files a different way: using the 1 IMPORT procedure.

There are a few things that PROC IMPORT does for you that make it easy to read certain types of data files. PROC IMPORT will scan your data file and automatically determine the variable types (character or numeric), will assign proper lengths to the character variables, and can 2 recognize some date formats. PROC IMPORT will treat two consecutive delimiters in your data file as a missing value, will read values enclosed by quotation marks, and assign missing values to variables when it runs out of data on a line. Also, if you want, you can use the first line in your data file for the variable names. The IMPORT procedure actually writes a DATA step for you, and after you submit your program, you can look in the Log window to see the DATA step it produced. The simplest form of the IMPORT procedure is
PROC IMPORT DATAFILE = ’filename’ OUT = data-set;

where the file you want to read follows the DATAFILE= option, and the name of the SAS data set you want to create follows the OUT= option. SAS will determine the file type by the extension of the file as shown in the following table. Type of File Comma-delimited Tab-delimited Delimiters other than commas or tabs Extension .csv .txt DBMS Identifier CSV TAB DLM

If your file does not have the proper extension, or your file is of type DLM, then you must use the DBMS= option in the PROC IMPORT statement. Use the REPLACE option if you already have a SAS data set with the name you specified in the OUT= option, and you want to overwrite it. Here is the general form of PROC IMPORT with both the REPLACE and the DBMS options:
PROC IMPORT DATAFILE = ’filename’ OUT = data-set DBMS = identifier REPLACE;

The IMPORT procedure will, by default, get variable names from the first line in your data file. If you do not want this, then add the GETNAMES=NO statement after the PROC IMPORT statement. PROC IMPORT will assign the variables the names VAR1, VAR2, VAR3, and so on. Also if your data file is type DLM, PROC IMPORT assumes that the delimiter is a space. If you have a

1 2

The IMPORT procedure is available on UNIX, OpenVMS, and Windows only.

By default the IMPORT procedure will scan the first 20 rows of delimited files. If you have all missing data in these rows, then the Import Wizard may not read the file correctly. To change the number of rows, enter the REGEDIT command on the SAS command line, then select Find from the Edit menu and search for “GuessingRows” (make sure Value Names is checked). Then double click on “GuessingRows” to change the value.

Example The following example uses data about Jerry’s Coffee Shop where Jerry employs local bands to attract customers. Jerry keeps records of the number of customers present throughout the evening for each band. The data are the band name, followed by the gig date, and the number of customers present at 8 p.m., 9 p.m., 10 p.m., and 11 p.m. Notice that one of the bands, “Stop, Drop, and Rock-N-Roll,” has commas in the name of the band. When a data value contains the delimiter, then the value must be enclosed in quotation marks.
Band Name,Gig Date,Eight PM,Nine PM,Ten PM,Eleven PM Lupine Lights,12/3/2003,45,63,70, Awesome Octaves,12/15/2003,17,28,44,12 ”Stop, Drop, and Rock-N-Roll”,1/5/2004,34,62,77,91 The Silveyville Jazz Quartet,1/18/2004,38,30,42,43 Catalina Converts,1/31/2004,56,,65,34

Here is the program that will read this data file and print out the SAS data set after importing:
PROC IMPORT DATAFILE ='c:\MyRawData\Bands.csv' OUT = music REPLACE; PROC PRINT DATA = music; TITLE 'Customers at Each Gig'; RUN;

2.17 Reading PC Files with the IMPORT Procedure
If you have SAS/ACCESS for PC File Formats software, then you can use the IMPORT procedure to import several types of PC files. The IMPORT procedure will scan your file to 1 determine variable types and will, by default, use the first row of data for the variable names. In the Windows operating environment, you can import Microsoft Excel, Lotus, dBase, and 2 Microsoft Access files . On UNIX systems you can import dBase files, and starting with SAS 9.1, UNIX users can also read Microsoft Excel and Microsoft Access files. An alternative method of reading PC files in the Windows operating environment which does not require SAS/ACCESS is Dynamic Data Exchange (DDE) which is covered in section 2.18.

where filename is the file you want to read and data-set is the name of the SAS data set you want to create. The REPLACE option tells SAS to replace the SAS data set named in the OUT= option if it already exists. If your data file has the proper extension, as shown in the following table, then you may not need the DBMS= option. Of course, it never hurts to specify the DBMS. Type of File Microsoft Excel Extension .xls DBMS Identifier 3 EXCEL EXCEL5 EXCEL4 WK4 WK3 WK1 DBF

Lotus

dBase

.wk4 .wk3 .wk1 .dbf

If you are reading a Microsoft Excel file, and you have more than one sheet in your file, then you can specify which sheet to read using the following statement:
SHEET=name-of-sheet;

By default, the IMPORT procedure will take the variable names from the first row of the spreadsheet (Microsoft Excel and Lotus only). If you do not want this, then you can add the following statement to the procedure and SAS will name the variables F1, F2, and so on.
GETNAMES=NO;
1

By default the IMPORT procedure will scan the first 8 rows for Microsoft Excel files. If you have all missing data in these rows, then the IMPORT procedure may not read the file correctly. To change the number of rows, submit the REGEDIT command from the Windows command line (from the Start menu, select Run). Select Find from the Edit menu, and search for “TypeGuessRows”. Double-click on TypeGuessRows to change the value. If you are running Microsoft Windows 64-Bit Edition, then you cannot read Microsoft Access or Microsoft Excel 97, Excel 2000, or Excel 2002 files.
3 2

The DBMS identifiers, EXCEL, EXCEL2002, EXCEL2000, and EXCEL97, are interchangeable since all these types of Microsoft Excel files have the same format. If you want to read a Microsoft Excel4 or Microsoft Excel5 file, then you must specify the DBMS identifier.

The following are the DBMS identifiers for Microsoft Access: DBMS Identifier 5 ACCESS ACCESS97 Example Suppose you have the following Microsoft Excel spreadsheet which contains data about onion ring sales for the local minor league baseball team games. The visiting team name is followed by the sales in the concession stands and in the bleachers, then the number of hits and runs for each team. Type of File Microsoft Access Extension .mdb

The following program reads the Microsoft Excel file using the IMPORT procedure. Microsoft Excel does not need to be running to use the IMPORT procedure.
* Read an Excel spreadsheet using PROC IMPORT; PROC IMPORT DATAFILE = 'c:\MyExcelFiles\Onions.xls' OUT = sales; PROC PRINT DATA = sales; TITLE 'SAS Data Set Read From Excel File'; RUN;

Additional options may be needed if your Microsoft Access database is password protected. See the SAS Help and Documentation for more information.
5

4

The DBMS identifiers ACCESS, ACCESS2000, and ACCESS2002 are interchangeable since all these types of Microsoft Access files have the same format. If you want to read a Microsoft Access 97 file, then you must specify the DBMS identifier.

64

The Little SAS Book

2.18 Reading PC Files with DDE
One method for reading PC files is Dynamic Data Exchange (DDE). DDE has some advantages and disadvantages when compared to other methods of reading PC files. DDE can only be used in the Windows operating environment, and the application (such as Microsoft Excel) must be running on the computer while SAS is accessing the file. But DDE does allow you to directly access data stored in PC files and it does not require any additional SAS products to be licensed. There are several ways to access data through DDE. We will present three methods: ¨ ¨
¨

copying data to the clipboard specifying the DDE triplet starting the PC application from SAS, then reading the data.

Copying data to the clipboard If you don’t want to be bothered with determining the DDE triplet, then you can just copy the rows and columns that you want to read into SAS onto the clipboard. Then you use the CLIPBOARD keyword in the DDE FILENAME statement. For example, suppose you have the following spreadsheet open in Microsoft Excel.

The FILENAME statement defines a fileref (BASEBALL) as type DDE and specifies that you want to read the contents of the clipboard. By default, DDE assumes there are spaces between your data values. So, if you have embedded spaces in your data, then you will need the NOTAB and the DLM=‘09’x options in the INFILE statement. These two options tell SAS to put a tab character (NOTAB) between values and define the tab character as the delimiter (DLM=‘09’x). In addition, if you have missing values in your data, you will want to add the DSD and MISSOVER options to the INFILE statement. The DSD option treats two delimiters in a row as missing data and the MISSOVER options tells SAS not to go to the next data line to continue reading data if it runs out of data on the current line.

Specifying the DDE triplet The clipboard method is easy, but it requires you to take the extra step of copying the data to the clipboard before you run the SAS program. If you know the DDE triplet for the data you want to read, then you can just specify the triplet in the FILENAME statement. However figuring out what the DDE triplet is, can be a little tricky. Each application

Chapter 2: Getting Your Data into SAS

65

has its own way of specifying a DDE triplet. In general, the DDE triplet takes on the following form: application | topic ! item Specific information about DDE triplets can be found in the documentation for the PC application. However, there is a way to find out the DDE triplet for your data from within SAS. First, copy the data you want onto the clipboard, then toggle to your SAS session. From the Solutions menu, select Accessories. Then select DDE Triplet. A window will appear that will give the DDE triplet for the data that you copied to the clipboard. For example, the DDE triplet for the spreadsheet shown is
Excel|C:\MyFiles\[BaseBall.xls]sheet1!R2C1:R5C7

So, to read the same data by specifying the DDE triplet, you would use the following FILENAME statement and the rest of the program is the same:
FILENAME baseball DDE 'Excel|C:\MyFiles\[BaseBall.xls]sheet1!R2C1:R5C7';

Starting the application from SAS With both the previous examples, the PC application must first be running before you can run the SAS program. Since this is sometimes inconvenient, you may want to start the application from within SAS, then read the data using DDE. You need to add two things to your SAS program to do this. First, you need the NOXWAIT and NOXSYNC systems options, then you need to use the X statement. Here is an example program:
* Read an Excel spreadsheet using DDE; OPTIONS NOXSYNC NOXWAIT; X '"C:\MyFiles\BaseBall.xls"'; FILENAME baseball DDE 'Excel|C:\MyFiles\[BaseBall.xls]sheet1!R2C1:R5C7'; DATA sales; INFILE baseball NOTAB DLM='09'x DSD MISSOVER; LENGTH VisitingTeam $ 20; INPUT VisitingTeam CSales BSales OurHits TheirHits OurRuns TheirRuns; RUN;

The NOXWAIT and the NOXSYNC options tell SAS not to wait for input from the user, and to return control back to SAS after executing the command. The X statement simply tells Windows to execute the program or open the file that follows in quotation marks. Notice that there are two sets of quotation marks around the filename. If you have embedded spaces in the path for your filename, then you need to enclose the filename in two sets of quotation marks. Note that using this method, you must specify the DDE triplet in the FILENAME statement.

66

The Little SAS Book

2.19 Temporary versus Permanent SAS Data Sets
SAS data sets are available in two varieties: temporary and permanent. A temporary SAS data set is one that exists only during the current job or session and is automatically erased by SAS when you finish. If a SAS data set is permanent, that doesn’t mean that it lasts for eternity, just that it remains when the job or session is finished. Each type of data set has its own advantages. Sometimes you want to keep a data set for later use, and sometimes you don’t. In this book, most of our examples use temporary data sets because we don’t want to clutter up your disks. But, in general, if you use a data set more than once, it is more efficient to save it as a permanent SAS data set than to create a new temporary SAS data set every time you want to use the data.

SAS data set names All SAS data sets have a two-level name such as WORK.BIKESALES, with the two levels separated by a period. The first level of a SAS data set name, WORK in this case, is called its libref (short for SAS data library reference). A libref is like an arrow pointing to a particular location. Sometimes a libref refers to a physical location, such as a floppy disk or CD, while other times it refers to a logical location such as a directory or folder. The second level, BIKESALES, is the member name that uniquely identifies the data set within the library.
Both the libref and member name follow the standard rules for valid SAS names. They must start with a letter or underscore and contain only letters, numerals, or underscores. However, librefs cannot be longer than 8 characters while member names can be up to 32 characters long. You never explicitly tell SAS to make a data set temporary or permanent, it is just implied by the name you give the data set when you create it. Most data sets are created in DATA steps, but PROC steps can also create data sets. If you specify a two-level name (and the libref is something other than WORK) then your data set will be permanent. If you specify just one level of the data set name (as we have in most of the examples in this book), then your data set will be temporary. SAS will use your one-level name as the member name and automatically append the libref WORK. By definition, any SAS data set with a libref of WORK is a temporary data set and will be erased by SAS at the end of your job or session. Here are some sample DATA statements and the characteristics of the data sets they create: DATA statement DATA ironman; DATA WORK.tourdefrance; DATA Mylib.doublecentury; Libref WORK WORK Mylib Member name ironman tourdefrance doublecentury Type temporary temporary permanent

Notice that the libref WORK does not appear in the DATA statement. Because the data set has just a one-level name, SAS assigns the default library, WORK, and uses DISTANCE as the member name within that library. The log contains this note with the complete, two-level name:
NOTE: The data set WORK.DISTANCE has 1 observations and 2 variables.

Permanent SAS data sets Before you can use a libref, you need to define it. You can define libraries using the New Library window in SAS Explorer (covered in section 1.11). You can also use the LIBNAME statement (covered in section 2.20) or you can let SAS define the libref for you 1 using direct referencing (covered in section 2.21) .
The Mylib library, defined in the New Library window shown in the figure, points to the ‘Ruiz Racing Bicycles’ folder under the ‘Documents and Settings’ folder, on the C drive (Windows).

The following program is the same as the preceding one except that it creates a permanent SAS data set. Notice that a two-level name appears in the DATA statement.
DATA Mylib.distance; Miles = 26.22; Kilometers = 1.61 * Miles; PROC PRINT DATA = Mylib.distance; RUN;

This time the log contains this note:
NOTE: The data set MYLIB.DISTANCE has 1 observations and 2 variables.

This is a permanent SAS data set because the libref is not WORK.

1

With batch processing under OS/390 or z/OS, you may also use Job Control Language (JCL). The DDname is your libref.

A libref is a nickname that corresponds to the location of a SAS data library. When you use a libref as the first level in the name of a SAS data set, SAS knows to look for that data set in that location. This section shows you how to define a libref using the LIBNAME statement which is the most universal (and therefore most portable) method of creating a libref. You can also define a libref using the New Library window (covered in section 1.11) or for 1 some computers, operating environment control language. The basic form of the LIBNAME statement is
LIBNAME libref ’your-SAS-data-library’;

After the keyword LIBNAME, you specify the libref and then the location of your permanent SAS data set in quotation marks. Librefs must be eight characters or shorter; start with a letter or underscore; and contain only letters, numerals, or underscores. Here is the general form of LIBNAME statements for individual operating environments: Windows: UNIX: OpenVMS: OS/390 or z/OS: LIBNAME LIBNAME LIBNAME LIBNAME libref libref libref libref ’drive:\directory’; ’/home/path’; ’[userid.directory]’; ’data-set-name’;

This program sets up a libref named PLANTS pointing to the MySASLib directory on the C drive (Windows). Then it reads the raw data from a file called Mag.dat, creating a permanent SAS data set named MAGNOLIA which is stored in the PLANTS library.
LIBNAME plants ’c:\MySASLib’; DATA plants.magnolia; INFILE ’c:\MyRawData\Mag.dat’; INPUT ScientificName $ 1-14 CommonName $ 16-32 MaximumHeight AgeBloom Type $ Color $; RUN;

1

With batch processing under OS/390 or z/OS, you may use Job Control Language (JCL). The DDname is your libref.

Chapter 2: Getting Your Data into SAS

69

The log contains this note showing the two-level data set name:
NOTE: The data set PLANTS.MAGNOLIA has 5 observations and 6 variables.

If you print a directory of files on your computer, you will not see a file named PLANTS.MAGNOLIA. That is because operating environments have their own systems for naming files. When run under Windows, UNIX, or OpenVMS, this data set will be called magnolia.sas7bdat. Under OS/390 or z/OS, the filename would be the data-set-name specified in the LIBNAME statement.

Reading a permanent SAS data set To use a permanent SAS data set, you can include a LIBNAME statement in your program and refer to the data set by its two-level name. For instance, if you wanted to go back later and print the permanent data set created in the last example, you could use the following statements:
LIBNAME example ’c:\MySASLib’; PROC PRINT DATA = example.magnolia; TITLE ’Magnolias’; RUN;

This time the libref in the LIBNAME statement is EXAMPLE instead of PLANTS, but it points to the same location as before, the MySASLib directory on the C drive. The libref can change, but the member name, MAGNOLIA, stays the same. The output looks like this:
Magnolias Maximum Height 80 80 12 25 10 Age Bloom 15 20 4 3 3 1

2.21 Using Permanent SAS Data Sets by Direct Referencing
If you don’t want to be bothered with setting up librefs and defining SAS libraries, but you still want to use permanent SAS data sets, then you can use direct referencing. Direct referencing still uses SAS libraries, but instead of defining the library yourself, you let SAS do it for you. Using direct referencing is easy, just take your operating environment’s name for a file, enclose it in quotation marks, and put it in your program. The quotation marks tell SAS that this is a permanent SAS data set. Here is the general form of the DATA statement for creating permanent SAS data sets under different operating environments: Windows: UNIX: OpenVMS: OS/390 or z/OS: DATA DATA DATA DATA ’drive:\directory\filename’; ’/home/path/filename’; ’[userid.directory]filename’; ’data-set-name’;

For directory-based operating environments, if you leave out the directory or path, then SAS uses the current working directory. For example, this statement would create a permanent SAS data set named TREES in your current working directory.
DATA ’trees’;

For UNIX and OpenVMS operating environments, by default, your current directory is the directory where you started SAS. You can change the current directory for the SAS session by choosing Change Directory from the Options menu of the Tools pull-down menu. Under Windows the name of the current working directory is displayed at the bottom of the SAS window. You can change the directory for the current SAS session by double-clicking on the directory name which will open the Change Folder window.

This program reads the raw data from a file called Mag.dat, creating a permanent SAS data set named MAGNOLIA. The MAGNOLIA data set is stored in the MySASLib directory on the C drive (Windows).
DATA ’c:\MySASLib\magnolia’; INFILE ’c:\MyRawData\Mag.dat’; INPUT ScientificName $ 1-14 CommonName $ 16-32 MaximumHeight AgeBloom Type $ Color $; RUN;

If you look in your SAS log you will see this note:
NOTE: The data set c:\MySASLib\magnolia has 5 observations and 6 variables.

Chapter 2: Getting Your Data into SAS

71

This is a permanent SAS data set, so SAS will not erase it. If you list the files in the MySASLib directory, you will see a file named magnolia.sas7bdat. Notice that SAS automatically appended a file extension, even though no extension appeared in the SAS program. When you put quotation marks around your data set name, you are using direct referencing, and SAS creates a permanent SAS data set. Since you haven't specified a libref, SAS makes up a libref for you. You don’t need to know the name of the libref that SAS makes up, but it is there and, you can see it in the Active Libraries window. This is what the Active Libraries window looks like after running the previous program. SAS has created a library named Wc000001 which contains the MAGNOLIA data set.

Reading SAS data sets using direct referencing To read a permanent SAS data set using direct referencing, simply enclose the path and name for the data set in quotation marks wherever you would use a SAS data set name. For example, to print the MAGNOLIA data set, you could use the following statements:
PROC PRINT DATA = ’c:\MySASLib\magnolia’; TITLE ’Magnolias’; RUN;

2.22 Listing the Contents of a SAS Data Set
To use a SAS data set, all you need to do is tell SAS the name and location of the data set you want, and SAS will figure out what is in it. SAS can do this because SAS data sets are selfdocumenting, which is another way of saying that SAS automatically stores information about the data set (also called the descriptor portion) along with the data. You can’t display a SAS data set on your computer screen using a word processor. However, there is an easy way to get a description of a SAS data set; you simply run the CONTENTS procedure. PROC CONTENTS is a simple procedure. In most cases you just type the keywords PROC CONTENTS and specify the data set you want with the DATA= option:
PROC CONTENTS DATA = data-set;

If you omit the DATA= option, then by default SAS will use the most recently created data set.

Example

The following DATA step creates a data set so we can run PROC CONTENTS:

Note that the DATA step above includes a LABEL statement. For each variable, you can specify a label up to 256 characters long. These optional labels allow you to document your variables in more detail than is possible with just variable names. If you specify a LABEL statement in a DATA step, then the descriptions will be stored in the data set and will be printed by PROC CONTENTS. You can also use LABEL statements in PROC steps to customize your reports, but then the labels apply only for the duration of the PROC step and are not stored in the data set. INFORMAT and FORMAT statements also appear in this program. You can use these optional statements to associate informats or formats with variables. Just as informats give SAS special instructions for reading a variable, formats give SAS special instructions for writing a variable. If you specify an INFORMAT or FORMAT statement in a DATA step, then the name of that informat or format will be saved in the data set and printed by PROC CONTENTS. FORMAT statements, like LABEL statements, can be used in PROC steps to customize your reports, but 1 then the name of the format is not stored in the data set.

The output starts with information about your data set and then describes each variable. For the data set     Data set name Number of observations Number of variables Date created For each variable  Type (numeric or character)  Length (storage size in bytes)  Format for printing (if any)  Informat for input (if any)  Label (if any)

3

‘‘

Contrariwise,” continued Tweedledee,” if it was so, it might be; and if it were so, it would be; but as it isn’t, it ain’t. That’s logic.

Creating and Redefining Variables
If someone were to compile a list of the most popular things to do with SAS software, creating and redefining variables would surely be on it. Fortunately, SAS is flexible and uses a common sense approach to these tasks. You create and redefine variables with assignment statements using this basic form: variable = expression;

On the left side of the equal sign is a variable name, either new or old. On the right side of the equal sign may appear a constant, another variable, or a mathematical expression. Here are examples of these basic types of assignment statements: Type of expression numeric constant character constant a variable addition subtraction multiplication division exponentiation Assignment statement
Qwerty Qwerty Qwerty Qwerty Qwerty Qwerty Qwerty Qwerty = = = = = = = = 10; 'ten'; OldVar; OldVar + 10; OldVar - 10; OldVar * 10; OldVar / 10; OldVar ** 10;

Whether the variable Qwerty is numeric or character depends on the expression that defines it. When the expression is numeric, Qwerty will be numeric; when it is character, Qwerty will be character. When deciding how to interpret your expression, SAS follows the standard mathematical rules of precedence: SAS performs exponentiation first, then multiplication and division, followed by addition and subtraction. You can use parentheses to override that order. Here are two similar SAS statements showing that a couple of parentheses can make a big difference: Assignment statement x = 10 * 4 + 3 ** 2; x = 10 * (4 + 3 ** 2);

Result x = 49 x = 130

While SAS can read expressions with or without parentheses, people often can’t. If you use parentheses, your programs will be a lot easier to read.

Example The following raw data are from a survey of home gardeners. Gardeners were asked to estimate the number of pounds they harvested for four crops: tomatoes, zucchini, peas, and grapes.
Gregor Molly Luther Susan 10 2 15 5 50 10 20 0 40 0 10 1000 15 50 . 20

This program contains five assignment statements. The first creates a new variable, Zone, equal to a numeric constant, 14. The variable Type is set equal to a character constant, home. The variable Zucchini is multiplied by 10 because that just seems natural for zucchini. Total is the sum for all the types of plants. PerTom is not a genetically engineered tomato but the percentage of harvest which were tomatoes. The report from PROC PRINT contains all the variables, old and new:
Home Gardening Survey Obs Name 1 2 3 4 Gregor Molly Luther Susan Tomato Zucchini Peas Grapes Zone Type 10 15 50 20 20 50 100 0 40 10 15 . 0 1000 50 20 14 14 14 14 home home home home Total 70 1075 215 . 1 PerTom 14.2857 1.3953 23.2558 .

Notice that the variable Zucchini appears only once because the new value replaced the old value. The other four assignment statements each created a new variable. When a variable is new, SAS adds it to the data set you are creating. When a variable already exists, SAS replaces the original value with the new one. Using an existing name has the advantage of not cluttering your data set with a lot of similar variables. However, you don’t want to overwrite a variable unless you are really sure you won’t need the original value later. The variable Peas had a missing value for the last observation. Because of this, the variables Total and PerTom, which are calculated from Peas, were also set to missing and this message appeared in the log:
NOTE: Missing values were generated as a result of performing an operation on missing values.

This message is a flag that often indicates an error. However, in this case it is not an error but 1 simply the result of incomplete data collection.

1

If you want to add only non-missing values, you can use the SUM function discussed in section 10.7.

78

The Little SAS Book

3.2

Using SAS Functions
Sometimes a simple expression, using only arithmetic operators, does not give you the new value you are looking for. This is where functions are handy, simplifying your task because SAS has already done the programming for you. All you need to do is plug the right values into the function and out comes the result—like putting a dollar in a change machine and getting back four quarters.

FUNCTION

SAS has over 400 functions in the following general areas: Character Date and Time Financial Macro Mathematical Probability Random Number Sample Statistics State and ZIP Code

CHANGE

$

ARGUMENT

Section 3.3 gives a sample of the most common SAS functions.

RESULT

Functions perform a calculation on, or a transformation of, the arguments given in parentheses following the function name. SAS functions have the following general form: function-name(argument, argument, ...)

All functions must have parentheses even if they don’t require any arguments. Arguments are separated by commas and can be variable names, constant values such as numbers or characters enclosed in quotation marks, or expressions. The following statement computes Birthday as a SAS date value using the function MDY and the variables MonthBorn, DayBorn, and YearBorn. The MDY function takes three arguments, one each for the month, day, and year:
Birthday = MDY(MonthBorn, DayBorn, YearBorn);

Functions can be nested, where one function is the argument of another function. For example, the following statement calculates NewValue using two nested functions, INT and LOG:
NewValue = INT(LOG(10));

The result for this example is 2, the integer portion of the natural log of the numeric constant 10 (2.3026). Just be careful when nesting functions that each parenthesis has a mate.

Example Data from a pumpkin carving contest illustrate the use of several functions. The contestants’ names are followed by their age, type of pumpkin (carved or decorated), date of entry, and the scores from five judges:

The variable AvgScore is created using the MEAN function, which returns the mean of the nonmissing arguments. This differs from simply adding the arguments together and dividing by their number, which would return a missing value if any of the arguments were missing. The variable DayEntered is created using the DAY function, which returns the day of the month. SAS has all sorts of functions for manipulating dates, and what’s great about them is that you don’t have to worry about things like leap year—SAS takes care of that for you. The variable Type is transformed using the UPCASE function. SAS is case sensitive when it comes to variable values; a 'd' is not the same as 'D'. The data file has both lowercase and uppercase letters for the variable Type, so the function UPCASE is used to make all the values uppercase. Here are the results:
Pumpkin Carving Contest 1

Left aligns a SAS character expression Returns the length of an argument not counting trailing blanks (missing values have a length of 1) Extracts a substring from an argument starting 3 at 'position' for 'n' characters or until end if no 'n' Replaces 'from' characters in 'source' with 'to' characters (one to one replacement only—you can’t replace one character with two, for example) Removes trailing blanks from character expression Converts all letters in argument to uppercase
4

Returns the day of the month from a SAS date value Returns a SAS date value from month, day, and year values Returns the month (1-12) from a SAS date value Returns the yearly quarter (1-4) from a SAS date value Returns the current date as a SAS date value

Check the SAS Help and Documentation for a complete list of functions. arg is short for argument, which means a literal value, variable name, or expression. SUBSTR has a different function when on the left side of an equal sign. A SAS date value is the number of days since January 1, 1960.

Using IF-THEN Statements
Frequently, you want an assignment statement to apply to some observations but not all—under some conditions, but not others. This is called conditional logic, and you do it with IF-THEN statements:
IF condition THEN action;

The condition is an expression comparing one thing to another, and the action is what SAS should do when the expression is true, often an assignment statement. For example
IF Model = 'Mustang' THEN Make = 'Ford';

This statement tells SAS to set the variable Make equal to Ford whenever the variable Model equals Mustang. The terms on either side of the comparison may be constants, variables, or expressions. Those terms are separated by a comparison operator, which may be either symbolic or mnemonic. The decision of whether to use symbolic or mnemonic operators depends on your personal preference and the symbols available on your keyboard. Here are the basic comparison operators: Symbolic = Ø =, ^ =, or ~ = > < >= '01JAN2003'D THEN NewCard = 'yes'; PROC PRINT DATA = librarycards; FORMAT IssueDate MMDDYY8. ExpireDate WEEKDATE17.; TITLE 'SAS Dates without and with Formats'; RUN;

Formats can be used in PUT statements and PUT functions in DATA steps, and in FORMAT statements in either DATA or PROC steps.

92

The Little SAS Book

3.9

Using the RETAIN and Sum Statements
When reading raw data, SAS sets the values of all variables equal to missing at the start of each iteration of the DATA step. These values may be changed by INPUT or assignment statements, but they are set back to missing again when SAS returns to the top of the DATA step to process the next observation. RETAIN and sum statements change this. If a variable appears in a RETAIN statement, then its value will be retained from one iteration of the DATA step to the next. A sum statement also retains values from the previous iteration of the DATA step, but then adds to it the value of an expression.

RETAIN statement Use the RETAIN statement when you want SAS to preserve a variable’s value from the previous iteration of the DATA step. The RETAIN statement can appear anywhere in the DATA step and has the following form, where all variables to be retained are listed after the RETAIN keyword:
RETAIN variable-list;

You can also specify an initial value, instead of missing, for the variables. All variables listed before an initial value will start the first iteration of the DATA step with that value:
RETAIN variable-list initial-value;

Sum statement A sum statement also retains values from the previous iteration of the DATA step, but you use it for the special cases where you simply want to cumulatively add the value of an expression to a variable. A sum statement, like an assignment statement, contains no keywords. It has the following form: variable + expression;

No, there is no typo here and no equal sign either. This statement adds the value of the expression to the variable while retaining the variable’s value from one iteration of the DATA step to the next. The variable must be numeric and has the initial value of zero. This statement can be re-written using the RETAIN statement and SUM function as follows:
RETAIN variable 0; variable = SUM(variable, expression);

As you can see, a sum statement is really a special case of using RETAIN.

Example This example illustrates the use of both the RETAIN and sum statements. The minor league baseball team, the Walla Walla Sweets, has the following data about their games. The date the game was played and the team played are followed by the number of hits and runs for the game:
6-19 6-20 6-23 6-24 6-25 6-30 7-1 7-4 7-4 7-5 Columbia Peaches Columbia Peaches Plains Peanuts Plains Peanuts Plains Peanuts Gilroy Garlics Gilroy Garlics Sacramento Tomatoes Sacramento Tomatoes Sacramento Tomatoes 8 3 10 5 3 4 7 2 12 8 4 4 9 4 15 9 10 10 2 3

Chapter 3: Working with Your Data

93

The team wants two additional variables in their data set. One shows the cumulative number of runs for the season, and the other shows the maximum number of runs in a game to date. The following program uses a sum statement to compute the cumulative number of runs, and the RETAIN statement and MAX function to determine the maximum number of runs in a game to date:
* Using RETAIN and sum statements to find most runs and total runs; DATA gamestats; INFILE 'c:\MyRawData\Games.dat'; INPUT Month 1 Day 3-4 Team $ 6-25 Hits 27-28 Runs 30-31; RETAIN MaxRuns; MaxRuns = MAX(MaxRuns, Runs); RunsToDate + Runs; PROC PRINT DATA = gamestats; TITLE "Season's Record to Date"; RUN;

The variable MaxRuns is set equal to the maximum of its value from the previous iteration of the DATA step (since it appears in the RETAIN statement) or the value of the variable Runs. The variable RunsToDate adds the number of runs per game, Runs, to itself while retaining its value from one iteration of the DATA step to the next. This produces a cumulative record of the number of runs. Here are the results:
Season's Record to Date Max Runs 3 5 5 5 8 8 8 9 10 10 1 Runs ToDate 3 8 12 14 22 26 30 39 49 52

3.10 Simplifying Programs with Arrays
Sometimes you want to do the same thing to many variables. You may want to take the log of every numeric variable or change every occurrence of zero to a missing value. You could write a series of assignment statements or IF statements, but if you have a lot of variables to transform, using arrays will simplify and shorten your program. An array is an ordered group of similar items. You might think your local mall has a nice array of stores to choose from. In SAS, an array is a group of variables. You can define an array to be any group of variables you like, as long as they are either all numeric or all character. The variables can be ones that already exist in your data set, or they can be new variables that you want to create. Arrays are defined using the ARRAY statement in the DATA step. The ARRAY statement has the following general form:
ARRAY name (n) $ variable-list;

In this statement, name is a name you give to the array, and n is the number of variables in the array. Following the (n) is a list of variable names. The number of variables in the list must equal the number given in parentheses. (You may use {} or [ ] instead of parentheses if you like.) This is called an explicit array, where you explicitly state the number of variables in the array. The $ is needed if the variables are character and is only necessary if the variables have not previously been defined. The array itself is not stored with the data set; it is defined only for the duration of the DATA step. You can give the array any name, as long as it does not match any of the variable names in your data set or any SAS keywords. The rules for naming arrays are the same as those for naming variables (must be 32 characters or fewer and start with a letter or underscore followed by letters, numerals, or underscores). To reference a variable using the array name, give the array name and the subscript for that variable. The first variable in the variable list has subscript 1, the second has subscript 2, and so forth. So if you have an array defined as
ARRAY store (4) Macys Penneys Sears Target;

STORE(1) is the variable Macys, STORE(2) is the variable Penneys, STORE(3) is the variable Sears, and STORE(4) is the variable Target. This is all just fine, but simply defining an array doesn’t do anything for you. You want to be able to use the array to make things easier for you.

The listener’s city of residence, age, and their responses to all ten songs are listed. The following program changes all the 9s to missing values. (The variables are named using the first letters of the words in the song’s title.)
* Change all 9s to missing values; DATA songs; INFILE 'c:\MyRawData\WBRK.dat'; INPUT City $ 1-15 Age domk wj hwow simbh kt aomm libm tr filp ttr; ARRAY song (10) domk wj hwow simbh kt aomm libm tr filp ttr; DO i = 1 TO 10; IF song(i) = 9 THEN song(i) = .; END; PROC PRINT DATA = songs; TITLE 'WBRK Song Survey'; RUN;

An array, SONG, is defined as having ten variables, the same ten variables that appear in the INPUT statement representing the ten songs. Next comes an iterative DO statement. All statements between the DO statement and the END statement are executed, in this case, ten times, once for each variable in the array. The variable I is used as an index variable and is incremented by 1 each time through the DO loop. The first time through the DO loop, the variable I has a value of 1 and the IF statement would read IF song(1)=9 THEN song(1)=.;, which is the same as IF domk=9 THEN domk=.;. The second time through, I has a value of 2 and the IF statement would read IF song(2)=9 THEN song(2)=.;, which is the same as IF wj=9 THEN wj=.;. This continues through all 10 variables in the array. Here are the results:
WBRK Song Survey Obs 1 2 3 4 5 City Albany Richmond Oakland Richmond Berkeley Age domk wj hwow simbh kt aomm libm tr filp ttr 54 33 27 41 18 4 5 1 4 3 3 2 3 3 4 5 4 2 5 . . 3 . 5 1 . . . 5 4 2 2 . 2 . 1 . 3 . 3 4 3 4 4 . 4 3 2 5 3 . 3 3 5 2 i 11 11 11 11 11 1

Notice that the array members SONG(1) to SONG(10) did not become part of the data set, but the variable I did. You could have written ten IF statements instead of using arrays and accomplished the same result. In this program it would not have made a big difference, but if you had 100 songs in your survey instead of ten, then using arrays would clearly be a better solution.

96

The Little SAS Book

3.11 Using Shortcuts for Lists of Variable Names
As the title states, this section is about shortcuts, shorthand ways of writing lists of variable names. While writing SAS programs, you will often need to write a list of variable names. When defining ARRAYS, using functions like MEAN or SUM, or using SAS procedures, you must specify which variables to use. Now, if you only have a handful of variables, you might not feel a need for a shortcut. But if, for example, you need to define an array with 100 elements, you might be a little grumpy after typing in the 49th variable name knowing you still have 51 more to go. You might even think, “There must be an easier way.” Well, there is. You can use an abbreviated list of variable names anywhere you can use a regular variable list. In functions, abbreviated lists must be preceded by the keyword OF (for example, SUM(OF Cat8 Cat12)). Otherwise, you simply replace the regular list of variables with the abbreviated one.

Numbered range lists Variables which start with the same characters and end with consecutive numbers can be part of a numbered range list. The numbers can start and end anywhere as long as the number sequence between is complete. For example, the following INPUT statement shows a variable list and its abbreviated form:
Variable list
INPUT Cat8 Cat9 Cat10 Cat11 Cat12;

Abbreviated list
INPUT Cat8 - Cat12;

Name range lists Name range lists depend on the internal order, or position, of the variables in the SAS data set. This is determined by the order of appearance of the variables in the DATA step. For example, if you had the following DATA step, then the internal variable order would be Y A C H R B:
DATA example; INPUT y a c h r; b = c + r; RUN;

To specify a name range list, put the first variable, then two hyphens, then the last variable. The following PUT statements show the variable list and its abbreviated form using a named range: Variable list
PUT y a c h r b;

Abbreviated list
PUT y -- b;

If you are not sure of the internal order, you can find out using PROC CONTENTS with the POSITION option. The following program will list the variables in the permanent SAS data set DISTANCE sorted by position:
LIBNAME mydir 'c:\MySASLib'; PROC CONTENTS DATA = mydir.distance POSITION; RUN;

Use caution when including name range lists in your programs. Although they can save on typing, they may also make your programs more difficult to understand and debug.

Special SAS name lists The special name lists, _ALL_, _CHARACTER_, and _NUMERIC_ can also be used any place you want either all the variables, all the character variables, or all the

Chapter 3: Working with Your Data

97

numeric variables in a SAS data set. These name lists are useful when you want to do something like compute the mean of all the numeric variables for an observation (MEAN(OF _NUMERIC_)), or list the values of all variables in an observation (PUT _ALL_;).

Example The radio station WBRK wants to modify the program from the previous section, which changes all 9s to missing values. Now, instead of changing the original variables, they use the following program to create new variables (Song1 through Song10) which will have the new missing values. This program also computes the average score using the MEAN function.
DATA songs; INFILE 'c:\MyRawData\WBRK.dat'; INPUT City $ 1-15 Age domk wj hwow simbh kt aomm libm tr filp ttr; ARRAY new (10) Song1 - Song10; ARRAY old (10) domk -- ttr; DO i = 1 TO 10; IF old(i) = 9 THEN new(i) = .; ELSE new(i) = old(i); END; AvgScore = MEAN(OF Song1 - Song10); PROC PRINT DATA = songs; TITLE 'WBRK Song Survey'; RUN;

Note that both ARRAY statements use abbreviated variable lists; array NEW uses a numbered range list and array OLD uses a name range list. Inside the iterative DO loop, the Song variables (array NEW) are set equal to missing if the original variable (array OLD) had a value of 9. Otherwise, they are set equal to the original values. After the DO loop, a new variable, AvgScore, is created using an abbreviated variable list in the function MEAN. The output includes variables from both the OLD array (domk, wj, ... ttr) and NEW array (Song1 - Song10):
WBRK Song Survey A v g S c o r e 3.28571 3.12500 2.57143 4.22222 2.85714 1

Using SAS Procedures
Using a procedure, or PROC, is like filling out a form. Someone else designed the form, and all you have to do is fill in the blanks and choose from a list of options. Each PROC has its own unique form with its own list of options. But while each procedure is unique, there are similarities too. This section discusses some of those similarities. All procedures have required statements, and most have optional statements. PROC PRINT, for example, requires only two words:
PROC PRINT;

However, by adding optional statements you could make this procedure a dozen lines or even longer.

PROC statement All procedures start with the keyword PROC followed by the name of the procedure, such as PRINT or CONTENTS. Options, if there are any, follow the procedure name. The DATA= option tells SAS which data set to use as input for that procedure. In this case, SAS will use a temporary SAS data set named BANANA:
PROC CONTENTS DATA = banana;

The DATA= option is, of course, optional. If you skip it, then SAS will use the most recently created data set, which is not necessarily the same as the most recently used. Sometimes it is easier to specify the data set you want than to figure out which data set SAS will use by default. To use a permanent SAS data set, issue a LIBNAME statement to set up a libref pointing to the location of your data set, and put the data set’s two-level name in the DATA= option, as discussed in section 2.20,
LIBNAME tropical 'c:\MySASLib'; PROC CONTENTS DATA = tropical.banana;

or refer to it directly by placing your operating environment’s name for the permanent SAS data set between quotation marks, as discussed in section 2.21.
PROC CONTENTS DATA = 'c:\MySASLib\banana';

BY statement The BY statement is required for only one procedure, PROC SORT. In PROC SORT the BY statement tells SAS how to arrange the observations. In all other procedures, the BY statement is optional, and tells SAS to perform a separate analysis for each combination of values of the BY variables rather than treating all observations as one group. For example, this statement tells SAS to run a separate analysis for each state:
BY State;

All procedures, except PROC SORT, assume that your data are already sorted by the variables in your BY statement. If your observations are not already sorted, then use PROC SORT to do the job.

TITLE and FOOTNOTE statements You have seen TITLE statements many times in this book. FOOTNOTE works the same way, but prints at the bottom of the page. These global statements are not technically part of any step. You can put them anywhere in your program, but since they apply to the procedure output it generally makes sense to put them with the procedure.

Chapter 4: Sorting, Printing, and Summarizing Your Data

101

The most basic TITLE statement consists of the keyword TITLE followed by your title enclosed in quotation marks. SAS doesn’t care if the two quotation marks are single or double as long as they are the same:
TITLE 'This is a title';

If you find that your title contains an apostrophe, use double quotation marks around the title, or replace the single apostrophe with two:
TITLE ”Here’s another title”; TITLE ’Here’’s another title’;

You can specify up to ten titles or footnotes by adding numbers to the keywords TITLE and FOOTNOTE:
FOOTNOTE3 ’This is the third footnote’;

Titles and footnotes stay in effect until you replace them with new ones or cancel them with a null statement. The following null statement would cancel all current titles:
TITLE;

When you specify a new title or footnote, it replaces the old title or footnote with the same number and cancels those with a higher number. For example, a new TITLE2 cancels an existing TITLE3, if there is one.

LABEL statement By default, SAS uses variable names to label your output, but with the LABEL statement you can create more descriptive labels, up to 256 characters long, for each variable. This statement creates labels for the variables ReceiveDate and ShipDate:
LABEL ReceiveDate = ’Date order was received’ ShipDate = ’Date merchandise was shipped’;

When a LABEL statement is used in a DATA step, the labels become part of the data set; but when used in a PROC, the labels stay in effect only for the duration of that step.

Customizing output You have a lot of control over the output produced by procedures. Using system options, you can set many features such as centering, dates, line size, and page size (section 1.13). With the Output Delivery System, you can you can also change the overall style of your output, produce output in different formats (such as HTML or RTF), or change almost any detail of your output (section 1.10 and chapter 5). Output data sets Most procedures produce some kind of report, but sometimes you would like the results of the procedure saved as a SAS data set so you can perform further analysis. You can create SAS data sets from any procedure output using the ODS OUTPUT statement (section 5.3). Some procedures can also write a SAS data set using an OUTPUT statement or OUT= option.

102

The Little SAS Book

4.2
A B C A B

Subsetting in Procedures with the WHERE Statement
WHERE

A A

One optional statement for any PROC that reads a SAS data set is the WHERE statement. The WHERE statement tells a procedure to use a subset of the data. There are other ways to subset data, as you probably remember, so you could get by 1 without ever using the WHERE statement. However, the WHERE statement is a shortcut. While the other methods of subsetting work only in DATA steps, the WHERE statement works in PROC steps too.

Unlike subsetting in a DATA step, using a WHERE statement in a procedure does not create a new data set. That is one of the reasons why WHERE statements are sometimes more efficient than other ways of subsetting. The basic form of a WHERE statement is
WHERE condition;

Only observations satisfying the condition will be used by the PROC. This may look familiar since it is similar to a subsetting IF. The left side of that condition is a variable name, and the right side is a variable name, a constant, or a mathematical expression. Mathematical expressions can contain the standard arithmetic symbols for addition (+), subtraction (-), multiplication (*), division (/), and exponentiation (**). Between the two sides of the expression, you can use comparison and logical operators; those operators may be symbolic or mnemonic. Here are the most frequently used operators: Symbolic = Ø=, ~=, ^= > < >= 20; Rainfall < AvgRain; Rainfall >= AvgRain + 5; Rainfall 20 AND Temp < 90; Rainfall > 20 OR Temp < 90; Region IS NOT MISSING; Region BETWEEN 'Plain' AND 'Spain'; Region CONTAINS 'ain'; Region IN ('Rain', 'Spain', 'Plain');

1

Subsetting while reading a raw data file is discussed in section 2.13, and the subsetting IF statement is discussed in section 3.6.

To make this example more realistic, it has two steps: one to create a permanent SAS data set, the other to subset the data. The first DATA step reads the data from a file named Artists.dat, and uses direct referencing (you could use a LIBNAME statement instead) to create a permanent SAS data set named STYLE in a directory named MySASLib (Windows).
DATA 'c:\MySASLib\style'; INFILE 'c:\MyRawData\Artists.dat'; INPUT Name $ 1-21 Genre $ 23-40 Origin $ 42; RUN;

Suppose a day later you wanted to print a list of just the impressionist painters. The quick-and-easy way to do this is with a WHERE statement and PROC PRINT. The quotation marks around the data set name tell SAS that this is a permanent SAS data set.
PROC PRINT DATA = 'c:\MySASLib\style'; WHERE Genre = 'Impressionism'; TITLE 'Major Impressionist Painters'; FOOTNOTE 'F = France N = Netherlands U = US'; RUN;

There are many reasons for sorting your data: to organize data for a report, before combining data sets, or before using a BY statement in another PROC or DATA step. Fortunately, PROC SORT is quite simple. The basic form of this procedure is
PROC SORT; BY variable-1 ... variable-n;

The variables named in the BY statement are called BY variables. You can specify as many BY variables as you wish. With one BY variable, SAS sorts the data based on the values of that variable. With more than one variable, SAS sorts observations by the first variable, then by the second variable within categories of the first, and so on. A BY group is all the observations that have the same values of BY variables. If, for example, your BY variable is State then all the observations for North Dakota form one BY group. The DATA= and OUT= options specify the input and output data sets. If you don’t specify the DATA= option, then SAS will use the most recently created data set. If you don’t specify the OUT= option, then SAS will replace the original data set with the newly sorted version. This sample statement tells SAS to sort the data set named MESSY, and then put the sorted data into a data set named NEAT:
PROC SORT DATA = messy OUT = neat;

The NODUPKEY option tells SAS to eliminate any duplicate observations that have the same values for the BY variables. To use this option, just add NODUPKEY to the PROC SORT statement:
PROC SORT DATA = messy OUT = neat NODUPKEY;

By default SAS sorts data in ascending order, from lowest to highest or from A to Z. To have your data sorted from highest to lowest, add the keyword DESCENDING to the BY statement before each variable that should be sorted from highest to lowest. This statement tells SAS to sort first by State (from A to Z) and then by City (from Z to A) within State:
BY State DESCENDING City;

The DATA step reads the raw data from a file called Sealife.dat and creates a SAS data set named MARINE. Then PROC SORT rearranges the observations by family in ascending order, and by length in descending order. The NODUPKEY option of PROC SORT eliminates any duplicates, while the OUT= option writes the sorted data into a new data set named SEASORT. The output from PROC PRINT looks like this:
Whales and Sharks Obs 1 2 3 4 5 6 7 8 9 10 Name humpback whale basking mako dwarf blue sperm gray killer beluga Family Length 50.0 40.0 30.0 12.0 0.5 100.0 60.0 50.0 30.0 15.0 1

shark shark shark shark whale whale whale whale whale

Notice that the humpback with a missing value for Family became observation one. That is because missing values are always low for both numeric and character variables. Also, the NODUPKEY option eliminated a duplicate observation for the whale shark. The log contains these notes showing that the sorted data set has one fewer observation than the original data set.
NOTE: The data set WORK.MARINE has 11 observations and 3 variables. NOTE: 1 observations with duplicate key values were deleted. NOTE: The data set WORK.SEASORT has 10 observations and 3 variables.

106

The Little SAS Book

4.4

Printing Your Data with PROC PRINT
The PRINT procedure is perhaps the most widely used SAS procedure. You have seen this procedure used many times in this book to print the contents of a SAS data set. In its simplest form, PROC PRINT prints all variables for all observations in the SAS data set. SAS decides the best way to format the output, so you don’t have to worry about things like how many variables will fit on a page. But there are a few more features of PROC PRINT that you might want to use. The PRINT procedure requires just one statement:
PROC PRINT;

By default, SAS uses the SAS data set created most recently. If you do not want to print the most recent data set, then use the DATA= option to specify the data set. We recommend always using the DATA= option for clarity in your programs as it is not always easy to quickly determine which data set was created last.
PROC PRINT DATA = data-set;

Also, SAS prints the observation numbers along with the variables’ values. If you don’t want observation numbers, use the NOOBS option in the PROC PRINT statement. If you define variable labels with a LABEL statement, and you want to print the labels instead of the variable names, then add the LABEL option as well. The following statement shows all of these options together:
PROC PRINT DATA = data-set NOOBS LABEL;

The following are optional statements that sometimes come in handy:
BY variable-list;

The BY statement starts a new section in the output for each new value of the BY variables and prints the values of the BY variables at the top of each section. The data must be presorted by the BY variables. When you use the ID statement, the observation numbers are not printed. Instead, the variables in the ID variable list appear on the left-hand side of the page. The SUM statement prints sums for the variables in the list. The VAR statement specifies which variables to print and the order. Without a VAR statement, all variables in the SAS data set are printed in the order that they occur in the data set.

ID variable-list;

SUM variable-list; VAR variable-list;

Example Students from two fourth-grade classes are selling candy to earn money for a special field trip. The class earning more money gets a free box of candy. The following are the data for the results of the candy sale. The students’ names are followed by their classroom number, the date they turned in their money, the type of candy: mint patties or chocolate dinosaurs, and the number of boxes sold:

The class earns $1.25 for each box of candy sold. The teachers want a report giving the money earned for each classroom, the money earned by each student, the type of candy sold, and the date the students returned their money. The following program reads the data, computes money earned (Profit), and sorts the data by classroom using PROC SORT. Then, the PROC PRINT step uses a BY statement to print the data by Class and a SUM statement to give the totals for Profit. The VAR statement lists the variables to be printed:
DATA sales; INFILE 'c:\MyRawData\Candy.dat'; INPUT Name $ 1-11 Class @15 DateReturned MMDDYY10. CandyType $ Quantity; Profit = Quantity * 1.25; PROC SORT DATA = sales; BY Class; PROC PRINT DATA = sales; BY Class; SUM Profit; VAR Name DateReturned CandyType Profit; TITLE 'Candy Sales for Field Trip by Class'; RUN;

Changing the Appearance of Printed Values with Formats
Obs 1 2 3 Date 01/01/60 01/03/60 02/01/60 Sales 1,002 2,012 4,336
When SAS prints your data, it decides which format is best—how many decimal places to print, how much space to allow for each value, and so on. This is very convenient and makes your job much easier, but SAS doesn’t always do what you want. Fortunately you’re not stuck with the format SAS thinks is best. You can change the appearance of printed values using SAS formats.

0 1002 2 2012 31 4336

SAS has many formats for character, numeric, and date values. For example, you can use the COMMAw.d format to print numbers with embedded commas, the $w. format to control the number of characters printed, and the MMDDYYw. format to print SAS date values (the number of days since January 1, 1960) in a readable form like 12/03/2003. You can even print your data 1 in more obscure formats like hexadecimal, zoned decimal, and packed decimal, if you like. The general forms of a SAS format are Character
$formatw.

Numeric formatw.d Date formatw. where the $ indicates character formats, format is the name of the format, w is the total width including any decimal point, and d is the number of decimal places. The period in the format is very important because it distinguishes a format from a variable name, which cannot, by default, contain any special characters except the underscore.

FORMAT statement You can associate formats with variables in a FORMAT statement.
The FORMAT statement starts with the keyword FORMAT, followed by the variable name (or names if more than one variable is to be associated with the same format), followed by the format. For example, the following FORMAT statement associates the DOLLAR8.2 format with the variables Profit and Loss and associates the MMDDYY8. format with the variable SaleDate:
FORMAT Profit Loss DOLLAR8.2 SaleDate MMDDYY8.;

FORMAT statements can go in either DATA steps or PROC steps. If the FORMAT statement is in a DATA step, then the format association is permanent and is stored with the SAS data set. If the FORMAT statement is in a PROC step, then it is temporary—affecting only the results from that procedure.

PUT statement You can also use formats in PUT statements when writing raw data files or reports. Place a format after each variable name, as in the following example:
PUT Profit DOLLAR8.2 Loss DOLLAR8.2 SaleDate MMDDYY8.;

Example In section 4.4, results from the fourth-grade candy sale were printed using the
PRINT procedure. The names of the students were printed along with the date they turned in their money, the type of candy sold, and the profit. You may have noticed that the dates printed

1

You can also create your own formats using the FORMAT procedure covered in section 4.7.

Chapter 4: Sorting, Printing, and Summarizing Your Data

109

were numbers like 14690 and 14694. Using the FORMAT statement in the PRINT procedure, we can print the dates in a readable form. At the same time, we can print the variable Profit using the DOLLAR6.2 format so dollar signs appear before the numbers. Here are the data, where the students’ names are followed by their classroom, the date they turned in their money, the type of candy sold: mint patties or chocolate dinosaurs, and the number of boxes sold:
Adriana Nathan Matthew Claire Caitlin Ian Chris Anthony Stephen Erika 21 14 14 14 21 21 14 21 14 21 3/21/2000 3/21/2000 3/21/2000 3/22/2000 3/24/2000 3/24/2000 3/25/2000 3/25/2000 3/25/2000 3/25/2000 MP CD CD CD CD MP CD MP CD MP 7 19 14 11 9 18 6 13 10 17

Selected Standard Formats
Here are definitions of commonly used formats along with the width range and default width. Definition Converts character data to hexidecimal (specify w twice the length of the variable) Writes standard character data—does not trim leading blanks (same as $CHARw.)
2 1

Writes SAS date values in form ddmmmyy or ddmmmyyyy Writes SAS datetime values in form ddmmmyy:hh:mm:ss.ss Writes day of month from a SAS date value Writes a SAS date value in form: dd.mm.yy Writes a Julian date from a SAS date value in form yyddd or yyyyddd Writes SAS date values in form mmddyy or mmddyyyy Writes SAS time values in form hh:mm:ss.ss Writes SAS date values in form day-of-week, month-name dd, yy or yyyy Writes SAS date values in form month-name dd, yyyy SAS chooses best format—this is the default format for writing numeric data Writes numbers with commas separating every three digits Writes numbers with a leading $ and commas separating every three digits Writes numbers in scientific notation Writes numbers in packed decimal—w specifies the number of bytes Writes standard numeric data

5-9 7-40 2-32 2-10 5-7 2-10 2-20 3-37 3-32

1-32 2-32 2-32 7-32 1-16 1-32

12 6 6 12 1 none

1 2

Check your SAS Help and Documentation for a complete list of formats. SAS date values are the number of days since January 1, 1960. SAS time values are the number of seconds past midnight, and datetime values are the number of seconds since midnight January 1, 1960.

The EBCDIC character set is used on most IBM mainframe computers while the ASCII character set is used on most other computers. So, depending on the computer you are using, you will get one or the other. These values cannot be printed.

4

112

The Little SAS Book

4.7 m 2 f 1 m 3

Creating Your Own Formats Using PROC FORMAT
At some time you will probably want to create your own custom formats—especially if you use a lot of coded data. Imagine that you have just completed a survey for your company and to save disk space and time, all the responses to the survey questions are coded. For example, the age categories teen, adult, and senior are coded as numbers 1, 2, and 3. This is convenient for data entry and analysis but bothersome when it comes time to interpret the results. You could present your results along with a code book, and your company directors could look up the codes as they read the results. But this will probably not get you that promotion you’ve been looking for. A better solution is to create user-defined formats using PROC FORMAT and print the formatted values instead of the coded values.

Obs 1 2 3

Sex Male Female Male

AgeGroup Adult Teen Senior

The FORMAT procedure creates formats that will later be associated with variables in a FORMAT statement. The procedure starts with the statement PROC FORMAT and continues with one or more VALUE statements (other optional statements are available):
PROC FORMAT; VALUE name range-1 = 'formatted-text-1' range-2 = 'formatted-text-2' . . . range-n = 'formatted-text-n';

The name in the VALUE statement is the name of the format you are creating. If the format is for character data, the name must start with a $. The name can’t be longer than 32 characters (including the $ for character data), it must not start or end with a number, and cannot contain any special characters except the underscore. In addition, the name can’t be the name of an existing format. Each range is the value of a variable that is assigned to the text given in quotation marks on the right side of the equal sign. The text can be up to 32,767 characters long, but some procedures print only the first 8 or 16 characters. The following are examples of valid range specifications:
'A' 1, 3, 5, 7, 9 500000 - HIGH 13 -< 20 0 1000000 THEN CALL SYMPUT(”bestseller”, BookTitle);

This statement tells SAS to create a macro variable named &BESTSELLER which is equal to the value of the variable BookTitle when TotalSales exceed 1,000,000.

Caution You cannot create a macro variable with CALL SYMPUT and use it in the same DATA step because SAS does not assign a value to the macro variable until the DATA step executes. DATA steps execute when SAS encounters a step boundary such as a subsequent DATA, PROC, or RUN statement.

In this example, the grower wants a program that will find the customer with the single largest order, and print all the orders for that customer.
* Read the raw data; DATA flowersales; INFILE 'c:\MySASLib\TropicalSales.dat'; INPUT CustomerID $4. @6 SaleDate MMDDYY10. @17 Variety $9. Quantity; PROC SORT DATA = flowersales; BY DESCENDING Quantity; * Find biggest order and pass the customer id to a macro variable; DATA _NULL_; SET flowersales; IF _N_ = 1 THEN CALL SYMPUT(”selectedcustomer”,CustomerID); ELSE STOP; PROC PRINT DATA = flowersales; WHERE CustomerID = ”&selectedcustomer”; FORMAT SaleDate WORDDATE18.; TITLE ”Customer &selectedcustomer Had the Single Largest Order”; RUN;

This program has a lot of steps, but each step is fairly simple. The first DATA step reads the data from the raw data file. Then PROC SORT sorts the data by descending Quantity. That way, the largest single order will be the first observation in the newly sorted data set. The second DATA step then uses CALL SYMPUT to assign the value of the variable CustomerID to the macro variable &SELECTEDCUSTOMER when _N_ equals 1 (the first iteration of the DATA step). Since that is all we need from this DATA step, we can use the STOP statement to tell SAS to end this DATA step. The STOP statement is not necessary, but it is efficient because it prevents SAS from reading the remaining observations for no reason. When SAS reaches the PROC PRINT statement, SAS knows that the DATA step has ended so SAS executes the DATA step. At this point the macro variable &SELECTEDCUSTOMER has the value 356W (the customer ID with the largest single order) and can be used in the PROC PRINT. The output looks like this:
Customer 356W Had the Single Largest Order Customer ID 356W 356W 356W 1

Obs 1 2 5

SaleDate February 8, 2003 February 12, 2003 February 8, 2003

Variety Anthurium Ginger Heliconia

Quantity 300 240 60

For more information on CALL routines, see the SAS Help and Documentation.

212

The Little SAS Book

7.7

Debugging Macro Errors
Many people find that writing macros is not that hard. Debugging them, however, is another matter. This section covers techniques to ease the debugging process.

Avoiding macro errors As much as possible, develop your program in standard SAS code first. Then, when it is bug-free, add the macro logic one feature at a time. Add your %MACRO and %MEND statements. When that’s working, add your macro variables, one at a time, and so on, until your macro is complete and bug-free. Quoting problems The macro processor doesn’t resolve macros inside single quotation marks. To get around this, use double quotation marks whenever you refer to a macro or macro variable and you want SAS to resolve it. For example, below are two TITLE statements containing a macro variable named &MONTH. If the value of &MONTH is January, then SAS will substitute January in the title with the double quotation marks, but not the title with single quotation marks. Original statement
TITLE ’Report for &month’; TITLE ”Report for &month”;

Statement after resolution
TITLE ’Report for &month’; TITLE ”Report for January”;

System options for debugging macros These five system options affect the kinds of messages SAS writes in your log. The default settings appear in bold.
MERROR | NOMERROR SERROR | NOSERROR MLOGIC | NOMLOGIC MPRINT | NOMPRINT SYMBOLGEN | NOSYMBOLGEN when this option is on, SAS will issue a warning if you invoke a macro that SAS cannot find. when this option is on, SAS will issue a warning if you use a macro variable that SAS cannot find. when this option is on, SAS prints in your log details about the execution of macros. when this option is on, SAS prints in your log the standard SAS code generated by macros. when this option is on, SAS prints in your log the values of macro variables.

While you want the MERROR and SERROR options to be on at all times, you will probably want to turn on MLOGIC, MPRINT, and SYMBOLGEN one at a time and only while you are debugging since they tend to make your log hard to read. To turn them on (or off), use the OPTIONS statement, for example:
OPTIONS MPRINT NOSYMBOLGEN NOMLOGIC;

Chapter 7: Writing Flexible Code with the SAS Macro Facility

213

MERROR message If SAS has trouble finding a macro, and the MERROR option is on, then SAS will print this message:
WARNING: Apparent invocation of macro SAMPL not resolved.

Check for a misspelled macro name.

SERROR message If SAS has trouble resolving a macro variable in open code, and the
SERROR option is on, then SAS will print this message:
WARNING: Apparent symbolic reference FLOWER not resolved.

Check for a misspelled macro variable name. If the name is spelled right, then the scope may be wrong. Check to see if you are using a local variable outside of its macro. See section 7.1 for definitions of local and global macro variables.

SYMBOLGEN messages When the SYMBOLGEN option is on, SAS prints messages in your log showing the value of each macro variable after resolution. If you run %SAMPLE with the SYMBOLGEN option, your log will look like this:
30 OPTIONS SYMBOLGEN; 31 %sample(flowertype=Anthurium) SYMBOLGEN: Macro variable FLOWERTYPE resolves to Anthurium

8

‘‘

331 3% of the mice used in / the experiment were cured by the test drug; 331 3% of the test / population were unaffected by the drug and remained in a moribund condition; the third mouse got away.

’’

ERWIN NETER

From “How to Write a Scientific Paper” by Robert A. Day, ASM News, vol. 41, no. 7, pp 486-494, July 1975. Reprinted by permission of publisher and author. Also appears in How to Write and Publish a Scientific Paper 4th edition by Robert A. Day, copyright 1994 by Oryx Press.

Examining the Distribution of Data with PROC UNIVARIATE
When you are doing statistical analysis, you usually have a goal in mind, a question you are trying to answer, hypotheses you want to test. But before you jump into statistical tests, it is a good idea to pause and do a little exploration. A good procedure to use at this point is PROC UNIVARIATE. PROC UNIVARIATE, which is part of Base SAS software, produces statistics describing the distribution of a single variable. These statistics include the mean, median, mode, standard deviation, skewness, and kurtosis. Using PROC UNIVARIATE is fairly simple. After the PROC statement, you specify one or more numeric variables in a VAR statement:
PROC UNIVARIATE; VAR variable-list;

Without a VAR statement, SAS will calculate statistics for all numeric variables in your data set. You can specify other options in the PROC statement, if you wish, such as PLOT or NORMAL:
PROC UNIVARIATE PLOT NORMAL;

The NORMAL option produces tests of normality while the PLOT option produces three plots of your data (stem-and-leaf plot, box plot, and normal probability plot). You can use a BY statement to obtain separate analyses for BY groups. (Just remember to use PROC SORT first if your data are not already sorted by your BY variables.)

Because the model is significant (significance probability = .0053), we conclude that not all the teams are the same height. The SCHEFFE option in the MEANS statement compares the heights between the teams. Letters are used to group means, and means with the same letters are not significantly different from each other (at the 0.05 level). The following results show that your friend’s daughter is partially correct—one team (PINK) is taller than her team (RED) but not all the teams are taller.
Girls' Heights on Basketball Teams The ANOVA Procedure Scheffe's Test for Height NOTE: This test controls the type I experimentwise error rate. Alpha 0.05 Error Degrees of Freedom 55 Error Mean Square 13.78182 Critical Value of F 2.53969 Minimum Significant Difference 4.8306 Means with the same letter are not significantly different. Scheffe Grouping A A A A A Mean 54.833 50.500 50.333 49.833 49.500 N 12 12 12 12 12 Team pink gold gray blue red 3

B B B B B B B

232

The Little SAS Book

8.9 Graphical Interfaces for Statistical Analysis
Statistical results can be obtained using traditional SAS programming statements, but there are also several Graphical User Interfaces which may be available to you for producing results. We get you started with some of the interfaces in this section, but for more details on any of them, please see the SAS Help and Documentation.

SAS Enterprise Guide If you are using the Windows operating environment, then you may have access to SAS Enterprise Guide. Starting with SAS 9, SAS Enterprise Guide comes with Base 1 SAS software , but it is installed separately and has a separate interface outside of the SAS windowing environment. Start SAS Enterprise Guide from your Windows Start Menu.
In SAS Enterprise Guide, you can enter data, or read data from a variety of sources. You can perform data manipulation, generate statistical analyses, and make graphs all using pull-down menus and windows. When you request statistics, SAS Enterprise Guide opens a window which steps you through setting up your analysis. This figure shows the window that appears when you request a linear regression.

SAS Enterprise Guide organizes information into projects containing data, results, code, and the SAS log. Code generated by SAS Enterprise Guide can be edited and resubmitted, or saved for later use. This figure shows a project consisting of a data set, a line chart and a linear regression.

SAS Enterprise Guide requires Base SAS software and if you want to do advanced statistics and graphics, then you will also need SAS/STAT software and SAS/GRAPH software.

1

Chapter 8: Using Basic Statistical Procedures

233

Analyst If you are using either the Windows or UNIX operating environments, then you can use 2 Analyst to help you with your statistical analyses . Start the Analyst application from the Solutions pull-down menu in the SAS windowing environment. In the Analyst application, you can enter data into tables, or you can read data from existing SAS data sets. If you have SAS/ACCESS for PC File Formats software, then you can also read a number of PC file types. You can produce results by choosing from a pull-down list of statistics, graphs, and reports. The code that Analyst generates can be copied into the Program Editor where it can be saved or edited and submitted in SAS. Like SAS Enterprise Guide, when you request statistics in Analyst, a window appears where you can specify your analysis. This figure shows the window for a simple regression.

Like SAS Enterprise Guide, Analyst organizes information into projects which consist of data, results, and the code to produce the results. This figure shows an Analyst project including a data set, a 2-D scatter plot and a simple linear regression. .

SAS/LAB and SAS/INSIGHT There are two other SAS products, SAS/LAB software and SAS/INSIGHT software, which provide interfaces to the statistical and graphical procedures. SAS/LAB software is for guided statistical analysis and is good for people who need to analyze data but do not have a background in statistics. SAS/INSIGHT software is a tool for visual analysis of data where statistical results are displayed graphically whenever possible and interactive manipulation of data is possible.

9.1 Methods for Exporting Your Data
In our ever increasingly complex world, people often need to transfer data from one application to another or from one type of computer to another. Fortunately, SAS gives you many options for doing this.

Exporting data to other applications The types of files that you can create and the methods available for creating those files depends on what operating environment you are using and whether you have SAS/ACCESS software. There are three general methods for exporting data to other applications: create delimited or text files that the other software can read; create files in formats like HTML, RTF, or XML that the other software can read; or write the data in the other software’s native format.
· No matter what your environment, you can always create delimited files and most software has the ability to read these types of data files. The DATA step, discussed in section 9.5, gives you the most control over the format of your files, but requires the most steps. The Export Wizard, discussed in section 9.2, and the EXPORT procedure, discussed in section 9.3, are easy to use, but you have less control over the result and not everyone has access to these tools. The Output Delivery System (ODS), discussed in section 9.6, can create comma-separated values (CSV) files from any procedure output and a simple PROC PRINT will produce a reasonable file for importing into other programs. Using ODS, discussed in section 9.6, you can create HTML, RTF, and XML files from any procedure output. Many applications can read data in these types of files. Although we do not cover creating RTF and XML files for this purpose, the general method is the same as creating HTML files. If you have SAS/ACCESS for PC File Formats software, then you can create several different file types that are common for PC applications. Both the Export Wizard, discussed in section 9.2, and the EXPORT procedure, discussed in section 9.4, can produce PC files. By creating the files in the native format of the application, you avoid the extra step of importing the file into the other application. There are also other SAS/ACCESS products for many popular database management systems including ORACLE, DB2, INGRES and SYBASE. If you don’t have SAS/ACCESS for PC File Formats software, and you are using Windows, you can use Dynamic Data Exchange (DDE) or Open Database Connectivity (ODBC) to move data from SAS to PC applications without creating any intermediate files. For more information on using other SAS/ACCESS products, DDE, or ODBC to export SAS data, see the SAS Help and Documentation.

·

·

Exporting SAS data sets to other operating environments Since not all computers store data using the same representation, sometimes it is necessary to convert data from one type to another if you are moving your data from one operating environment to another. The following are some of the available methods: Cross Environment Data Access (CEDA), the XPORT engine or the CPORT procedure, the XML engine, and SAS/CONNECT software.
· CEDA, covered in section 9.7, is by far the simplest method for moving SAS data sets to other operating environments. However CEDA cannot be used for SAS Version 6 data sets, nor for data stored in OS/390 or z/OS bound libraries.

Chapter 9: Exporting Your Data ·

237

Both the XPORT engine and the CPORT procedure create transport files which can be moved to other operating environments and then converted back into SAS data sets. Creating transport files can cause loss in numerical precision, but for SAS Version 6 data sets, or data stored in OS/390 bound libraries, CEDA is not an option so you may need to use one of these methods. See the SAS Help and Documentation for more information about the XPORT engine and the CPORT procedure. If you are using SAS 9 or later, then you can use the XML engine on the LIBNAME statement to create XML documents from your SAS data sets. The XML documents can then be transferred to another computer and turned back into SAS data sets using the XML engine for input. See the SAS Help and Documentation for more information. SAS/CONNECT software (not part of Base SAS software), along with many other capabilities, allows you to transfer SAS data sets to other operating environments without creating intermediate transport files. SAS/CONNECT software can move SAS datasets from an earlier version of SAS to a later version and vice versa. See the SAS Help and Documentation for more information about SAS/CONNECT software.

·

·

238

The Little SAS Book

9.2 Writing Files Using the Export Wizard
The Export Wizard provides an easy way to produce files that can be imported into other 2 software . The Export Wizard is a Graphical User Interface (GUI) to the EXPORT procedure (discussed in sections 9.3 and 9.4) and if you only need to export data once in a while, then it’s easier than trying to remember the PROC EXPORT statements. Start the Export Wizard by selecting Export Data… from the File menu. In the first Export Wizard window, choose the library and member name for the SAS data set that you want to export. If you are exporting a temporary SAS data set, then the library is WORK. If you are exporting a permanent SAS data set, then make sure your library is defined before you start the Export Wizard. Then choose the library from the drop down list. The member name is the name of the SAS data set.
1

In the next window, choose the type of file you would like to create. Either choose from the pull-down list of standard data sources, or check the box next to User-defined formats. The User-defined formats takes you to the External File Interface (EFI) facility which enables you to assign formats to your variables, as well as choose either a delimited file structure, or a file that is arranged into columns. If you select one of the standard data sources, then any formats that you have assigned to variables in the SAS data set will be applied when creating the data file. The Export Wizard always writes the variable names as the first row in the file it creates. If you choose either the Microsoft Excel or Microsoft Access file types, then you will be

1

The Export Wizard is available for the Windows, UNIX, and OpenVMS operating environments.

2

The Export Wizard can write data files in many different formats including space-, comma-, and tab-delimited files and files formatted into columns. In addition, if you have SAS/ACCESS for PC File Formats software, and you are running the Windows operating environment, then you can also write data files in the native format of other software products such as Microsoft Access, dBase, Lotus, and Microsoft Excel. UNIX users with SAS/ACCESS for PC File Formats software can create dBase files, and starting with SAS 9.1, UNIX users can also write Microsoft Access and Microsoft Excel files.

Chapter 9: Exporting Your Data

239

presented with additional windows where you can make choices about table names for Microsoft Excel, and database information for Microsoft Access. In the next window you choose the location for the exported data. If you are exporting delimited data, then you may also choose the delimiter by clicking on the Options button in this window. If any of your data contain the delimiter that you choose, then that value will be enclosed in double quotation marks.

In the final window you have the option to save the PROC EXPORT statements that are generated through the Export Wizard.

240

The Little SAS Book

9.3 Writing Delimited Files with the EXPORT Procedure
The EXPORT procedure, like the Export Wizard, is available for Windows, UNIX, and OpenVMS operating environments. Since the Export Wizard is an interface to the EXPORT procedure, you can create the same types of files with the EXPORT procedure that you can with the Export Wizard. The advantage of using the procedure over the wizard is that you can incorporate the procedure code into existing SAS programs, and you don’t need to step through all the Export Wizard windows every time you want to create a file.

The EXPORT procedure The general form of PROC EXPORT is
PROC EXPORT DATA = data-set OUTFILE = 'filename';

where data-set is the SAS data set you want to export, and filename is the name you make up for the output data file. The following statement tells SAS to read a temporary SAS data set named HOTELS and write a comma-delimited file named Hotels.csv in a directory named MyRawData on the C drive (Windows):
PROC EXPORT DATA = hotels OUTFILE = 'c:\MyRawData\Hotels.csv';

SAS uses the last part of the filename, called the file extension, to decide what type of file to create. You can also specify the file type by adding the DBMS= option to the PROC EXPORT statement. The following table shows the filename extensions and DBMS identifiers currently available with Base SAS software. If you specify the DBMS option, then it takes precedence over the file extension. Type of file Extension DBMS Identifier Comma-delimited .csv CSV Tab-delimited .txt TAB Space-delimited DLM Notice that for space-delimited files, there is no standard extension so you must use the DBMS= option. The following statement, containing the DBMS= option, tells SAS to create a spacedelimited file named Hotels.spc. The REPLACE option tells SAS to replace any file with the same name.
PROC EXPORT DATA = hotels OUTFILE = 'c:\MyRawData\Hotels.spc' DBMS = DLM REPLACE;

If you want to create a file with a delimiter other than a comma, tab, or space, then you can add the DELIMITER statement. If you use the DELIMITER statement, then it does not matter what file extension you use, or what DBMS identifier you specify, the file will have the delimiter that you specify in the DELIMITER statement. For example, the following would produce a file, Hotels.txt, that has the ampersand (&) as the delimiter:
PROC EXPORT DATA = hotels OUTFILE = 'c:\MyRawData\Hotels.txt' DBMS = DLM REPLACE; DELIMITER='&';

Example A travel company maintains a SAS data set containing information about golf courses. For each golf course the file includes its name, number of holes, par, yardage, and greens fees. Here is a subset of the data:

The following program uses INFILE and INPUT statements to read the data and put them in a permanent SAS data set named GOLF in the MySASLib directory on the C drive (Windows). This example uses a LIBNAME statement to tell SAS where to store the permanent SAS data set, but you could use direct referencing instead:
LIBNAME travel ’c:\MySASLib’; DATA travel.golf; INFILE ’c:\MyRawData\Golf.dat’; INPUT CourseName $18. NumberOfHoles Par Yardage GreenFees; RUN;

Now, suppose you want to write a letter to a potential customer and insert the golf data. The following program writes a plain text, tab-delimited file that you can read with any text editor or word processor:
LIBNAME sports ’c:\MySASLib’; * Create Tab-delimited file; PROC EXPORT DATA = sports.golf OUTFILE = 'c:\MyRawData\Golf.txt' REPLACE; RUN;

Because the name of the output file ends with .txt and there is no DELIMITER statement, SAS will write a tab-delimited file. If you run this program, your log will contain the following note about the output file:
NOTE: 7 records were written to the file 'c:\MyRawData\Golf.txt'.

Any format that you have assigned to variables in the SAS data set will be applied by PROC EXPORT. If you want to change a format, use a FORMAT statement (discussed in section 4.5) in a DATA step before running PROC EXPORT.

242

The Little SAS Book

9.4 Writing PC Files with the EXPORT Procedure
If you are using the Windows or UNIX operating environments, and you have SAS/ACCESS for PC File Formats software, then you can use the EXPORT procedure to create PC file types in addition to delimited files. If you are running the Windows operating environment, the 1 EXPORT procedure can create Microsoft Access, Microsoft Excel, dBase, and Lotus files . If you are running the UNIX operating environment, then you can create dBase files, and starting with SAS 9.1, UNIX users can also create Microsoft Access and Microsoft Excel files.

where data-set is the SAS data set you want to export, and filename is the name you make up for the output data file. The following statement tells SAS to read a temporary SAS data set named HOTELS and write a Microsoft Excel file named Hotels.xls in a directory named MyRawData on the C drive (Windows):
PROC EXPORT DATA = hotels OUTFILE = 'c:\MyRawData\Hotels.xls';

SAS uses the last part of the filename, called the file extension, to decide what type of file to create. You can also specify the file type by adding the DBMS= option. The following table shows the filename extensions and DBMS identifiers: Type of file Microsoft Excel Extension .xls DBMS Identifier 2 EXCEL EXCEL5 EXCEL4 WK4 WK3 WK1 DBF

By default, the name of the Microsoft Excel sheet will be the same as the name of the SAS data set. If you want the sheet to have a different name, then specify it in the SHEET= statement (this statement is not valid for Microsoft Excel 4 or Microsoft Excel 5 files). Special characters in sheet names will be converted to underscores, and the $ is not allowed at the end of the sheet name. The following statement creates a sheet named Golf_Hotels:
SHEET = 'Golf Hotels';
If you are running Microsoft Windows 64-Bit Edition, then you cannot export Microsoft Access or Microsoft Excel 97, Microsoft Excel 2000 or Microsoft Excel 2002 files.
2 1

Microsoft Access files If you want to create a Microsoft Access database file, then instead of using the OUTFILE= option, you use the OUTTABLE= option and you add the DATABASE= statement. The general form of PROC EXPORT for Microsoft Access files is:
PROC EXPORT DATA = data-set OUTTABLE = 'filename' DBMS=identifier; DATABASE = 'filename';

The DATABASE statement specifies which Microsoft Access database you wish to modify or create and the OUTTABLE option specifies the name of the table in that database. If you need to specify user IDs, passwords, or workgroups for your database, there are optional statements that allow you to do this. See the SAS Help and Documentation for more information. You must specify the DBMS option to create a Microsoft Access table. The following table shows the DBMS identifiers for Microsoft Access files. All Microsoft Access files have the .mdb extension. Type of file Microsoft Access Extension .mdb DBMS Identifier 3 ACCESS ACCESS97

The following program uses INFILE and INPUT statements to read the data and put them in a permanent SAS data set named GOLF in the MySASLib directory on the C drive (Windows).
LIBNAME travel ’c:\MySASLib’; DATA travel.golf; INFILE ’c:\MyRawData\Golf.dat’; INPUT CourseName $18. NumberOfHoles Par Yardage GreenFees; RUN;

9.5 Writing Raw Data Files with the DATA Step
When you need total control over the contents and format of raw data files that you are creating, then the DATA step is the way to go. Using FILE and PUT statements in the DATA step, you can write almost any form of raw data file. This method has, to some extent, been replaced by the easier-to-use 1 PROC EXPORT and Export Wizard, but while PROC EXPORT gives you only a few options in formatting your files, the DATA step gives you flexibility to create raw data files just the way you want. You can write raw data the same way that you read raw data, with just a few changes. Instead of naming the external file in an INFILE statement, you name it in a FILE statement. Instead of reading variables with an INPUT statement, you write them with a PUT statement. To say it another way, you use INFILE and INPUT statements to get raw data into SAS, and FILE and PUT

raw data file

INFILE INPUT

SAS data set

FILE PUT

raw data file

statements to get raw data out. PUT statements can be in list, column, or formatted style, just like INPUT statements, but since SAS already knows whether a variable is numeric or character, you don’t have to put a $ after character variables. If you use list format, SAS will automatically put one space between each variable, creating a space-delimited file. To write files with other delimiters, use a list-style PUT statement 2 and the DSD and DLM= options in your FILE statement.
FILE ’file-specification’ DSD DLM = ’delimiter’;

If you use column or formatted styles of PUT statements, SAS will put the variables wherever you specify. You can control spacing with the same pointer controls that INPUT statements use: @n to move to column n, +n to move n columns, / to skip to the next line, #n to skip to line n, and the trailing @ to hold the current line. In addition to printing variables, you can insert a text string by simply enclosing it in quotation marks.

Example To show how much more control you have using the DATA step as opposed to PROC EXPORT, this example uses the same data containing information about golf courses. For each course the file includes the course name, number of holes, par, yardage, and greens fees. Here is a subset of the data:
Kapalua Plantation Pukalani Sandlewood Silversword Waiehu Municipal Grand Waikapa
1 2

18 18 18 18 18 18

73 72 72 71 72 72

7263 125.00 6945 55.00 6469 35.00 . 57.00 6330 25.00 6122 200.00

The EXPORT procedure is available on UNIX, OpenVMS, and Windows. See section 2.17 for a discussion of the DSD and DLM= options.

Chapter 9: Exporting Your Data

245

The following program uses INFILE and INPUT statements to read the data from a file called Golf.dat and put it in a permanent SAS data set named GOLF in the MySASLib directory on the C drive (Windows).
LIBNAME travel ’c:\MySASLib’; DATA travel.golf; INFILE ’c:\MyRawData\Golf.dat’; INPUT CourseName $18. NumberOfHoles Par Yardage GreenFees; RUN;

Suppose you want to put the data in a raw data file, but with only three variables, in a new order, and with dollar signs added to the variable GreenFees. The following program reads the SAS data set and writes a raw data file using FILE and PUT statements:
LIBNAME activity ’c:\MySASLib’; DATA _NULL_; SET activity.golf; FILE ’c:\MyRawData\Newfile.dat’; PUT CourseName ’Golf Course’ @32 GreenFees DOLLAR7.2 @40 ’Par ’ Par; RUN;

The word _NULL_ appears in the DATA statement instead of a SAS data set name. You could put a data set name there, but _NULL_ is a special keyword that tells SAS not to bother making a new SAS data set. By not writing a new SAS data set, you save computer resources. The SET statement simply tells SAS to read the permanent SAS data set GOLF. The FILE statement tells SAS the name of the output file you want to create. Then, the PUT statement tells SAS what to write and where. The PUT statement contains two quoted strings, “Golf Course” and “Par” which SAS inserts in the raw data file. The PUT statement also tells SAS exactly where to place the data values for each variable using the @ column pointer, and to use the DOLLAR7.2 format to write the values for the GreenFees variable. Using the PUT statement you have complete control over the content of your raw data files. If you run this program, your log will contain the following note telling how many records were written to the output file:
NOTE: 6 records were written to the file ’c:\MyRawData\Newfile.dat’.

9.6 Writing Delimited and HTML Files Using ODS
The Output Delivery System (ODS) is a powerful tool for creating all sorts of output formats. Among the various output formats that ODS can create are two, comma-separated values (CSV) and HyperText Markup Language (HTML), that are useful for transferring data from 1 SAS to other applications . Many applications can read data that are in either CSV or HTML format, and the great thing is that you can use this method in any operating environment and it’s included in Base SAS software. Since all procedure output goes to ODS, you can use ODS to export data by choosing the appropriate output destination for your application, and using PROC PRINT to get a listing of your data. By default, SAS will print a period for any missing numeric data. If you would rather have SAS print nothing for missing numeric data, then you can use the MISSING=' ' system option. Also by default, PROC PRINT includes observation numbers. If you don’t want observation numbers in your output file, then use the NOOBS option on the PROC PRINT statement.

CSV files Starting with SAS 9, you can use ODS to create CSV files. CSV files have commas separating all the data values and the values are enclosed in double quotation marks. The double quotation marks allow values to contain commas as part of the value. To create a CSV file containing your data, use the following ODS statements:
ODS CSV FILE = 'filename.csv'; Your PROC PRINT statements go here RUN; ODS CSV CLOSE;

Where filename.csv is the name of the CSV file that you are creating, and you insert the appropriate PROC PRINT statements for your data. The CSV output destination does not include titles or footnotes; if you want titles and footnotes to appear in the CSV file, then use the CSVALL output destination instead of CSV.

HTML files Use the following statements to produce an HTML file of your data (and any titles or footnotes) with the default style. You can choose a different style by adding the STYLE= option to the ODS HTML statement. Or, if you do not want any styling, then use the CHTML (compact HTML¾available beginning with SAS 9) output destination instead of HTML.
ODS HTML FILE = 'filename.html'; Your PROC PRINT statements go here RUN; ODS HTML CLOSE;

Example This example uses the permanent SAS data set, GOLF (created in section 9.5), which has information about golf courses in Hawaii. The following program uses ODS to create a CSV file, golfinfo.csv, from the results of the PRINT procedure:
LIBNAME travel 'c:\MySASLib'; ODS CSV FILE='c:\MyCSVFiles\golfinfo.csv'; PROC PRINT DATA = travel.golf; TITLE 'Golf Course Information'; RUN; ODS CSV CLOSE;
Extensible Markup Language (XML) is another ODS destination that is useful for data transfer. See the SAS Help and Documentation for more information.
1

Chapter 9: Exporting Your Data

247

This is what the CSV file, golfinfo.csv, looks like if you open it in a simple editor such as Microsoft Notepad:
"Obs","CourseName","NumberOfHoles","Par","Yardage","GreenFees" "1","Kapalua Plantation","18","73","7263","125" "2","Pukalani","18","72","6945"," 55" "3","Sandlewood","18","72","6469"," 35" "4","Silversword","18","71"," ."," 57" "5","Waiehu Municipal","18","72","6330"," 25" "6","Grand Waikapa","18","72","6122","200"

If you open the same file, golfinfo.csv, using Microsoft Excel, this is what you see:

The following program creates an HTML file, golfinfo.html, of the GOLF data, this time using the NOOBS option on the PROC PRINT statement to eliminate the Obs column:
LIBNAME travel 'c:\MySASLib'; ODS HTML FILE='c:\MyHTMLFiles\golfinfo.html'; PROC PRINT DATA = travel.golf NOOBS; TITLE 'Golf Course Information'; RUN; ODS HTML CLOSE;

2

This is what the HTML file looks like when you open it Microsoft Excel. You can see that although the data are the same as in the CSV file, the HTML file also includes the title and the default HTML styling.

If you want the HTML file to be automatically recognized as a Microsoft Excel file, then give the file the .xls extension instead of the .html extension.

2

248

The Little SAS Book

9.7 Sharing SAS Data Sets with Other Types of Computers
When you access a SAS data set , SAS looks at the data set to determine if it is compatible with the operating environment that you are using. If the data set is in a representation of a different operating environment, then SAS will automatically use Cross-Environment Data Access (CEDA) to dynamically translate the data into a form that SAS in your operating environment can understand. Two cases where CEDA cannot be used are: SAS data sets in OS/390 or z/OS bound libraries and SAS Version 6 or earlier data sets. For these types of data sets see “If you can’t use CEDA” at the end of this section.
1

Determining data representation CEDA is so transparent that by default you don’t know when it is being used. If you want to be informed as to when CEDA is being used, then use the following OPTIONS statement in your program:
OPTIONS MSGLEVEL=I;

Then a note will appear in your SAS log whenever SAS uses CEDA to access your data. Here is an example of the note:
INFO: Data set TEST.MYUNIX.DATA is in a foreign host format. Cross Environment Data Access will be used, which may require additional CPU resources and reduce performance.

The data representation is also noted in the output when you run the CONTENTS procedure on a SAS data set.

Creating SAS data sets for foreign hosts If you need to use your SAS data sets on a computer with a different operating environment than the one where they were created, then you might want to create the data sets in the representation of the other computer. This way when the other computer accesses the data, it doesn’t have to waste resources translating the data to its own format. You do this by using the OUTREP= option on either the LIBNAME statement, if you want all the data sets in that library to have the specified host representation, or as a data set option if you only want it to apply to one data set. The general form for the LIBNAME statement is:
LIBNAME libref 'path' OUTREP=data-representation;

The general form for the data set option is: data-set-name(OUTREP=data-representation) There are many possible values for data-representation. The data representation is basically the name of the operating environment. For example if you want the data representation for the Microsoft Windows 64-Bit Edition, the value is: WINDOWS_64. If you want the data representation for the Solaris 32-Bit Edition, the value is: SOLARIS_32 (or just SOLARIS for SAS 9 or earlier). See the SAS Help and Documentation for a complete list of possible values.

Example You have data about golf courses in Hawaii stored in a permanent SAS data set named GOLF on your Windows desktop computer. Your friend, who needs to use the golf data, is a LINUX guru and always gives you a hard time for using Windows. You decide to send him
Accessing data sets includes reading the data, and performing simple functions such as sorting, setting, or reading the data set in a procedure. Some functions, such as using the MODIFY statement, are not allowed. If you get an error message when trying to access a data set created on a different host, then convert the data set to your operating environment before continuing.
1

Chapter 9: Exporting Your Data

249

the data in LINUX format so you won’t get any grief for using Windows. The following program uses the SET statement in a DATA step to read the GOLF data from the SPORTS library, then the OUTREP= data set option on the DATA statement tells SAS to write the data in LINUX format creating a SAS data set named GOLFLINUX.
OPTIONS MSGLEVEL=I; LIBNAME sports 'c:\MySASLib; DATA sports.golflinux(OUTREP=LINUX); SET sports.golf; RUN;

The system option MSGLEVEL=I causes the following note to be added to the SAS log informing you that CEDA was used to create the GOLFLINUX data set.
INFO: Data set SPORTS.GOLFLINUX.DATA is in a foreign host format. Cross Environment Data Access will be used, which may require additional CPU resources and reduce performance.

Moving SAS data sets If both computers have access to the same file system, then simply point your LIBNAME statement to the directory where the SAS data set is located. Otherwise you can transfer the SAS data set using FTP (File Transfer Protocol) in binary mode, or use an external media such as a floppy disk, or CD. FAT file systems SAS data sets created beginning with SAS Version 7 by default have the extension .sas7bdat. Some Windows systems which use FAT (File Allocation Table) file systems can only have files with three-character extensions, so for these systems the extension for SAS data sets is .sd7. If you receive a SAS data set with a three letter extension, or if you need to create a SAS data set with a three letter extension, then use the SHORTFILEEXT option on the LIBNAME statement for the data set.
LIBNNAME libref 'path' SHORTFILEEXT;

If you can’t use CEDA If you need to read a SAS Version 6 data set that was created in a different operating environment, or if you are using SAS data sets in bound libraries in the OS/390 or z/OS operating environments, then you will not be able to use CEDA. In these cases, you will either need to create a SAS data set in transport format, create an XML document using the XML engine, or use SAS/CONNECT software to transfer data. You can use either the XPORT engine or PROC CPORT to create transport files. Transport files created using the XPORT engine must be read with the XPORT engine and files created with PROC CPORT must be read with PROC CIMPORT. The drawbacks to using transport files are that: extra steps are needed to create and read the files, they do not support variable names over 8 characters, and you can lose precision in numeric data. Creating XML documents will preserve your long variable names, but you must have SAS 9 or higher to read the XML documents. SAS/CONNECT software does not create an intermediate file, but it is an add-on product and not every one has it. See the SAS Help and Documentation for more information on transport files, the XML engine, and SAS/CONNECT software.

10

‘‘

Problems that go away by themselves come back by themselves.

’’

MARCY E. DAVIS

From The Official Explanations by Paul Dickson. Copyright 1980 by Delacorte Press. Reprinted by permission of the publisher.

10.11 Error: Invalid Option, Error: The Option Is Not Recognized, or Error: Statement Is Not Valid 272 274

10.12 Note: Variable Is Uninitialized or Error: Variable Not Found 10.13 SAS Truncates a Character Variable 276

10.14 SAS Stops in the Middle of a Job 278 10.15 SAS Runs Out of Memory or Disk Space 280

252

The Little SAS Book

10.1 Writing SAS Programs That Work
It’s not always easy to write a program that works the first time you run it. Even experienced SAS programmers will tell you it’s a delightful surprise when their programs run on the first try. The longer and more complicated the program, the more likely it is to have syntax or logic errors. But don’t despair, there are a few guidelines you can follow that can make your programs run correctly sooner and help you discover errors more easily.

Make programs easy to read One simple thing you can do is develop the habit of writing programs in a neat and consistent manner. Programs that are easy to read are easier to debug and will save you time in the long run. The following are suggestions on how to write your programs:
¨ Put only one SAS statement on a line. SAS allows you to put as many statements on a line as you wish, which may save you some space in your program, but the saved space is rarely worth the sacrifice in readability. Use indention to show the different parts of the program. Indent all statements within the DATA and PROC steps. This way you can tell at a glance how many DATA and PROC steps there are in a program and which statement belongs to which step. It’s also helpful to further indent any statements between a DO statement and its END statement. Use comment statements generously to document your programs. This takes some discipline but is important, especially if anyone else is likely to read or use your program. Everyone has a different programming style, and it is often impossible to figure out what someone else’s program is doing and why. Comment statements take the mystery out of the program.

¨

¨

Test each part of the program You can increase your programming efficiency tremendously by making sure each part of your program is working before moving on to write the next part. If you were building a house, you would make sure the foundation was level and square before putting up the walls. You would test the plumbing before finishing the bathroom. You are required to have each stage of the house inspected before moving on to the next. The same should be done for your SAS program. But you don’t have to wait for the inspector to come out; you can do it yourself.
If you are reading data from a file, use PROC PRINT to print the SAS data set at least once to make sure it is correct before moving on. Sometimes, even though there are no errors or even suspicious notes in your SAS log, the SAS data set is not correct. This could happen because SAS did not read the data the way you imagined (after all it does what you say, not what you’re thinking) or because the data had some peculiarities you did not realize. For example, a researcher who received two data files from Taiwan wanted to merge them together by date. She could not figure out why they refused to merge correctly until she printed both data sets and realized one of the files used Taiwanese dates, which are offset by 11 years. It’s a good habit to print all the SAS data sets you create in a program at least once to make sure they are correct. As with reading raw data files, sometimes merging and setting data sets can produce the wrong result even though there were no error messages. So when in doubt, use PROC PRINT.

Chapter 10: Debugging Your SAS Programs

253

Test programs with small data sets Sometimes it’s not practical to test your program with your entire data set. If your data files are very large, you may not want to print all the data and it may take a long time for your programs to run. In these cases, you can test your program with a subset of your data.
If you are reading data from a file, you can use the OBS= option in the INFILE statement to tell SAS to stop reading when it gets to that line in the file. This way you can read only the first 50 or 100 lines of data or however many it takes to get a good representation of your data. The following statement will read only the first 100 lines of the raw data file Mydata.Dat:
INFILE 'Mydata.Dat' OBS = 100;

You can also use the FIRSTOBS= option to start reading from the middle of the data file. So, if the first 100 data lines are not a good representation of your data but 101 through 200 are, you can use the following statement to read just those lines:
INFILE 'Mydata.Dat' FIRSTOBS = 101 OBS = 200;

Here FIRSTOBS= and OBS= relate to the records of raw data in the file. These do not necessarily correspond to the observations in the SAS data set created. If, for example, you are reading two records for each observation, then you would need to read 200 records to get 100 observations. If you are reading a SAS data set instead of a raw data file, you can use the OBS= and FIRSTOBS= 1 data set options in the SET, MERGE, or UPDATE statements. This controls which observations are processed in the DATA step. For example, the following DATA step will read the first 50 observations in the CATS data set. Note that when reading SAS data sets OBS= and FIRSTOBS= truly do correspond to the observations and not to data lines:
DATA sampleofcats; SET cats (OBS = 50);

Test with representative data Using OBS= and FIRSTOBS= is an easy way to test your programs, but sometimes it is difficult to get a good representation of your data this way. You may need to create a small test data set by extracting representative parts of the larger data set. Or you may want to make up representative data for testing purposes. Making up data has the advantage that you can simplify the data and make sure you have every possible combination of values to test.
Sometimes you may want to make up data and write a small program just to test one aspect of your larger program. This can be extremely useful for narrowing down possible sources of error in a large, complicated program.

Syntax sensitive editors In the Windows operating environment the Enhanced Editor is the default editor; in other operating environments the Program Editor is the default. Both the Enhanced Editor and the Program Editor (starting with SAS 9) color code your program as you 2 write it. SAS keywords appear in one color, variables in another. All text within quotation marks appears in the same color, so it is immediately obvious when you forget to close your quotation marks. Similarly, missing semicolons are much easier to discover because the colors in your program are not right. Catching errors as you type them can be a real time saver.
1 2

Data set options are discussed in section 6.9.

If you are not using Windows, and you do not have SAS 9, you may still be able to use the color coding feature. In the OS/390 and z/OS operating environments, the color coding feature became the default starting with SAS 8.2. In UNIX the color-coding feature became available with SAS 8.2 but may not be the default.

254

The Little SAS Book

10.2 Fixing Programs That Don’t Work
In spite of your best efforts, sometimes programs just don’t work. More often than not, programs don’t run the first time. Even with simple programs it is easy to forget a semicolon or misspell a keyword—everyone does sometime. If your program doesn’t work, the source of the problem may be obvious like an error message with the offending part of your program underlined, or not so obvious as when you have no errors but still don’t have the expected results. Whatever the problem, here are a few guidelines you can follow to help fix your program.

Read the SAS log The SAS log has a wealth of information about your program. In addition to listing the program statements, it tells you things like how many lines were read from your raw data file and what were the minimum and maximum line lengths. It gives the number of observations and variables in each SAS data set you create. Information like this may seem inconsequential at first but can be very helpful in finding the source of your errors.
The SAS log has three types of messages about your program: errors, warnings, and notes.

Errors These are hard to ignore. Not only do they come up in red on your screen, but your program will not run with errors. Usually errors are some kind of syntax or spelling mistake. The following shows the error message when you accidentally add a slash between the PROC PRINT and DATA= keywords. SAS underlines the problem (the slash) and tells you there is a syntax error. Sometimes SAS will tell you what is expected in the location where the error occurred and often this is very revealing.
PROC PRINT / DATA=one; 22 ---202 ERROR 22-322: Syntax error, expecting one of the following: ;, DATA, DOUBLE, HEADING, LABEL, N, NOOBS, OBS, ROUND, ROWS, SPLIT, STYLE, UNIFORM, WIDTH. ERROR 202-322: The option or parameter is not recognized and will be ignored. 1

The location of the error is easy to find, because it is usually underlined, but the source of the error can sometimes be tricky. Sometimes what is wrong is not what is underlined but something else earlier in the program.

Warnings These are less serious than errors because your program will run with warnings.
But beware, a warning may mean that SAS has done something you have not intended. For example, SAS will attempt to correct your spelling of certain keywords. If you misspell INPUT as IMPUT you will get the following message in your log:
WARNING 1-322: Assuming the symbol INPUT was misspelled as IMPUT.

Usually you would think, “SAS is so smart—it knows what I meant to say,” but occasionally that may not be what you meant at all. Make sure that you know what all the warnings are about and that you agree with them.

Notes These are less straightforward than either warnings or errors. Sometimes notes just give you information, like telling you the execution time of each step in your program. But sometimes

Chapter 10: Debugging Your SAS Programs

255

notes can indicate a problem. Suppose, for example, that you have the following note in your SAS log:
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.

This could mean that SAS did exactly what you wanted, or it could indicate a problem with either your program or your data. Make sure that you know what each note means and why it is there.

Start at the beginning Whenever you read the SAS log, start at the beginning. This seems like a ridiculous statement—why wouldn’t you start at the beginning? Well, if you are using the SAS windowing environment, the SAS log rolls by in the Log window. When the program is finished, you are left looking at the end of the log. If you happen to see an error at the end of the log, it is natural to try to fix that error first—the first one you see. Avoid this temptation. Often errors at the end of the log are caused by earlier ones. If you fix the first error, often most or all of the other errors will disappear. If your lawnmower is out of gas and won’t start, it’s probably better to add gas before trying to figure out why it won’t start. The same logic applies to debugging SAS programs; fixing one problem will often fix others. Look for common mistakes first More often than not there is a simple reason why your program doesn’t work. Look for the simple reason before trying to find something more complicated. The remainder of this chapter consists of sections discussing the most common errors encountered in SAS programming. When you see this little bug in the upper-right corner of a section, you’ll know that the material deals with how to debug your program. Some programming errors produce error messages, some just notes. If your SAS log contains an error or a suspicious note, look in this chapter for a section which discusses your error or note.
Sometimes error messages just don’t make any sense. For example, you may get an error message saying the INPUT statement is not valid. This doesn’t make much sense because you know INPUT is a valid SAS statement. In cases like these, look for missing semicolons in the statements before the error. If SAS has underlined an item, be sure to look not only at the underlined item but also at the previous few statements. Finally, if you just can’t figure out why you are not getting the results you expect, make sure you add PROC PRINT statements everywhere you create a new SAS data set. This can really help you discover errors in your logic, and sometimes uncover surprising details about your data.

Check your syntax If you have large data sets, you may want to check for syntax errors in your program before processing your data. Do this by telling SAS not to process any data when you submit your program. Add the following line to your program and submit it in the usual way:
OPTIONS OBS=0 NOREPLACE;

The OBS=0 option tells SAS not to process any data, while the NOREPLACE option tells SAS not to replace existing SAS data sets with empty ones. Once you know your syntax is correct, you can resubmit your program without the OPTIONS statement in batch mode, or replace the OPTIONS with the following if you are using the SAS windowing environment.
OPTIONS OBS=MAX REPLACE;

Remember that this syntax check will not uncover any errors related to your data or logic errors.

256

The Little SAS Book

10.3 Searching for the Missing Semicolon
DATA toad

s;

Missing semicolons are the most common source of errors in SAS programs. For whatever reason, we humans can’t seem to remember to put a semicolon at the end of all our statements. (Maybe we all have rebellious right pinkies— who knows.) This is unfortunate because, while it is easy to forget the semicolon, it is not always easy to find the missing semicolon. The error messages produced are often misleading, making it difficult to find the error.

SAS reads statements from one semicolon to the next without regard to the layout of the program. If you leave off a semicolon, you in effect concatenate two SAS statements. Then SAS gets confused because it seems as though you are missing statements, or it tries to interpret entire statements as options in the previous statement. This can produce some very puzzling messages. So, if you get an error message that just doesn’t make sense, look for missing semicolons.

ERROR 180-322: Statement is not valid or it is used out of proper order. 4 INPUT ToadName $ Weight Jump1 Jump2 Jump3; ----180

ERROR 180-322: Statement is not valid or it is used out of proper order. 5 RUN;

In this case, DATA toads becomes part of the comment statement. Because there is now no DATA statement, SAS underlines the INFILE and INPUT keywords and says, “Hey these statements are in the wrong place; they have to be part of a DATA step.” This doesn’t make much sense to you because you know INFILE and INPUT are valid statements, and you did put them in a DATA step (or so you thought). That’s when you should suspect a missing semicolon.

Chapter 10: Debugging Your SAS Programs

257

Example The next example shows the same program, but now the semicolon is missing from the DATA statement. The INFILE statement becomes part of the DATA statement, and SAS tries to create a SAS data set named INFILE. SAS also tries to interpret the filename, ‘c:\MyRawData\ToadJump.dat’ as a SAS data set name, but the .dat extension is not valid for SAS data sets. It also gives you an error saying that there is no DATALINES or INFILE statement. In addition, you get some warnings about data sets being incomplete. This is a good example of how one simple mistake can produce a lot of confusing messages:
30 31 32 33 34 * Read the data file ToadJump.dat using list input; DATA toads INFILE 'C:\MyRawData\ToadJump.dat'; INPUT ToadName $ Weight Jump1 Jump2 Jump3; RUN;

ERROR: No DATALINES or INFILE statement. ERROR: Extension for physical file name "C:\MyRawData\ToadJump.dat" does not correspond to a valid member type. NOTE: The SAS System stopped processing this step because of errors. WARNING: The data set WORK.TOADS may be incomplete. When this step was stopped there were 0 observations and 5 variables. WARNING: Data set WORK.TOADS was not replaced because this step was stopped. WARNING: The data set WORK.INFILE may be incomplete. When this step was stopped there were 0 observations and 5 variables. WARNING: Data set WORK.INFILE was not replaced because this step was stopped.

Missing semicolons can produce a variety of error messages. Usually the messages say that either a statement is not valid, or an option or parameter is not valid or recognized. Sometimes you don’t get an error message, but the results are still not right. If you leave off the semicolon from the last RUN statement when submitting programs in the SAS windowing environment, you won’t get an error. But SAS won’t run the last part of your program either.

The DATASTMTCHK system option Some missing semicolons, such as the one in the last example, are easier to find if you use the DATASTMTCHK system option. This option controls what names you can use for SAS data sets in a DATA statement. By default it is set so that you cannot use the words: MERGE, RETAIN, SET, or UPDATE as a SAS data set name. This prevents you from accidentally overwriting an existing data set just because you forget a semicolon at the end of a DATA statement. You can make all SAS keywords invalid SAS data set names by setting the DATASTMTCHK option to ALLKEYWORDS. The partial log below again shows a missing semicolon at the end of the DATA statement, but this time DATASTMTCHK is set to ALLKEYWORDS:
35 36 37 38 OPTIONS DATASTMTCHK=ALLKEYWORDS; * Read the data file ToadJump.dat using list input; DATA toads INFILE 'C:\MyRawData\ToadJump.dat'; -----57 ERROR 57-185: INFILE is not allowed in the DATA statement when option DATASTMTCHK=ALLKEYWORDS. Check for a missing semicolon in the DATA statement, or use DATASTMTCHK=NONE. 39 40 INPUT ToadName $ Weight Jump1 Jump2 Jump3; RUN;

258

The Little SAS Book

10.4 Note: INPUT Statement Reached Past the End of the Line input lions tigers bears

The note “SAS went to a new line when INPUT statement reached past the end of a line” is rather innocent looking, but its presence can indicate a problem. This note often goes unnoticed. It doesn’t come up in red or even green lettering. It doesn’t cause your program to stop. But look for it in your SAS log because it is a common note that usually means there is a problem.

This note means that as SAS was reading your data, it got to the end of the data line before it read values for all the variables in your INPUT statement. When this happens, SAS goes by default to the next line of data to get values for the remaining variables. Sometimes this is exactly what you want SAS to do, but if it’s not, take a good look at your SAS log and output to be sure you know why this is happening. Look in your SAS log where it tells you the number of lines it read from the data file and the number of observations in the SAS data set. If you have fewer observations than lines read, and you planned to have one observation per line, then you know you have a problem. Print the SAS data set using PROC PRINT. This can be very helpful in determining the source of the problem.

Example The following shows what can happen if you are using list input, and you don’t have periods for missing values. You have the following data from the toad-jumping contest, where the toad’s number is followed by its weight and distances for each of three jumps. When a toad was disqualified from a jump, no entry was made for that jump:
13 25 10 8 3 21 65 131 202 128 162 99 1.9 3.0 2.5 3.1 .5 3.8 3.2 1.9 2.6 2.4 1.7 3.0

The following is the SAS log from a program that reads the raw data using list input and prints the results using PROC PRINT:
1 2 3 DATA toads; INFILE ’c:\MyRawData\Toadjmp2.dat’; INPUT ToadNumber Weight Jump1 Jump2 Jump3;

 NOTE: 6 records were read from the infile ’c:\MyRawData\Toadjmp2.dat’.
The minimum record length was 6. The maximum record length was 18.  NOTE: SAS went to a new line when INPUT statement reached past the end of a line.  NOTE: The data set WORK.TOADS has 3 observations and 5 variables. NOTE: DATA statement used (Total process time): real time 0.37 seconds 4 PROC PRINT; 5 TITLE ’SAS Data Set Toads’;

 Notice that there were six records read from the raw data file.  But, there are only three observations in the SAS data set.  The note, “… INPUT statement reached past the end of a line,” should alert you that there may be a problem. Chapter 10: Debugging Your SAS Programs

259

A look at the results of the PROC PRINT confirms that there is a problem since the numbers don’t look at all correct. (Can a toad jump 128 meters?)
SAS Data Set Toads Toad Number 13 10 3 1

Obs 1 2 3

Weight 65 202 162

Jump1 1.9 3.8 21.0

Jump2 3 8 99

Jump3 25.0 128.0 2.4

Here SAS went to a new line when you didn’t want it to. To fix this problem, the simplest thing to do is use the MISSOVER option in the INFILE statement. MISSOVER instructs SAS to assign missing values to any variables for which there were no data instead of going to the next line for data. The INFILE statement would look like this:
INFILE 'c:\MyRawData\Toadjmp2.dat' MISSOVER;

Possible causes Other reasons for receiving a note informing you that the INPUT statement reached past the end of the line include
¨ ¨ You planned for SAS to go to the next data line when it ran out of data. Blank lines in your data file, usually at the beginning or end, can cause this note. Look at the minimum line length in the SAS log. If it is zero, then you have blank lines. Edit out the blank lines and rerun your program. If you are using list input and you do not have a space between every value, you can get this note. For example, if you try to read the following data using list input, SAS will run out of data for the Gilroy Garlics because there is no space between the 15 and the 1035. SAS will read it as one number, then read the 12 where it should have been reading the 1035, and so on. To correct this problem, either add a space between the two numbers, or use column or formatted input.
Columbia Peaches Gilroy Garlics Sacramento Tomatoes 35 67 1 10 151035 12 11 124 85 15 4 2 7 9 1 6 1

¨

¨

If you have some data lines which are shorter than the rest, and you are using column or formatted input, this can cause a problem. If you try to read a name, for example, in columns 60 through 70 when some of the names extend only to column 68, and you didn’t add spaces at the end of the line to fill it out to column 70, then SAS will go to the next line to read the name. To avoid this problem, use the TRUNCOVER option in the INFILE statement (discussed in section 2.14). For example:
INFILE 'c:\MyRawData\Addresses.dat' TRUNCOVER;

260

The Little SAS Book

10.5 Note: Lost Card

K A p p

If you are reading multiple lines of data for each observation, then a lost card could mean you have missing or duplicate lines of data. If you are reading two data lines for each observation, then SAS will expect an even number of lines in the data file. If you have an odd number, then you will get the lost-card message. It can often be difficult to locate the missing or duplicate lines, especially with large data files. Printing the SAS data set as well as careful proofreading of the data file can be helpful in identifying problem areas.

p

J
10 p

Lost card? You thought you were writing SAS programs, not playing a card game. This note makes more sense if you remember that computer programs and data used to be punched out on computer cards. A lost card means that SAS was expecting another line (or card) of data and didn’t find it.

Example The following example shows what can happen if you have a missing data line. The raw data show the normal high and low temperatures and the record high and low for the month of July for each city. The last city is missing the last data line:
Nome AK 55 44 88 29 Miami FL 90 75 97 65 Raleigh NC 88 68

The following shows the SAS log from a program which reads the data, three lines per observation:
1 2 3 DATA highlow; INFILE ’c:\MyRawData\Temps.dat’; INPUT City $ State $ / NormalHigh NormalLow/ RecordHigh RecordLow;

In this case, you get the lost-card note, and SAS prints the values of the variables it read for the observation with the lost card. The observation is not included in the SAS data set. You can see

Chapter 10: Debugging Your SAS Programs

261

from the log that SAS read eight records from the file (it should have been a multiple of three) but the SAS data set has only two observations. The last partial observation was not included.

Example It is very common to get other messages along with the lost-card note. The invalid-data note is a common byproduct of the lost card. If the second line were missing from the temperature data, then you would get invalid data as well as a lost card because SAS will try to read Miami FL as the record high and low. The following shows the invalid-data note from the SAS log:
Nome AK 88 29 Miami FL 90 75 97 65 Raleigh NC 88 68 105 50
NOTE: Invalid data for RecordHigh in line 3 1-5. NOTE: Invalid data for RecordLow in line 3 7-8. RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+ 3 Miami FL City=Nome State=AK NormalHigh=88 NormalLow=29 RecordHigh=. RecordLow=. _ERROR_=1 _N_=1

Example In addition to getting the lost-card note, it is also common to get a note indicating that the INPUT statement reached past the end of a line. If you forgot the last number in the file, as in the following example, then you would get these two notes together:
Nome AK 55 44 88 29 Miami FL 90 75 97 65 Raleigh NC 88 68 105

Because the program uses list input, SAS will try to go to the next line to get the data for the last variable. Since there isn’t another line of data, you get the lost-card note. The following is part of the SAS log showing these two messages together:
NOTE: LOST CARD. City=Raleigh State=NC NormalHigh=88 NormalLow=68 RecordHigh=105 RecordLow=. _ERROR_=1 _N_=3 NOTE: 9 records were read from the infile ’c:\MyRawData\Temps3.dat’. The minimum record length was 3. The maximum record length was 10. NOTE: SAS went to a new line when INPUT statement reached past the end of a line. NOTE: The data set WORK.HIGHLOW has 2 observations and 6 variables.

For this example, the solution is to add the missing data to the raw data file and rerun the program.

262

The Little SAS Book

10.6 Note: Invalid Data
The typical new SAS user, upon seeing the invalid-data note, will ignore it, hoping perhaps that it will simply go away by itself. That’s rather ironic considering that the message is explicit and easy to interpret once you know how to read it.

Interpreting the message The invalid-data note appears when SAS is unable to read from a raw data file because the data are inconsistent with the INPUT statement. This note almost always indicates a problem. For example, one common mistake is typing in the letter O instead of the number 0. If the variable is numeric, then SAS is unable to interpret the letter O. In response, SAS does two things; it sets the value of this variable to missing and prints out a message like this for the problematic observation:
 NOTE: Invalid data for IDNumber in line 8 1-5.  RULE:----+----1----+----2----+----3----+----4----+----5----+----6----+  8 0O7 James Bond SA341  IDNumber=. Name=James Bond Class=SA Q1=3 Q2=4 Q3=1 _ERROR_=1 _N_=8  The first line tells you where the problem occurred. Specifically, it states the name of the variable SAS got stuck on and the line number and columns of the raw data file that SAS was trying to read. In this example, the error occurred while SAS was trying to read a variable named IDNumber from columns 1 through 5 in line 8 of the input file. The next line is a type of ruler with columns as the increments. The numeral 1 marks the tenth column, 2 marks the twentieth, and so on. Below the ruler, SAS dumps the actual line of raw data so you can see the little troublemaker for yourself. Using the ruler as a guide, you can count over to the column in question. At this point you can compare the actual raw data to your INPUT statement, and the error is usually obvious. The value of IDNumber should be zero-zero-seven, but looking at the line of actual data you can see that a careless typist has typed zero-letter O-seven. Such an error may seem minor to you, but you’ll soon learn that computers are hopelessly persnickety. As if this weren’t enough, SAS prints one more piece of information: the values of each variable for that observation as SAS read it. In this case, you can see that IDNumber equals missing, Name equals James Bond, and so on. Two automatic variables appear at the end of the line: _ERROR_ and _N_. The _ERROR_ variable has a value of 1 if there is a data error for that observation, and 0 if there is not. In an invalid-data note, _ERROR_ always equals 1. The automatic variable _N_ is the number of times SAS has looped through the DATA step.

As before, SAS prints the line of raw data that contains the invalid data. Directly below the line of raw data, SAS prints two lines containing the hexadecimal equivalent of the data. You needn’t understand hexadecimal values to be able to read this. SAS prints the data this way because the normal 10 numerals and 26 letters don’t provide enough values to represent all computer symbols uniquely. Hexadecimal uses two characters to represent each symbol. To read hexadecimal, take a digit from the first line (labeled ZONE) together with the corresponding digit from the second line (labeled NUMR). In this case, a tab slipped into column 2 and appears as a harmless-looking period in the line of data. In hexadecimal, however, the tab appears as 09, while a real 1 period in column 1 is 2E in hex.

Possible causes Common reasons for receiving the invalid-data note include
¨ ¨ ¨ ¨ ¨ ¨ ¨ ¨ using the letter O instead of the number zero forgetting to specify that a variable is character (SAS assumes it is numeric) incorrect column specifications producing embedded spaces in numeric data list-style data with two periods in a row and no space in between missing data not marked with a period for list-style input causing SAS to read the next data value using special characters such as tab, carriage-return-line-feed, or form-feed in numeric data using the wrong informat such as MMDDYY. instead of DDMMYY. invalid dates (such as September 31) read with a date informat.

1

In OS/390 or z/OS the hexadecimal representation of a tab is 05.

264

The Little SAS Book

10.7 Note: Missing Values Were Generated
The missing-values note appears when SAS is unable to compute the value of a variable because of preexisting missing values in your data. This is not necessarily a problem. It is possible that your data contain legitimate missing values and that setting a new variable to missing is a desirable response. But it is also possible that the missing values result from an error and that you need to fix your program or your data. A good rule is to think of the missing-values note as a flag telling you to check for an error.

Notice that several of the toads have missing values for one or more jumps. To compute the average distance jumped, the program in the following SAS log reads the raw data, adds together the values for the three jumps, and divides by three:
1 2 3 4 5 DATA toads; INFILE ’c:\MyRawData\Jump.dat’; INPUT ToadName $ Jump1 Jump2 Jump3; AverageJump = (Jump1 + Jump2 + Jump3) / 3; RUN;

NOTE: The infile ’c:\MyRawData\Jump.dat’ is: FILE NAME=c:\MyRawData\Jump.dat, RECFM=V,LRECL=132 NOTE: 6 records were read from the infile ’c:\MyRawData\Jump.dat’. The minimum record length was 17. The maximum record length was 18. NOTE:  Missing values were generated as a result of performing an operation on missing values.  Each place is given by: (Number of times) at (Line):(Column) 3 at 4:25 NOTE: The data set WORK.TOADS has 6 observations and 5 variables.

Because of missing values in the data, SAS was unable to compute AverageJump for some of the toads. In response, SAS printed the missing-values note which has two parts:   The first part of the note says that SAS was forced to set some values to missing. The second part is a bit more cryptic. SAS lists the number of times values were set to missing. This generally corresponds to the number of observations that generated missing values, unless the problem occurs within a DO-loop. Next SAS states where in the program it encountered the problem. In the preceding example, SAS set three values to missing: at line 4, column 25. Looking at the program, you can see that line 4 is the line which calculates AverageJump, and column 25 contains the first plus sign. Looking at the raw data, you can see that three observations have missing values for Jump1, Jump2, or Jump3. Those observations are the three times mentioned in the missing-values note.

Chapter 10: Debugging Your SAS Programs

265

Finding the missing values In this case it was easy to find the observations with missing values. But if you had a data set with hundreds, or millions, of observations, then you couldn’t just glance at the data. In that case, you could subset the problematic observations with a subsetting IF statement, and print them with a program like this:
DATA missing; INFILE 'Jump.dat'; INPUT ToadName $ Jump1 Jump2 Jump3; AverageJump = (Jump1 + Jump2 + Jump3) / 3; IF AverageJump = .; PROC PRINT DATA = missing; TITLE 'Observations with Missing Values Generated'; RUN;

Using the SUM and MEAN functions You may be able to circumvent this problem when you are computing a sum or mean by using the SUM or MEAN function instead of an arithmetic expression. In the preceding program, you could remove this line:
AverageJump = (Jump1 + Jump2 + Jump3) / 3;

And substitute this line:
AverageJump = MEAN(Jump1, Jump2, Jump3);

The SUM and MEAN functions use only non-missing values for the computation. In this example, you would still get the missing-values note for one toad, Winner, because it had missing values for all three jumps.

266

The Little SAS Book

10.8 Note: Numeric Values Have Been Converted to Character (or Vice Versa)
Even with only two data types, numeric and character, SAS programmers sometimes get their variables mixed up. When you accidentally mix numeric and character variables, SAS tries to fix your program by converting variables from numeric to character or vice versa, as needed. Programmers sometimes ignore this problem, but that is not a good idea. If you ignore this message, it may come back to haunt you as you find new incompatibilities resulting from the fix. If, indeed, a variable needs to be converted, you should do it yourself, explicitly, so you know what your variables are doing.

Example To show how SAS handles this kind of incompatibility, here are data about a class.
Each line of data contains a student’s ID number, name, and scores on two tests.
110 203 105 224 Linda Derek Kathy Michael 53 72 98 80 60 64 82 55

The instructor runs the following program to read the data and create a permanent SAS data set named SCORES.
LIBNAME students 'c:\MySASLib'; DATA students.scores; INFILE 'c:\MyRawData\Scores.dat'; INPUT StudentID Name $ Score1 Score2 $; RUN;

After creating the permanent SAS data set, the instructor runs a program to compute the total score and substring the first digit of StudentID. (Students in section 1 of the class have IDs starting with 1 while students in section 2 have IDs starting with 2.) Here is the log from the program:
2 3 4 5 6 DATA grades; SET students.scores; TotalScore = Score1 + Score2; Class = SUBSTR(StudentID,2,1); Run;

NOTE: Character values have been converted to numeric values at the places given by:(Line):(Column). 4:26 NOTE: Numeric values have been converted to character values at the places given by:(Line):(Column). 5:19 NOTE: There were 4 observations read from the data set STUDENTS.SCORES. NOTE: The data set WORK.GRADES has 4 observations and 6 variables. NOTE: DATA statement used (Total process time): real time 0.04 seconds cpu time 0.04 seconds

This program produces two values-have-been-converted notes. The first conversion occurred in line 4, column 26. Looking at the log you can see that the variable Score2 appears in column 26 of line 4. Score2 was accidentally input as a character variable, so SAS had to convert it to numeric before adding it to Score1 to compute TotalScore.

Chapter 10: Debugging Your SAS Programs

267

The second conversion occurred in line 5, column 19. Looking at the log you can see that the variable StudentID appears in column 19 of line 5. StudentID was input as a numeric variable, but the SUBSTR function requires character variables, so SAS was forced to convert StudentID to character.

Converting variables You could go back and input the raw data with the correct types, but sometimes that’s just not practical. Instead you can convert the variables from one type to another. To convert variables from character to numeric, you use the INPUT function. To convert from numeric to character, you use the PUT function. Most often, you would use these functions in an assignment statement with the following syntax:
Character to Numeric newvar = INPUT(oldvar, informat);

Numeric to Character newvar = PUT(oldvar, format);

These two slightly eccentric functions are first cousins of the PUT and INPUT statements. Just as an INPUT statement uses informats, the INPUT function uses informats; and just as PUT statements use formats, the PUT function uses formats. These functions can be confusing because they are similar but different. In the case of the INPUT function, the informat must be the type you are converting to—numeric. In contrast, the format for the PUT function must be the type you are 1 converting from—numeric. To convert the troublesome variables in the preceding program, you would use these statements: Character to Numeric
NewScore2 = INPUT(Score2, 2.);

NOTE: There were 4 observations read from the data set STUDENTS.SCORES. NOTE: The data set WORK.GRADES has 4 observations and 8 variables. NOTE: DATA statement used (Total process time): real time 0.03 seconds cpu time 0.03 seconds

Notice that this version of the program runs without any suspicious messages.

1

In this discussion, we are talking about converting variables from numeric to character or vice versa, but you can also use the PUT function to change one character value to another character value. When you do this, oldvar and newvar would be character variables, and the format would be a character format.

268

The Little SAS Book

10.9 DATA Step Produces Wrong Results but No Error Message
Some of the hardest errors to debug aren’t errors at all, at least not to SAS. If you do complex programming, you may write a DATA step that runs just fine—with no errors or suspicious notes—but produces the wrong results. The more complex your programs are, the more likely you are to get this kind of error. Sometimes it seems like a DATA step is a black box. You know what goes in, and you know what comes out, but what happens in the middle is a mystery. This problem is actually a logic error; somewhere along the way SAS got the wrong instruction.

Example Here is a program that illustrates this problem and how to debug it. The raw data file below contains information from a class. For each student there are three scores from tests, and one score from homework:
Linda Derek Kathy Michael 53 72 98 80 60 66 42 64 56 32 82 100 48 55 95 50

NOTE: The infile ’c:\MyRawData\Class.dat’ is: File Name=c:\MyRawData\Class.dat, RECFM=V,LRECL=256 NOTE: 4 records were read from the infile ’c:\MyRawData\Class.dat’. The minimum record length was 20. The maximum record length was 20. NOTE: The data set WORK.LOWSCORE has 0 observations and 6 variables.

First, the DATA step reads the raw data from a file called Class.dat. The highest possible score on homework is 50. To make the homework count the same as a test, the program doubles the value of Homework. Then the program computes the mean of the three test scores and Homework, and subsets the data by selecting only observations with a mean score below 70. Unfortunately, something went wrong. The LOWSCORE data set contains no observations. A glance at the raw data confirms that there should be students whose mean scores are below 70.

Using the PUT statement to debug To debug a problem like this, you have to figure out exactly what is happening inside the DATA step. A good way to do this is with PUT statements. Elsewhere in this book, PUT statements are used along with FILE statements to write raw data files and custom reports. If you use a PUT statement without a FILE statement, then SAS writes the data in the SAS log. That is just fine for debugging. PUT statements can take many forms, but for debugging, a handy style of PUT statement is
PUT _ALL_;

Chapter 10: Debugging Your SAS Programs

269

SAS will print all the variables in your data set: first the variable name, then the actual data value, with an equal sign in between. If you have a lot of variables, you can print just the relevant ones this way:
PUT variable-1= variable-2= . . . variable-n=;

Without the equal signs, SAS would print just the data values. Adding the equal signs tells SAS to label the data so that you know which data values are which. The DATA step below is identical to the one shown earlier except that a PUT statement was added. In a longer DATA step, you might choose to have more than one PUT statement. In this case, one will suffice. This PUT statement is placed before the subsetting IF, since in this particular program the subsetting IF eliminates all observations:
9 10 11 12 13 14 15 16 17 * Keep only students with mean below 70; DATA lowscore; INFILE ’c:\MyRawData\Class.dat’; INPUT Name $ Score1 Score2 Score3 Homework; Homework = Homework * 2; AverageScore = MEAN(Score1 + Score2 + Score3 + Homework); PUT Name= Score1= Score2= Score3= Homework= AverageScore=; IF AverageScore < 70; RUN;

Looking at the the log, you can see the result of the PUT statement. The data listed in the middle of the log show that the variables are being input properly, and the variable Homework is being adjusted properly. However, something is wrong with the values of AverageScore; they are much too high. There is a syntax error in the line that computes AverageScore. Instead of commas separating the three score variables in the MEAN function, there are plus signs. Since functions can contain arithmetic expressions, SAS simply added the four variables together, as instructed, and computed the mean of a single number. That’s why no observations had values of AverageScore below 70.

270

The Little SAS Book

10.10 The DATA Step Debugger
If you use interactive SAS, then you have another choice when it comes to debugging logic errors. Instead of the PUT statements discussed in the previous section, you can use the DATA step debugger. To understand the DATA step debugger, you have to know that SAS runs every program in two phases. To the person running the program, it looks like one action, but in reality SAS first compiles your program, then SAS executes your program. Errors can occur during either phase, but they are different types of errors. Syntax errors and some data errors (such as numeric-tocharacter-conversion) occur at compile time. Other errors such as logic errors and some data errors (such as missing-values-were-generated) compile just fine, but cause you to get bad results at execution. The DATA step debugger does its work at execution time. That means you can’t use the DATA step debugger to find compile-time errors such as missing semicolons. (You don’t really need it for these errors since they always generate messages in your log.) However, if you have an execution-time error, then the DATA step debugger may be a big help.

Starting the debugger The following program is supposed to select students whose average score is below 70, but it doesn’t work. To invoke the debugger, simply add the DEBUG option to the end of your DATA statement, and submit the DATA step from the SAS windowing environment.
* Keep only students with mean below 70; DATA lowscore / DEBUG; INFILE 'c:\MyRawData\Class.dat'; INPUT Name $ Score1 Score2 Score3 Homework; Homework = Homework * 2; AverageScore = MEAN(Score1 + Score2 + Score3 + Homework); IF AverageScore < 70; RUN;

The debugger windows After you submit the DATA step, two windows will appear: the DEBUGGER LOG window and the DEBUGGER SOURCE window. The DEBUGGER LOG window contains messages from the debugger and a command line. The DEBUGGER SOURCE window contains your DATA step statements with the current line highlighted.
One nice bonus of the DATA step debugger is the ability to watch SAS executing a DATA step line-by-line and observation-by-observation. Since the highlighting in the DEBUGGER SOURCE window marks each line as SAS executes it, the debugger provides a graphic illustration of the structure of a DATA step. For a beginner, this alone could be very enlightening. You may even

Chapter 10: Debugging Your SAS Programs

271

want to take a DATA step that works just fine, and run it through the DATA step debugger just to see this.

Executing debugger commands You can control the debugger in two ways—using pull-down menus or typing commands at a command line. Once you invoke the DATA step debugger, you will see some new menu options. The View, Run, and Breakpoint menus contain debugger commands. If you prefer to type commands, you can type them after the arrow at the bottom of the DEBUGGER LOG window. In the DEBUGGER LOG window to the right, the STEP command has been typed at the command line. The following table shows the most common commands:

Menu Path
Run-Step

Command Line STEP n

Description executes one statement executes n statements, where n is a number prints the values of variables assigns a value to a specified variable for the current observation ends the debugger and finishes executing the DATA step In this DEBUGGER LOG window you can see the programmer has pressed the return key until SAS stepped to line 6 of the program. Then the programmer typed EXAMINE _ALL_, and SAS listed all the variables and their values. Looking at the data values, you can see the value of AverageScore is much too high. There is a logic error in the line that computes AverageScore. The plus signs should be commas. Once you find the error, quit the debugger, and correct the error, remembering to remove the DEBUG option.

View-Examine values View-Set values

EXAMINE variable-list SET variable = expression

Run-Quit

QUIT

272

The Little SAS Book

10.11 Error: Invalid Option, Error: The Option Is Not Recognized, or Error: Statement Is Not Valid
If SAS cannot make sense out of one of your statements, it stops executing the current DATA or PROC step and prints one of these messages:
ERROR 22-7: Invalid option name. ERROR 202-322: The option or parameter is not recognized. ERROR 180-322: Statement is not valid or it is used out of proper order.

The invalid-option message and its cousin, the option-is-not-recognized message, tell you that you have a valid statement, but SAS can’t make sense out of an apparent option. The statement-is-notvalid message, on the other hand, means that SAS can’t understand the statement at all. Thankfully, with all three messages SAS underlines the point at which it got confused so you know where to look for the problem.

SAS underlined the VAR statement. This message may seem puzzling since VAR is not an option, but a statement, and a valid statement at that. But if you look at the previous statement, you will see that the PROC statement is missing one of those pesky semicolons. As a result, SAS tried to interpret the words VAR and Score2 as options in the PROC statement. Since no options exist with those names, SAS stopped processing the step and printed the option-is-not-recognized message. SAS also printed the syntax-error message listing all the valid options for a PROC statement.

Chapter 10: Debugging Your SAS Programs

273

Example Here is a log with the statement-is-not-valid message:
8 9 PROC PRINT; SET class; --180 ERROR 180-322: Statement is not valid or it is used out of proper order. 10 RUN; NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE PRINT used (Total process time): real time 0.01 seconds cpu time 0.01 seconds

In this case, a SET statement was used in a PROC step. Since SET statements can be used only in DATA steps, SAS underlines the word SET and prints the statement-is-not-valid message.

Possible causes Generally, with these error messages, the cause of the problem is easy to detect. You should check the underlined item and the previous statement for possible errors. Possible causes include
¨ ¨ ¨ ¨ ¨ ¨ ¨ a misspelled keyword a missing semicolon a DATA step statement in a PROC step (or vice versa) a RUN statement in the middle of a DATA or PROC step (this does not cause errors for some procedures) the correct option with the wrong statement an unmatched quotation mark an unmatched comment.

274

The Little SAS Book

10.12 Note: Variable Is Uninitialized or Error: Variable Not Found
If you find one of these messages in your SAS log, then SAS is telling you that the variable named in the message does not exist:
NOTE: Variable X is uninitialized. WARNING: Variable X not found. ERROR: Variable X not found.

Generally, the first time you get one of these messages, it is quite a shock. You may be sure that the variable does exist. After all, you remember creating it. Fortunately, the problem is usually easy to fix once you understand what SAS is telling you. If the problem happens in a DATA step, then SAS prints the variable-is-uninitialized note, initializes the variable, and continues to execute your program. Normally variables are initialized when they are read (via an INPUT, SET, MERGE, or UPDATE statement) or when they are created via an assignment statement. If you use a variable for the first time in a way that does not assign a value to the variable (such as on the right side of an assignment statement, in the condition of an IF statement, or in a DROP or KEEP option) then SAS tries to fix the problem by assigning a value of missing to the variable for all observations. This is very generous of SAS, but it almost never fixes the problem, since you probably don’t want the variable to have missing values for all observations. When the problem happens in a PROC step, the results are more grave. If the error occurs in a critical statement such as a VAR statement, then SAS prints the variable-not-found error and does not execute the step. If the error occurs in a less critical statement such as a LABEL statement, then SAS prints the variable-not-found warning message, and attempts to run the step.

Example Here is the log from a program with missing-variable problems in both a DATA and a
PROC step:
1 2 3 4 5 DATA highscore (KEEP = Name Total); INPUT Name $ Score1 Score2; IF Scor1 > 5; Total = Score1 + Score2; DATALINES;

In this DATA step, the INPUT statement reads three variables: Name, Score1, and Score2. But a misspelling in the subsetting IF statement causes SAS to initialize a new variable named Scor1. Because Scor1 has missing values, none of the observations satisfies the subsetting IF, and the data set HIGHSCORE is left with zero observations. In the PROC PRINT, the VAR statement requests three variables: Name, Score2, and Total. Score2 did exist but was dropped from the data set by the KEEP= option in the DATA statement. That KEEP= option kept only two variables, Name and Total. As a result, SAS prints the variable-notfound error message, and does not execute the PROC PRINT.

Possible causes Common ways to “lose” variables include
¨ ¨ ¨ ¨ misspelling a variable name using a variable that was dropped at some earlier time using the wrong data set committing a logic error, such as using a variable before it is created.

If the source of the problem is not immediately obvious, PROC CONTENTS can often help you figure out what is going on. PROC CONTENTS, which is discussed in section 2.21, gives you information about what is in a SAS data set including variable names.

276

The Little SAS Book

10.13 SAS Truncates a Character Variable
Sometimes you may notice that some, or all, of the values of a character variable are truncated. You may be expecting “peanut butter” and get “peanut b” or “chocolate ice cream” and get “chocolate ice.” This usually happens when you use IF statements to create a new character variable, or when you are using list-style input and you have values longer than eight characters. All character variables have a fixed length determined by one of the following methods.

INPUT statement If a variable’s values are read from a raw data file, then the length is determined by the INPUT statement. If you are using list-style input, then the length defaults to 8. If you are using column or formatted input, then the length is determined by the number of columns, or informat. The following shows examples of INPUT statements that read values for the variable Food and the resulting lengths of Food:
INPUT statement
INPUT Food $; INPUT Food $ 1-10; INPUT Food $15.;

Length of Food
8 10 15

Assignment statement If you are creating the variable in an assignment statement, then the length is determined by the first occurrence of the new variable name. For example, the following program creates a variable, Status, whose values are determined by the Temperature variable:
DATA summer; SET temps; IF Temperature > 100 THEN Status = 'Hot'; ELSE Status = 'Cold'; RUN;

Because the word Hot has three characters and that is the first statement which uses the variable, Status has a length of 3. Any other values for that variable would be truncated to three characters (Col instead of Cold, for example).

LENGTH statement The LENGTH statement in a DATA step defines variable lengths and, if it comes before the INPUT or assignment statement, will override either of the previous two methods of determining length. The following LENGTH statement sets the length of the Status variable to 4 and the Food variable to 15:
LENGTH Status $4 Food $15;

ATTRIB statement You can also assign variable lengths in an ATTRIB statement in a DATA step where you can associate formats, informats, labels, and lengths to variables in a single statement. Always place the LENGTH option before a FORMAT option in an ATTRIB statement to ensure that the variables are assigned proper lengths. For example, the following statement assigns the character variable Status a length of 4 and the label Hot or Cold:
ATTRIB Status LENGTH = $4 LABEL = 'Hot or Cold';

Chapter 10: Debugging Your SAS Programs

277

Example The following example shows what can happen if you let SAS determine the length of a character variable (in this case, using the assignment statement method). You have the following data for a consumer survey of car color preferences. Age is followed by sex (coded as 1 for male and 2 for female), annual income, and preferred car color (yellow, gray, blue, or white):
19 45 72 31 58 1 1 2 1 2 14000 65000 35000 44000 83000 Y G B Y W

You want to create a new variable, AgeGroup, which has these values: Teen for customers under 20, Adult for ages 20 through 64, and Senior for those 65 and over. In the following program, a series of IF-THEN/ELSE statements create AgeGroup:
DATA carsurvey; INFILE 'c:\MyRawData\Cars.dat'; INPUT Age Sex Income Color $; IF Age < 20 THEN AgeGroup = 'Teen'; ELSE IF Age < 65 THEN AgeGroup = 'Adult '; ELSE AgeGroup = 'Senior'; PROC PRINT DATA = carsurvey; TITLE 'Car Color Survey Results'; RUN;

The following results of the PROC PRINT show how the values of AgeGroup are truncated to four characters—the number of characters in Teen.
Car Color Survey Results Age Group Teen Adul Seni Adul Adul 1

Obs 1 2 3 4 5

Age 19 45 72 31 58

Sex 1 1 2 1 2

Income 14000 65000 35000 44000 83000

Color Y G B Y W

The addition of a LENGTH statement in the DATA step, as follows, would eliminate the truncation problem:
DATA carsurvey; INFILE 'c:\MyRawData\Cars.dat'; INPUT Age Sex Income Color $; LENGTH AgeGroup $6; IF Age < 20 THEN AgeGroup = 'Teen'; ELSE IF Age < 65 THEN AgeGroup = 'Adult'; ELSE AgeGroup = 'Senior'; RUN;

278

The Little SAS Book

10.14 SAS Stops in the Middle of a Job
One of the most disconcerting errors encountered by SAS users is having SAS stop in the middle of a job. It’s as if your program has suddenly dropped dead without so much as an error message to act as a smoking gun. Without an error message, you are left to sleuth this problem on your own. Often the problem has nothing to do with SAS. Instead the operating environment may have stopped your program in its tracks. Other times the problem results from programming errors that prevent SAS from seeing the entire job. A number of completely unrelated reasons can cause SAS to stop in the middle of a job. They are listed below, starting with the most general problems and ending with the ones that are specific to certain execution modes or operating environments.

An unmatched quotation mark Unmatched quotation marks wreak havoc on SAS programs, including making SAS stop in the middle of a job. In this case, SAS stops because, in effect, it thinks the remainder of the job is part of a quote. In batch or non-interactive mode, the solution is simple enough. Insert the missing quotation mark and resubmit the program. In the SAS windowing environment you can’t just resubmit the program because SAS is still waiting for the other quotation mark. The solution is to submit a sacrificial quotation mark like this:
'; RUN;

Then edit your program, correct the problem (remembering to delete the extra quotation mark and RUN statement at the end), and rerun the program. Some prefer to exit SAS and start over. If you do, just remember to save your program before exiting.

An unmatched comment Unmatched comments can cause SAS to stop in the middle of a program, much like unmatched quotation marks. The problem is that SAS can’t read the entire program because part of it is accidentally stuck in a comment. This isn’t so likely to happen if you use the kind of comment that starts with an asterisk and ends with a semicolon since programs contain many semicolons, and any semicolon will do to end a comment. But if you use the style of comment that starts with /* and ends with */, and you forget to include the last */, then SAS will assume that the remainder of your job is one long comment. The solution, in batch or noninteractive mode is to insert the missing end-of-comment and resubmit the program. In the SAS windowing environment, the solution is to submit a lone end-of-comment like this:
*/; RUN;

Then edit your program, correct the problem (remembering to delete the extra end-of-comment and RUN statement at the end), and rerun the program. Some prefer to exit SAS and start over. If you do, just remember to save your program before exiting.

Chapter 10: Debugging Your SAS Programs

279

No RUN statement at the end of a program This problem occurs only in interactive SAS. In non-interactive or in batch mode there is an implicit RUN statement at the end of every SAS job. The problem is that in interactive mode SAS has no way of knowing when it is time to execute your last step unless you tell it with a RUN statement. The solution is to submit the wayward statement:
RUN;

Not sure what the problem is? If you are working in the SAS windowing environment, and you think you have an unmatched quotation mark, unmatched comment, or missing RUN statement, but you’re not sure, you may want to submit the following set of statements:
*'; *"; */; RUN;

Together these statements form a sort of universal terminator for SAS programs. If the program has no problems, these statements do nothing since the first three would then be comments, and an extra RUN statement between steps does nothing. That means you can submit these without fear of causing any harm.

Out of time Batch systems often have time limits, measured in CPU seconds, for computer jobs. These limits are set locally by your systems programmers. And these limits are helpful because they allow small jobs to be submitted to a special queue with a higher priority. That way your short job doesn’t have to wait for some mega-job to finish processing. Time limits may also be set to stop jobs that accidentally get into an infinite loop. If your job stops in the middle, and you are running in batch mode, and you can find no unmatched quotation marks or comments, then you should consider whether your job might have stopped because it ran into a time limit. To find out how to fix this problem, talk to your local SAS Support Consultant or systems programmer. /* in the first column Under OS/390 or z/OS there is a unique hazard. Recall that one style of SAS comment starts with a slash-asterisk (/*). Batch jobs under OS/390 or z/OS use Job Control Language (JCL). In JCL a /* starting in column one signals the end of your program file. So if SAS programmers start a comment with a /* in column one, they inadvertently instruct the computer to stop right then and there. SAS never even sees the remainder of the job. The solution, of course, is to move the comment out of column one or to change to a comment starting with an asterisk (*) and ending with a semicolon (;).

280

The Little SAS Book

10.15 SAS Runs Out of Memory or Disk Space
What do you do when you finally get your program running, and you get a message that your computer is out of memory or disk space? Well, you could petition to buy a more powerful computer, which isn’t really such a bad idea, but there are a few things you can try before resorting to spending money. Because this issue is very system dependent, it is not possible to cover everything you might be able to do in this section. However, this section describes a few universal actions you can take to remedy the situation. If none of these things work, then seek out your site’s SAS Support Consultant for advice. It is helpful, in trying to solve the problem, to know why it happens. Usually when you run out of memory, it’s when you are doing some pretty intensive computations or sorting data sets with lots of variables. The GLM procedure (General Linear Models), for example, can use lots of memory when your model is complicated and there are many levels for each classification variable. You run out of disk space because SAS uses disk space to store all its temporary working files, including temporary SAS data sets, and the SAS log and output. If you are creating many large temporary SAS data sets during the course of a SAS session, this can quickly fill up your disk space.

Memory and disk space One thing you can do to help decrease disk storage is decrease the number of bytes needed to store data. This can also help memory problems that arise when sorting data sets with character data. Since all numbers are expanded to the fullest precision while SAS is processing data, changing storage requirements for numeric data will not help memory problems. Both character (if you are using list input), and numeric variables have a default storage requirement of eight bytes. This works for most situations. But if memory or disk space is at a premium, you can usually find some variables which require fewer bytes.
For character data, each character requires one byte of storage. The length of a character variable is determined by one of the following: the INPUT statement, the LENGTH or ATTRIB statement, or, if it is created in an assignment statement, the length of the first value. If you are using list input, then variables are given a length of eight. If your data are only one character long, Y or N for example, then you are using eight times the storage space you actually need. You can use the LENGTH statement before the INPUT statement to change the default length. For example, the following gives the character variable Answer a length of one byte:
LENGTH Answer $1;

If you are using column input, then the length is equal to the number of columns you are reading; if you are using formatted input, then the length is equal to the width of the format. You can change the lengths of variables in existing SAS data sets by using a LENGTH statement between a DATA statement and a SET, MERGE, or UPDATE statement.

Disk space If you are running out of disk space, in addition to shortening the lengths of character variables, you may also be able to decrease the lengths of numeric variables. Numeric data are a little trickier than character when it comes to length. All numbers can be safely stored in eight bytes, and that’s why eight is the default. Some numbers can be safely stored in fewer bytes, but which numbers depends on your operating environment. Look in the SAS Help and Documentation for your operating environment to determine the length and precision of numeric variables. For example, under Windows and UNIX, you can safely store integers up to 8,192 in three bytes. In general, if your numbers contain decimal values, then you must use eight bytes. If you have small integer values, then you can use four bytes (in some operating environments two or three bytes). Use the LENGTH statement to change the lengths of numeric data:

Chapter 10: Debugging Your SAS Programs

281

LENGTH Tigers 4;

This statement changes the length of the numeric variable Tigers to four bytes. If your numbers are categorical, like 1 for male and 2 for female, then you can read them as character data with a length of 1 and save even more space. Another thing you can try if you are running out of disk space is to decrease the number and size of SAS data sets created during a SAS session. If you are going to use only a fraction of your data for analysis, then subset your data as soon as possible using the subsetting IF statement. For example, if you needed observations only for females, then use the following statement in your DATA step:
IF Sex = ’female’;

If you need to look at only a few of the variables in your data set, then use the KEEP= (or DROP=) data set option to decrease the number of variables. For example, if you had a data set containing information about all the zoo animals, but you wanted to look at only the lions and tigers, then you could use the following statements to create a data set with only the Lions and Tigers variables:
DATA partial; SET zooanimals (KEEP = Lions Tigers);

The SAS log and output also take up disk space. If you are using the SAS windowing environment, then clear the SAS log and output often. It is also possible to compress SAS data sets. Compressing may save space if your data have many repeated values. But beware, compressing can in some cases actually increase the size of your data set. Fortunately SAS gives a message in your log window telling you the change in size of your data sets. You can turn on compression by using either the COMPRESS=YES system option, or the COMPRESS=YES data set option. Use the system option if you want all the SAS data sets you create to be compressed. Use the data set option when you want to control which SAS data sets to compress. For example:
DATA compressedzooanimals (COMPRESS = YES); SET zooanimals;

If you have more than one disk on your system, then you might be able to have SAS store its working files in a different location where there is more space. See the SAS Help and Documentation for your operating environment, or check with your site’s SAS Support Consultant for more information on how to do this.

Memory If memory is your problem, then do what you can to eliminate other programs that are using your computer’s memory. If you are using a windowing environment to run your SAS programs, try running in batch or non-interactive mode instead. The windows take quite a lot of memory, and it can be a significant fraction of the total available memory. Also, see the SAS Help and Documentation for your operating environment for potential ways to make more memory available on your system. If you have tried all of the above, and you are still running out of memory or disk space, then you can always try finding a more powerful computer. One of the nice things about SAS is that the language is the same for all operating environments. To move your program to another operating environment, you would only need to change a few statements like INFILE, which deal directly with the operating environment.

‘‘

Where observation is concerned, chance favors a prepared mind.

’’

LOUIS PASTEUR

From The Oxford Dictionary of Quotations 5th edition, edited by Elizabeth Knowles, copyright 1999 by Oxford University Press.

APPENDICES
A B C D E F

8
284 286 288 291 298

Where to Go from Here

Getting Help from SAS Technical Support An Overview of SAS Products Coming to SAS from SPSS

Coming to SAS from a Programming Language Coming to SAS from SQL 302

284

The Little SAS Book

Appendix A Where to Go from Here
The goal of this book is to get you started using SAS and to teach you basic principles of SAS programming. For some of you, this book may be all you need. Others, however, may need to go beyond this book. This section lists sources for other training and information about SAS software. Contact SAS for more information on any of the following items. You may also have additional sources of information, developed locally, at your site. Check with your site’s SAS Support Consultant for more information.

The SAS Web Site
Like most companies these days, SAS has a very useful Web site. You can find all sorts of information there: news and events, answers to frequently asked questions (FAQ), technical information, product descriptions, publications information, training information, documentation—the list is almost endless. If you have a question, and can’t find the answer in this book, then try the SAS Customer Support Center Web site: support.sas.com

SAS Help and Documentation
Beginning with SAS 9, SAS Help and Documentation is available from within your SAS session, and can be accessed through the Help pull-down menu or by typing the word HELP in the command line area on your display. SAS Help and Documentation is your complete reference material for SAS and gives you access to tutorials, sample programs, general information, and specific syntax. SAS Help and Documentation includes material for all products and operating environments. Prior to SAS 9, the documentation accessible through Help is less comprehensive but is complemented by the SAS OnlineDoc.

SAS OnlineDoc
SAS OnlineDoc is a stand-alone version of the SAS documentation. You do not need to be running SAS to view the documentation in this format. SAS OnlineDoc is available in HTML format that can be installed on a local Web server, or your own workstation. Or, you can register to access it though the SAS customer support Web site. You can also purchase a PDF version of SAS OnlineDoc, from which you can make hard copies of the documentation.

SAS Manuals
SAS publishes manuals in hard copy, digital, and CD-ROM formats covering topics from getting started guides to reference manuals. The best source for an up-to-date listing of SAS manuals is the SAS Publishing Web site.

Books by Users
There are many titles in the Books by Users series offered by SAS. These books are written by users of SAS software, and thus offer a different perspective from the SAS documentation. Topics range from very general and introductory to very specific. Some Books by Users are listed at the end of this book and a complete listing can be found through the SAS Publishing Web site.

SAS Online Tutor
SAS Online Tutor is a SAS training product that can be licensed on an annual basis and installed on your system. SAS Online Tutor is highly interactive and covers a broad range of topics from a

Appendices

285

general introduction to specialized areas. Or, you can access it through the SAS Training Web site for 60 or 90 day periods.

SAS Training Courses
SAS offers courses on SAS software covering many topics and varying in length and cost. You can also arrange to have on-site training for many of the courses. In addition to the instructor-based courses, SAS also offers video-based courses. Contact SAS for more information about either of these training opportunities through the SAS Training Web site.

SAS User Groups
SAS has a network of user groups which spans the globe. There are in-house groups, local groups, and regional and international groups. The regional and international groups generally meet once a year for several days. Presentations and demonstrations are given by users and SAS employees; there are workshops and training opportunities and usually vendor exhibits. SAS Users Group International (SUGI) is the largest user group. Local and in-house groups usually meet more frequently for a shorter duration. These user-group meetings can be a great source of information about SAS software. More information about SUGI and the regional user groups can be found at the SAS Customer Support Center Web site.

SAS Com magazine and Electronic Newsletters
The SAS Com magazine is available to all SAS users at no extra cost. It covers news items like capabilities of new releases of SAS software, has articles of general interest, and has some technical information. Also, SAS publishes several electronic newsletters including Your SAS Business Report for business and industry decision-makers and executives and Your SAS Technology Report for SAS software users, systems administrators, and IT staff. All of these publications can be accessed through the SAS Publishing Web site.

SAS-L
SAS-L is an independent electronic mailing list of SAS users all over the world. This group helps subscribers solve SAS problems, discusses SAS philosophy, posts announcements, and discusses whatever else seems related to SAS. Contact your site's SAS Support Consultant for information on how to subscribe to this high-volume list.

SAS Technical Support
If you are really stuck on a SAS problem, you can contact SAS Technical Support. The various ways of contacting SAS Technical Support are covered in Appendix B.

286

The Little SAS Book

Appendix B Getting Help from SAS Technical Support
Sooner or later you will come up with a question for which you can't find the answer. With some software companies, very little technical support is available, or the support is available but only for an extra charge—not so with SAS. SAS has a policy of “free, unlimited support to all sites 1 licensing software from SAS.” In addition, SAS’s low employee turnover means better, more knowledgeable service for users. There are several ways to contact Technical Support including Web site, e-mail, telephone and fax. Before you contact Technical Support, you must know certain information: your site or customer number, the release of SAS you are using, and the name of your operating environment. To find out your site number and release of SAS, run a SAS program, any SAS program, or just start interactive SAS. Then look at the beginning of your SAS log to find your site number and release notes.

Technical Support Web site If you using the SAS windowing environment and you are connected to the Internet, you can access the Technical Support Web site with a few clicks of a mouse. With SAS running, just select SAS on the Web from the Help pull-down menu and then select Technical Support. You can also connect to Technical Support’s Web site via the SAS Customer Support page: support.sas.com From the Technical Support Web site you can browse tables of Frequently Asked Questions (FAQ), access sample programs, search release notes for known problems, FTP files, and find other helpful information. If you can’t find the answer to your question, you can contact a person in Technical Support through the Web site.

E-mail You can also submit problems to Technical Support via the Electronic Mail Interface to Technical Support (or EMITS), by sending a message to support@sas.com However, e-mail messages sent to this address must be in a specific format. That’s why submitting your question via the Web site is so easy—it puts your message in the correct format for you. If you wish to submit a problem by e-mail, it must be in the following format:

The SAS Learning Edition is not licensed. If you are using the SAS Learning Edition, you cannot use the “live” technical support described in this section. However, you still have the online documentation provided with the SAS Learning Edition, and the SAS Learning Edition Web site (www.sas.com/LE) to help you learn more about SAS.

You just replace the arrows and descriptions with your information. For example,
To:support@sas.com From:mwong@xyzinc.com Subject:PROC TABULATE problem name=Mary Wong site=0098541001 company=XYZ, Inc. phone=+1(916) 123-4567 product=Base SAS procedures release=V9 os=Win XP When I set a variable header equal to blank in a LABEL statement, it doesn’t work.

Telephone and fax The traditional way to contact Technical Support still works well. Customers in North America can use these numbers:
Voice: (919) 677-8008 between 9 a.m. and 8 p.m. Eastern time on weekdays Fax: (919) 677-4444 Customers outside North America should contact their local SAS office. To find contact information (phone numbers, mailing addresses, and Web sites) for SAS offices outside North America, use the Technical Support Web site.

288

The Little SAS Book

Appendix C An Overview of SAS Products
SAS licenses many different products. This book covers elements from Base SAS software, SAS/STAT software, and SAS/ACCESS for PC Files software. You can see from the following list that there is much more to SAS than just these products. Fortunately, most of the products are integrated, so you don't have to convert data sets or start up another program to use the other products. The following is a partial list of SAS products with brief descriptions. Since the number of SAS products is constantly changing, check the SAS Web site (www.sas.com) for a current list. You must have Base SAS software installed on your system to run most of these products. Not all products are available for all operating environments. Contact SAS for more information on any of the products:

Base SAS must be installed on your system to run most of the other SAS products. Base SAS software includes the DATA step for manipulating your data and simple statistical and utility procedures.

SAS/ACCESS allows you access to data used by other software packages. You can read and, in some cases, write data in their native formats without having to leave SAS. Most of the popular database software is supported, and each has its own SAS/ACCESS product.

SAS/AF allows you to write your own interactive SAS applications. Applications written with SAS/AF software allow users quick-and-easy access to information without knowing the SAS language.

SAS/ASSIST is a menu-driven front end to SAS software. You make choices from menus, and SAS writes the program for you. Programs can be stored for later use.

SAS/C is a C and C++ development environment for IBM mainframes.

SAS/CONNECT connects computers running SAS software. Data can be shared between the computers, and programs developed on one computer or operating environment can be transferred to another for processing.

SAS/EIS allows you to develop and use custom executive information systems. Managers can use the EIS interfaces to SAS to quickly get the information they need by simply pointing and clicking (with a mouse, of course).

SAS Enterprise Guide is a graphical user interface to many parts of SAS software. This is a Windows only product, but can be used to access SAS servers on other systems.

SAS Enterprise Miner is a complete product in itself. It provides an easy-to-use front-end to the SEMMA (Sample, Explore, Modify, Model, Assess) process for business users.

SAS/IntrNet allows you to effectively deliver your SAS applications to the Web.

SAS/LAB is for guided statistical analysis. This product is good for people who need to analyze data but do not have a background in statistics.

SAS/MDDB Server allows you to save data in multidimensional database (MDDB) formats for use with online analytical processing (OLAP) (otherwise known as slicing and dicing your data).

SAS OLAP Server provides the components that you need to perform multidimensional analysis.

SAS OLE DB Providers consists of interfaces that can read data from a variety of sources using the OLE Component Object Model (COM). SAS OLE DB interfaces provide a standard by which applications can uniformly access stored data located in a variety of sources.

290

The Little SAS Book

SAS Online Tutor is an online tool for learning SAS. There are lessons covering many different aspects of SAS.

SAS Open OLAP Server enables you to access multidimensional data (for example, an MDDB) stored in SAS from an external source. The SAS Open OLAP Server supports the Microsoft Corporation’s OLE DB for OLAP API.

SAS/OR provides procedures for project management and operations research such as linear programming, Gantt charts, activity networks, and decision analysis.

SAS/SECURE provides encryption services to increase the security of transmissions across a network. SAS/SECURE software makes use of the cryptographic services provided by RSA’s Bsafe and Microsoft’s CryptoAPI ciphers and is subject to export regulations.

SAS/SHARE provides concurrent access to data by multiple users.

SAS/SPECTRAVIEW is a tool for analysis and visualization of three-dimensional data.

SAS/STAT has procedures for most types of statistical analyses including many forms of regression and analysis of variance.

SAS/Warehouse Administrator simplifies the creation and maintenance of data warehouses.

Appendices

291

Appendix D Coming to SAS from SPSS
More often than not, the first question asked by people who know SPSS and want to learn SAS is, “How do the two software packages compare?” No simple answer is possible since both products are continually evolving, with new releases introducing new capabilities. Nonetheless, general comparisons can be drawn. SAS and SPSS are very similar. Compared to other statistical software, these two products are similar because they are both based on languages. Most other statistical packages are comparatively rigid, lacking the flexibility of a language. Compared to other computer languages such as C, SAS and SPSS are similar because of their powerful, built-in data handling and statistical capabilities. Some SPSS users may not even know that SPSS has a programming language since many SPSS users use only the SPSS point-and-click interface. If you are one of these people, then you will be glad to know that SAS also has a point-and-click interface. You should try SAS Enterprise Guide or the Analyst application (section 8.9). If you are a programmer, you’ll be glad to know that SAS gives you a choice of modes. You can write your program in a menu-driven interactive system, or you can write your program with an editor and submit it non-interactively or in batch. Despite their fundamental similarities, SAS and SPSS have different styles. SAS is more diverse, especially when you consider the entire family of SAS products. Appendix C contains a partial listing of SAS products at the time this book was written. Most of these products are integrated, so they can be used seamlessly with Base SAS software. SAS has more options. More options mean more power to get exactly what you want. Likewise, SAS gives you more power to choose the format of your output, including HTML, XML, PDF, PCL, PostScript, LaTeX, Troff, text, and CSV, in addition to writing data for spreadsheets and databases. People who do really complex programming find they can do things with SAS that would be impossible to do with SPSS.

Terminology Some vocabulary differences exist between SAS and SPSS. To help you translate from one language to the other, here is a brief dictionary of analogous terms: SPSS term Analogous SAS term active file no analogous term no analogous term temporary SAS data set (also called a table) case observation (also called a row) command statement file handle libref function function input format informat numeric data numeric data output format format procedure procedure save file permanent SAS data set (also called a table) SPSS data file permanent SAS data set (also called a table) string data character data syntax statements syntax file a program system file permanent SAS data set (also called a table) value label user-defined format variable variable (also called a column) variable label label no analogous term DATA step no analogous term PROC step

292

The Little SAS Book

Active files The concept of an active file in SPSS has no equivalent in SAS. When you read data in an SPSS program, SPSS creates an active system file. This active file is similar to a temporary SAS data set because it exists only for the duration of the SPSS session, just as temporary SAS data sets exist only for the duration of a SAS session. However, SPSS has only one active file at a time, while SAS can have any number of temporary or permanent data sets. When you run an analysis in SPSS, the data must come from the active file. When you run an analysis in SAS, by default SAS will use the data set most recently created. But you can easily use any other SAS data set including the permanent SAS data set you created last year and haven't touched since. All SAS data sets are always active. DATA and PROC steps The SAS language has some concepts that have no parallel in SPSS, such as DATA and PROC steps. All SAS programs are divided into these two types of steps. Basically, DATA steps read and modify data while PROC (short for procedure) steps perform specific analyses or functions such as sorting, writing reports, or running statistical analyses. SPSS programs do the same types of operations but without distinct steps. Windows When you start SPSS 12.0 (the current release at the time this was written), you see the SPSS Data Editor window. From there you can type in data or open an existing data set. You can also select File-Open-Syntax from the menus to open the SPSS Syntax Editor so you can type in syntax or open an existing program. SAS has similar windows, but the order is reversed. You see the Editor window automatically, and can open the data editor (called Viewtable) by selecting Tools-Table Editor from the menus. Here are what the two data editor windows look like when you first open them.

Examples For a comparison, we provide the following two programs that perform the same operations in SPSS and SAS. We used SPSS 12.0 and SAS 9, both running in the Windows operating environment. A radio station commissioned a market research company to survey listeners. Respondents were asked to listen to songs and rate them on a scale of 1 to 5, with 1 being “dislike

Getting SPSS system files into SAS SAS can read SPSS data files directly. To do this you use a LIBNAME statement with this form:
LIBNAME libref SPSS 'filename';

After the keyword LIBNAME, you put the libref which is a nickname you make up for your file (similar to an SPSS file handle), then put the option SPSS followed by the actual name of your SPSS system or portable file. The SPSS option tells SAS to use the SPSS engine (instead of the default SAS data set engine) to read your data set. SAS can read SPSS data files (compressed or uncompressed) created in the same operating environment in which you are running SAS, or SPSS portable data files created in any operating environment. When SAS reads SPSS files, SAS preserves as much as possible. Variable names, variable labels, print formats, and the data remain the same. SPSS missing values become SAS missing values. SPSS value labels are not copied because the SAS equivalent, user-defined formats, are not stored in SAS data sets. If you want value labels, you can create user-defined formats with PROC FORMAT and then use them with FORMAT statements. See section 4.7 for an explanation of how to do this.

Example The following SAS program reads the SPSS file created by the SPSS program in the preceding example. The SPSS file, named survey.por, was saved in SPSS as a portable file using menus (Select File-Save as and use the SPSS portable file type). The LIBNAME statement tells SAS to use the SPSS engine to read the file.
LIBNAME myspss SPSS 'c:\MySPSSLib\survey.por'; * Print the SPSS portable file; PROC PRINT DATA = myspss.getsurv; * List the contents of the SPSS portable file; PROC CONTENTS DATA = myspss.getsurv; * Convert SPSS portable file to SAS data set; DATA 'c:\MySASLib\sassurvey'; SET myspss.getsurv; RUN;

First, SAS prints a copy of the SPSS portable file with PROC PRINT. Then, SAS prints a report describing the portable file with PROC CONTENTS. Last, the DATA step copies the SPSS portable file into a permanent SAS data set named SASSURVEY in the MySASLib directory: In this example, the name that SAS uses for the SPSS system file is MYSPSS.GETSURV. MYSPSS is the libref assigned to the SPSS portable file in the LIBNAME statement, and GETSURV is the member name. You can use any name you wish for the libref as long as it follows the rules for valid SAS librefs (eight characters or shorter; starts with a letter or underscore; and contains only letters, numerals, or underscores). Since SPSS files don't have internal names and never contain more than one data set, you can also use any name for the member name.

Appendix E Coming to SAS from a Programming Language
You can write SAS programs that do many of the tasks that standard programming languages like C++, FORTRAN, and Visual BASIC can do. There are many similarities between SAS and these languages, but there are some important differences. If you are used to programming with these types of languages, learning SAS will be easier if you remember the differences.

Built-in loop The major difference is that SAS has a built-in loop for data handling. If you read data from a file, or process SAS data sets in the DATA step, SAS automatically loops through all the data. In a standard programming language, you typically need to set up an array to hold the data, then use a loop (DO, WHILE, or FOR) to process the array. You may need to know how many data elements are in the file, or check for end-of-file markers. The DATA step in SAS automates this.
While SAS processes all the data, it sees only one observation at a time. All the statements in a DATA step operate on only one observation at a time. In a standard programming language, you can see all the observations at once, by referencing the appropriate array subscript. In SAS you can simulate this using LAG functions or other techniques, but you will find that it is seldom necessary.

Loops DO loops are present in SAS, but you must keep in mind that a DO loop in SAS is executed with each pass through the DATA step. So if your loop has 6 iterations, and you have 10 observations in your data set, the statements inside your loop will be executed 60 times—6 times for each of the 10 observations (assuming the INPUT or SET statement is not inside the loop). The built-in loop in SAS, in essence, puts a loop around your entire DATA step. Because of the built-in loop, arrays and DO loops are not used nearly as often in SAS programs as they are in other languages. Arrays SAS does have arrays, but they are used differently from the way they are used in standard programming languages. An array in SAS consists of variables. You use arrays when you want to do the same thing to each variable in the array, and you don’t want to write a separate statement for each variable. Arrays are temporary in SAS, existing only for the duration of the DATA step in which they are defined. Arrays provide ways to shorten and simplify your SAS programs.

Appendices

299

Functions SAS has many functions available that help simplify your programming tasks. Functions in SAS are used in DATA steps and, therefore, operate within an observation. If you want to find the minimum value for an observation across a group of variables, for example, you would use the MIN function. SAS has many functions available in the following categories: character, date and time, financial, mathematical, probability, random number, sample statistics, state and ZIP code, trigonometric and hyperbolic, and truncation. Procedures While functions operate across variables, SAS procedures operate across observations. If you want to find the minimum value for a variable across all observations, then use PROC MEANS. SAS procedures can do a lot in just a few statements. Results from procedures are nicely formatted and you don't have to worry about how many decimal places to print, or where to put the results on the page. A simple PROC PRINT statement, for example, will print all the data in your SAS data set, fit as many variables as it can on a page, decide on the best format for each variable, and label each variable at the top of every page. But, SAS is flexible, so if you don't like the way SAS printed your results, you can change it. Data types Another difference between SAS and many other languages is that SAS has only two types of data: numeric and character. All numbers in SAS are assumed to be double-precision floating-point values. You don't have to declare what type of numbers you are using. You can, however, change the number of bytes used to store data using the LENGTH statement. The default length is 8 bytes, which safely stores all numbers. If you are using small integer values, you might be able to use a length of 4 or fewer depending on the computer and operating environment you are using. The SAS documentation for your host will tell you which numbers you can safely store in how many bytes. Program structure Many programming languages are particular about the layout of programs. In FORTRAN, for example, any character in column 6 indicates that the line is a continuation of the previous line. SAS has no restrictions on program layout. A statement can be indented, split on many lines, or on the same line as other statements. SAS simply reads a statement from one semicolon to another. In addition, SAS statements are not case sensitive. Compilation and execution Most programming languages have separate compile and execute phases. SAS does have separate phases, but when you submit a SAS program it automatically compiles and executes. It is possible however, to save compiled SAS DATA steps and macros if you want.

300

The Little SAS Book

Comparison of a SAS program to a C++ program The following compares a SAS program to a C++ program. Each program reads the following data from a file and prints it. The data file has three columns for the students' names, ages, and grade-point averages:
Mary Bob Scott Marie Ruth 19 20 22 18 20 3.45 3.12 2.89 3.75 2.67

Similar Documents

...PCSX2 1.2.0
Readme
Overview
PCSX2 is a PlayStation 2 emulator for Windows and Linux, started by the same team that brought you PCSX (a Sony
PlayStation 1 emulator).
The PCSX2 project attempts to allow PS2 code to be executed on your computer, thus meaning you can put a PS2
DVD or CD into your computers drive, and boot it up!
The project has been running for nearly 10 years now, and since its initial release has grown in compatibility. From
initially just being able to run a few public domain demos, its current state enables many games to boot and actually
go in game, such as the 'famous' Final Fantasy X, Devil May Cry 3 and God of War. You can always visit the PCSX2
homepage to check the latest compatibility status of games with more than 2000 titles tested.
Following our new release scheme as described here, v1.2.0 is an official, stable release.
What's new in 1.2.0?
Windows
Core:
•
microVU fixes for Dreamworks games, later Tony Hawks games, Evil Dead and others.
•
Fixes to New GIF unit to solve regressions
•
microVU bugs fixed (affecting Extreme-G Racing and others)
•
CDVD fixes (Impossible Mission now boots)
•
Path 3 arbitration and timing refinements
•
MFIFO fixes for DDR games
•
Huge DMAC bug fix solving most of the problematic videos. (Baldurs Gate 2, Katamari Damacy and more)
•
Memorycard support improved in many games, now supports PSX memorycards also
•
Multitap support improved......

...Conceptualizing a Business
Isabel Lopez
Larry Shipley
BUS/475
August 25, 2011
Coffee House, Business Mission
SA Novel Beans is an exclusive bookstore plus coffee house mixture opening in the downtown area of San Antonio, Texas. SA Novel can be located on a fine trafficked street straight in main tourist area of San Antonio. The café is surrounded by the Market downtown. The society is complete with shops, restraints, bars, and companies that are geared in the direction of the ample university students and tourist that walk freely in this area. University of Texas at San Antonio, San Antonio College, and not to mention the University health science center and a mixture of all around the world tourist make up a wonderful combination of consumers for SA Novel Beans. A large mass of these students rely on bicycles, mopeds or walking to obtain to classes and their employment, and most of them go across the downtown shopping areas on an every day or weekly basis. Tourists most often walk to be able to look at the beauty that San Antonio has to offer.
SA Novel Beans offer an additional reason like a bookstore to attract the students’ population. “Most of the Coffee shops in the area are either chain locations such as Starbucks, or they are very alternative locations that border on hippy in nature, which might not be conductive to every consumer’s taste” (Evonson,2007). The SA Novel Beans is a very comfortable, clean, and good environment to enjoy snack as well as......

...TATTOO MANIA! (An A-Z of Flash Tattoos)
A proposed book illustration and its promotion
A Thesis presented to the
College of Fine Arts and Design
UNIVERSITY OF SANTO TOMAS
In Partial Fulfillment of the Requirement for the
Degree of Bachelor of Fine Arts
Major in Advertising
By
Ma. Minerva Minnehaha V. Capco
INTRODUCTION
Although our country still remains conservative as compared to the West, the prevalence of Skin Art here in the Philippines is still unstoppable.
Filipinos of the latest generations have gradually started opening up to embrace a whole new subculture---a subculture that is more experimental with art, music and sports. Crews and crews of Graffiti artists as well as Skaters are flourishing, Local bands are reaching new heights, and of course, the Industry of Tattooing is growing by the minute.
The word tattoo was said to have two major derivations. From the Polynesian word “Ta” which means “to strike something” and from the Tahitian word “Tatau” which means “to mark something”.
Archaeologists across the globe have unearthed preserved corpses and mummies that are tattooed. These mummies are said to have lived thousands of years ago, and most of the bodies bore tattoos that signify their cultures, ranks and beliefs. According to research, tattooing has been in activity to many countries such as Japan, Egypt, China, Polynesia, New Zealand, Indonesia, India, Thailand, Africa, Ancient Greece and Rome,......

...Memorandum
To: Head of Financial and Internal Control
From: Group Learning Team A
Date: 10/13/2014
Re: Challenges Communicating Accounting Changes
The issuance of SAS No. 112 in 2006 and SAS No. 115 in 2009 by the AICPA created the need to communicate significant audit procedure changes to our clients, as well as to our own firm accountants. SAS No. 115 supersedes SAS No. 112. Due to SAS No. 115, significant changes need to take place in order to comply with the new accounting principles. Specifically, internal company controls have become a major focus of the standard audit procedures. Each of the three groups experienced certain challenges regarding the requirements of the new directive. Specifically:
1- Firm Accountants - The new audit requirements has compelled our audit staff to redesign our traditional procedures on issues outside the financial statements. Our staff maintains a high competency regarding the financial statements themselves, but the requirement to review company financial controls and procedures has significantly changes and requires us to reinforce our staff training as many of the younger staff are confused. The younger staff has little experience with how companies run operationally, and they are now being required to judge the quality of these operations. A series of training regarding best practice financial controls is recommended to bolster the staff's ability to complete the audits per the new directive.
2- Clients - The new...

...increasingly in government schools (Cavendish, 2006).
http://books.google.com.sg/books?id=bl36oP9be8cC&pg=PA292&dq=maldives+language&hl=en&sa=X&ei=UK4VT8j5L42urAeI4pSKAg&ved=0CEkQ6AEwBA#v=onepage&q=maldives%20language&f=false
Education
According to research, “The Maldives has a functional literacy rate of 98%, which is the highest in the South Asia and Indian Ocean region. Educational standards are also among the highest in the region and schools follow the British system of education. English language is used as the medium of instruction in most schools; however, there are schools that provide Arabic and Islamic education specifically” (Government of Western Australia)
Studies have shown that education is the priority in the Maldives (Ferguson & Marlow, 2002). Pre-school education in Maldives exists mainly in the form of the Koranic schools where the purpose is to study the Koran in Arabic. Formal education continues after that in traditional koranic schools, Divehi-medium primary schools or increasingly in English-medium primary schools (Eur, 2003). However, there are no universities in Maldives except for colleges and institutes that teach technical skills. Those that want to further study have to go overseas for further education (Cavendish,......

...fabulous. Other terms with the same meaning, which he typically uses, are "havey" and "palong palo."
Sample: "Sa lahat ng unkabogable na madlang people, maraming maraming salamat sa inyong suporta!"
"Thunders"
No it's not the loud rumbling or crashing noise heard after a lightning flash, it's what Vice calls old people, which comes from the Filipino term "matatanda."
Sample: "Nakakatawa ang grupo ng mga thunders na nakasabay ko sa elevator kanina, ang saya lang nila."
"Severe"
Although, in a normal setting the word usually connotes an unfavorable situation, for Vice, "severe" has been transformed into an expression that means "super" or "fierce."
Sample: "Ang bongga lang nang severe ng costume ng mga tao kagabi sa Halloween party na pinuntahan ko."
"Echosera"
Again this is not his original term, but this gay speak for a "liar" or a "ridiculous flatterer" has been part of his daily commentary as "Showtime" mainstay hurado and has also been, in fact, picked up by his co-hosts like Anne Curtis and Karylle.
Sample: "Napaka echosera mo lang Ate, fan ka na agad ni Kuya Kim eh ngayon mo lang siya nakita."
"Eksaherada"
Does it sound like the Filipino translation of the word exaggerated? Well, it’s because that's what it exactly means. The only difference is that Vice enunciates the last syllable in an exaggerated crescendo tone.
Sample: "Eksaherada ang traffic kanina sa EDSA kaya ako na-late!"
"Saveh"
It may sound like "Pirates of the Caribbean" Jack Sparrow's favorite......

...Scott Perreault
December 5, 2012
Assimilation or Humiliation
In “The School Days of an Indian Girl” written by Zitkala Sa, we are thrust into the issues confronting the Native American population. White European culture was the controlling force in this era of misunderstanding and ethnocentricity. They felt threatened by a culture they did not understand, and so in response and a need to alleviate the pain of their insecurity, they required that the young Native American be assimilated into the ways of the White. The narrator who is immersed in this unreal reality is forced to submit, to resist is futile. The innocent girl from the reservation becomes a success story to the white man, but in doing so is alienated from family.
The dreamlike excitement of the train journey to the school would soon become a nightmare of sorts for her and her companions. It took very little time to discover that this was not her land, and her habitation here only aroused suspicion and mistrust. Sa writes, “I had arrived in the land of rosy skies, but I was not happy, as I had thought I should be” (Zitkala Sa, 1140). It is evident here that although the landscape is quite appealing and pleasant to the senses, she realizes that beauty is skin deep, and what lies beneath is an affront to her. For her everything is foreign; no sense of familiarity to envelop her, but her spirit did stay intact.
From time to time, her anger exuded the rebellious spirit within. “With fire in my heart, I took......

...Olivia Blankenship
Dr. Lawrence
Introduction to Humanities
7 July 2014
Cleopatra
Hardly any personalities from the Hellenistic period (323 BC – 31 BC) are as renowned as Cleopatra VII (69 BC – 30 BC), the Egyptian queen. The focus of a wide array of Western historical texts, music, poems, literature, and arts, Cleopatra has been widely portrayed as a Queen who ruled her subjects and her Roman lovers through sex and gender. Despite such portrayals, very little is known about Cleopatra and there are doubts among historians that such accounts are an inaccurate depiction of Cleopatra. This paper will research studies on Cleopatra to determine whether the accounts of her ruling through sexual liaisons are accurate or they are propaganda developed to tarnish her impeccable reputation.
The argument among scholars is that most of the accounts that currently depict Cleopatra VII as a Queen who used sex and gender to rule are erroneous. Roller argues that those accounts are the consequence of a perverse male-dominated historiography out to depict her as an extension of men in her life (2). According to Roller, modern and ancient male-dominated historiographies betray their chauvinistic attitudes towards Cleopatra in the manner in which they portray her primary accomplishments as the destruction of her male lovers (2). Such portrayals were necessary because of their effectiveness in discrediting Cleopatra’s achievements.
Roller and Salisbury’s......

...go. They will attend once, twice or for a month but later on they will decide to leave. Bakit kaya ito nangyayari sa ating mga iglesya, and we cannot deny the fact the it is also happening here in our church.
Sa Panahon natin ngayon one of the things na nararamdaman natin eh yung feeling of belongingness... we want to be belong to something or in something.
Most of the time we feel na parang OP tayo sa isang lugar na kung saan bago tayo. Mahirap kung sa church nararanasan ito ng mga bisita or even ng mga attendees, sometimes kahit members pa. Ang cause…kasi dahil yung ilan sa atin familiar na sa isa't - isa, na neneglect na natin na may iba pa pala tayong kasama. so they feel that they don't belong to this group. Or there are times instead na peace and comfort yung nararamdaman nya sa pagdalo sa isang bahay sambahan eh kabaligtaran ang nararamdaman niya.
We must not treat this topic as an ordinary topic, but my prayer is that God will touch our hearts and will enable us to understand and place it in our heart and able to practice it for real.
Our topic for today is... I Belong to God's family.
Hindi ba at napakagandang pakinggan sa isang mananampalataya pag may nagtanong ng ganito: "san ka nag-chuchurch?" ang sagot niya ay... "sa LCC, where I belong." It is a wonderful tagline for us... LCC Where I belong!
Sana yun ang nararamdaman ng bawat isa sa atin na naririto na for 5 years and for our visitors (Ask them to stand up and acknowledge their presence) sana......

...The Fraud Triangle
Abstract
In 2002 SAS No. 99, Consideration of Fraud in a Financial Statement Audit describes the difference between material misstatements due to errors and intentional fraud and defines two types of intentional fraud: fraudulent financial reporting and misappropriation of assets. SAS No. 99 also introduced D. R. Cressey’s theory of the fraud triangle which is so named because it consists of three conditions that are generally present when fraud occurs: incentive/pressure, opportunity, and attitude/rationalization.
Introduction
This paper reflects on SAS No. 99 to describe the difference between material misstatements due to errors and intentional fraud which includes fraudulent financial reporting and misappropriation of assets. It also describes the fraud triangle theory proposed by D. R. Cressey.
Think back to when you were in elementary school during fire safety week when the fire department would come and visit. Do you recall the fireman explaining what can be referred to as the fire triangle? That is, the description of what is necessary for fire to exist and continue. In order to create fire you need three things: fuel, oxygen, and heat. To put out (or prevent) the fire you would need to remove one of those three sides to the triangle. You could stop the fire by removing either the fuel, oxygen, or heat. This is a simple analogy for the fraud triangle. Just as there are three sides to the fire triangle there are three sides......

...represents an intangible asset that may significantly influence future firm performance. In 2014, three of those companies consisted of Google, SAS, and the Boston Consulting Group. These three companies find motivational ways to boost employee motivation and foster group cohesiveness.
Google holds the number one spot for best workplace and for good reason. Google currently employs over 42,000 employees (Fortune 100 Best Companies to Work For, 2014). Google gives employees plenty of options when it comes to choosing a team from engineering design to sales operations. Whether building products, growing businesses or helping to keep Google going, we do cool stuff that matters (Google Teams and Roles, 2014). According to Lush (2012), the group is cohesive because members like and are attracted to one another. Some major sources include member similarity and member attractiveness. The more choices an employee has about where they are placed in a company the more motivated they become. When employees are motivated it will help foster group cohesiveness.
The second spot for best workplace has been granted to SAS. SAS employs a little over 6,500 employees with a growth rate of 3.6%. We believe in stimulating work, an empowering management philosophy where you are encouraged to take risks and an inspiring work place where creativity thrives ( SAS Careers, 2014). Employees of the software developer use the services of its onsite health center, which is also open to family members.......

...as probable to report to him (Schein, 2010). Within the organization, he formed a hierarchy. During this time, two competitive organizations emerged in the market. The restructure in the organization caused a little problem internally in Apple Inc and the manager of Macintosh was alleged with favoritism in the department that led to demoralizing on other division of Apple Inc. in this it was required by Scully to reorganize the organizational structure once again as things were not working in the organization (Robbins, et al., 2003). Then organization was restructured and lost the control over the organization and Steve Jobs had overseen the division of Macintosh. Steve jobs returned and became the CEO of the organization. He managed all the divisions so effectively. His policies led to development of more new divisions like international and many projects were created for Steve Jobs. The organization took its position back in the market. These increased divisions led to the excess and redundant international projects for the company (Sinding, 2012).
Organizational Culture at Apple Inc
Apple Inc is undergoing some changes in structure and culture, because of some number of major events in the past few years. This is an organization that expanded rapidly in little period of time that the management observed some deficiency in the operation and financial controls. The organization was forced into the revaluation and redesigning of the organizational culture and......

...whom had purchased specially priced trips that were unprofitable to us. We decided to drive our costs down so that we could turn a profit even if we fell to 170,000 customers. But we didn’t just chop costs right off. We also restructured the organization, making it more flexible and able to handle more customers should the market bounce back. And the market truly did recover! Because of our flexibility, we easily absorbed the new customer demand and came out of the crisis showing a profit. During the first year of my presidency, we earned the largest profit in Vingresor’s history. In 1978, when I’d been president of Vingresor for just under four years, I was offered the presidency of Linjeflyg, Sweden’s domestic airline and an affiliate of SAS. Linjeflyg was losing money and desperately needed a strategy to turn it around. I accepted, becoming, at 36, the youngest airline president in the world.
This case was excerpted from Moments of Truth by Jan Carlzon, copyright  1987, used with permission of Ballinger Publishing Company. Excerpts were prepared by Professor John Kotter as the basis class discussion rather than to illustrate either effective or ineffective handling of an administrative situation. No part of this publication may be reproduced, stored in a retrieval system, used in a spreadsheet, or transmitted in any form or by any means—electronic, mechanical, photocopying, recording, or otherwise—without the permission of Harvard Business School. 1
489-046
Jan......