Learn SAS Programming by Code Examples

Learn SAS Programming by Code Examples with me as I compiled a list of useful code samples below used in developing SAS applications for printing reports and manipulating records in datasets.

How to print Hello World in SAS?
Use ‘put’ statement to display message in SAS log or print into a report line. ‘file’ is a SAS keyword to output your ‘put’ message whereas ‘infile’ is a SAS keyword to derive/extract raw data from an external file or datalines. ‘print’ is also a SAS keyword that refers to either SAS internal display or external file if explicitly link to it. A _null_ dataset is a temporary dataset that will be not be keep any records after usage.

data _null_; 
file print;
put 'Hello World';

How to populate a dataset using external input?
Assuming you have a text file named as ‘hardware.txt’ containing hardware information, you can use ‘infile’ (SAS Keyword) to extract data from it. Once you have pinpoint the source, use ‘input’ (SAS Keyword) to define the fields which will break a line of record into multiple sections and dump data into its respective fields based on the variable length (using $. or d.) and position (using @). The dollar sign represents string variable whereas non-dollar sign represents numeric variable.

data hardware;
infile hardware.txt;
input @1 type $5. @6 brand $10. @name $20.;

/*Assuming the hardware.txt contains the following sample data...
cpu  intel     Core i7 3770K
cpu  amd       FX8150
*/

How to populate a dataset using datalines? (basic method)
Datalines is a quick method to define a list of records without the need to create an external file. It’s best use to test a dataset whether its working fine with other logic within your SAS code. Using datalines without a delimiter, by default, will separate each information based on whitespace. However, if those related information should be joined with whitespace, you will need to use delimiter.

Length is used here to set the maximum characters that a string variable can hold the value. By default, a string variable can only hold 8 characters. If you do not specify sufficient character to hold the string value, it will be truncated from right for string and truncated left for numeric value.

data hardware;
length type $5. brand $20. name $20.;
input type $ brand $ name $;
datalines;
CPU Intel 3770K
CPU AMD FX8150
RAM Corsair ABC
PSU Coolermaster DEF
MOBO Gigabyte GHI
;
proc print data=hardware;

/* [NOTE]  Below is a list of hardware records printed via 'proc print'.
                     Obs    type    brand           name
                      1     CPU     Intel           3770K
                      2     CPU     AMD             FX8150
                      3     RAM     Corsair         ABC
                      4     PSU     Coolermaster    DEF
                      5     MOBO    Gigabyte        GHI
*/

How to populate dataset using datalines with comma or specific delimiter?
Sometimes your record must be broken up using a symbol that is not used within a record. Whitespace is a common character that is used to link English words as a sentence, therefore we can’t use that as our delimiter. So we can use something else, which is comma. If your sentence includes comma and whitespace, you can use something non-common such as a slash or straight bar or perhaps semicolon.

data hardware;
infile datalines delimiter=',';
length type $5. brand $20. name $20.;
input type $ brand $ name $;
datalines;
CPU,Intel,Core i7 3770K
RAM,Corsair,G.Skill TridentX DDR3 2400MHz 8GB
;
proc print data=hardware;

/* [NOTE] Below is a list of records contained in hardware dataset.
                 Obs    type     brand     name
                  1     CPU     Intel      Core i7 3770K
                  2     RAM     Corsair    G.Skill TridentX DDR
*/

How to limit observations read from external input?
Assuming the external file called hardware.txt has a list of over thousand of records/lines, but you just want the first 100 records/observations, then use (obs=total-observations-to-be-read).

data hardware;
infile hardware.txt (obs=100);
input @1 variable_name $10.;

How to limit observations read from a dataset?
The code below limits total observation read from dataset_A to 100. (obs=100)
Only the first 100 observations are processed in the data _null_;

data _null_;
set dataset_A (obs=100);

How to limit observations read from an external file?
The code below limits total observation read from external textfile by 100 (obs=100)
Also, it starts processing observations at 50 and above (firstobs=50)

data dataset_A;
infile external_file.txt obs=100 firstobs=50;

How to use Regular Expression to Match a String

data dummy (drop=regexp);
name = 'Ayumilove';
retain regexp prxparse("/Ayumilove/");
if prxmatch(regexp,name) then put 'Match Found! : ' name;

How to use Regular Expression to Replace a String
Assuming that we want to change the value 1 into 2:

data dummy (drop=regexp);
name = '1Ayumilove';
retain regexp prxparse("s/1(w+)/2$2/");
call prxchange(regexp,-1,name);
put name;

How to debug a dataset quickly?
To quickly check whether your variables in a dataset is populated correctly, you can use “proc print data” to view its contents as shown below, but don’t forget to print it out somewhere such as SASLIST.

proc printTo print=SASLIST;
proc print data=RECIPE;

How to truncate numeric data without rounding up or down?
Sometimes when you have numbers with more than 2 decimal points in your input or raw file, but you only want to display a maximum of 2 digits (2 decimal points) without rounding up or rounding down, we can use int() in SAS to solve this.

data _null_;
example = 123.4567; /*this value contains 4 decimal points but we need only 2*/
example2 = int(example * 100) / 100;
put example2; /*results:123.45*/

How to transfer data from one dataset to the other?
How to make a data in 1 dataset available in other datasets?

To allow a variable in one dataset available to be use in other datasets, you can use SAS function “call symput”.

data _null_;
ayumilove_age = '18';
call symput('ayumilove_age',ayumilove_age); /*make this variable accessible everywhere*/
run; /*run the call symput function to make variable available*/

data other_dataset; /*The other dataset that uses the global variable to print out*/
age = &ayumilove_age; /*to call the variable, prefix an ampersand symbol*/

proc print data=other_dataset;

How to merge 2 datasets using a common variable/attribute?
If you have 2 datasets that you want to combine by using a common field, you can use SAS “merge + by statement”. This will combine to 2 datasets based on the attribute you have given, acting as the key (index). If these key matches with one another, it will merge the record. As a result, one of the record will contains all fields from both datasets.

/*This is the first dataset containing personal information of each character*/
data character;
infile datalines delimiter=',';
length nickname $10. name $30.;
input nickname $ name $ age money ;
datalines;
Kirito,Kirigaya Kazuto,16,12.34
Asuna,Yuuki Asuna,17,56.78
Silica,Ayano Keiko,13,98.76
;


/*This is the second dataset containing skills of each character*/
data skill;
infile datalines delimiter='/';
length nickname $10. skill $120.;
input nickname $ skill $;
datalines;
Kirito/Starburst Stream,Dual Blades,Fishing,Tracking,Blade Throwing
Asuna/Star Splash,One-Handed Rapier,Cooking,Sewing,Acrobatics
Silica/Bubble Breath,One-Handed Dagger,Cooking,Familiar Communication
;

/*You need to sort both datasets before merging them using BY statement*/
proc sort data=skill; by nickname;
proc sort data=character; by nickname;

/*This is combining both skill and character datasets using BY statement*/
data skill_character;
merge character skill; by nickname;

proc print data=skill_character;

/* AYUMILOVE NOTE: This is the result of combining both datasets!
     Obs    nickname         name          age    money

      1      Asuna      Yuuki Asuna         17    56.78
      2      Kirito     Kirigaya Kazuto     16    12.34
      3      Silica     Ayano Keiko         13    98.76

     Obs                                 skill

      1     Star Splash,One-Handed Rapier,Cooking,Sewing,Acrobatics
      2     Starburst Stream,Dual Blades,Fishing,Tracking,Blade Throwing
      3     Bubble Breath,One-Handed Dagger,Cooking,Familiar Communication
*/

How to only output matched records when merging 2 datasets?

abc

How to perform a simple conditional statements in SAS?
Below is an example of how to use a simple if-statement in SAS to compare numeric values stored in variables. SAS is similar to COBOL where it can also use two-letters notation instead of the usual high-level programming language comparison value like Java or C++.

data _null_;
file print;

/*Ingredients*/
Sagu_Leaves = 52;
Pneuma_Flowers = 51;
Abilpa_Beans = 50;
Oola_Fish_Bones = 49;
Grogwa_Seeds = 48;
Shubur_Leaves = 47;

/* You can use maths notation to compare values in variables. */
if (Abilpa_Beans = 50) then put 'There are 50 Abilpa Beans.';
if (Pneuma_Flowers > 50) then put 'There are more than 50 Pneuma Flower';
if (Sagu_Leaves >= 50) then put 'There are 50 or more Sagu Leaves.';
if (Oola_Fish_Bones < 50) then put 'There are less than 50 Oola Fish Bones.';
if (Grogwa_Seeds <= 50) then put 'There are 50 or less Grogwa Seeds.';
if (Shubur_Leaves ^= 50) then put 'Total Shubur Leaves is not equal to 50.';

/* You can also use 2-letters notation for comparison. */
if (Abilpa_Beans EQ 50) then put 'Abilpa Beans equal to 50.';
if (Pneuma_Flowers GT 50) then put 'Pneuma Flowers is greater than 50.';
if (Sagu_Leaves GE 50) then put 'Sagu Leaves is greater than or equal to 50.';
if (Oola_Fish_Bones LT 50) then put 'Oola Fish Bones is less than 50.';
if (Grogwa_Seeds LE 50) then put 'Grogwa Seeds is less than or equal to 50.';
if (Shubur_Leaves NE 50) then put 'Shubur Leaves not equal to 50.';

/* [RESULT]
There are 50 Abilpa Beans.
There are more than 50 Pneuma Flower
There are 50 or more Sagu Leaves.
There are less than 50 Oola Fish Bones.
There are 50 or less Grogwa Seeds.
Total Shubur Leaves is not equal to 50.

Abilpa Beans equal to 50.
Pneuma Flowers is greater than 50.
Sagu Leaves is greater than or equal to 50.
Oola Fish Bones is less than 50.
Grogwa Seeds is less than or equal to 50.
Shubur Leaves not equal to 50.
*/

How to perform multi-line conditional statements in SAS?
If you want to execute multiple actions within 1 if-statement, you will need to encapsulate them in between a do-end statement. Here is the syntax: if (conditional-true) then do; (actions); end;

data _null_;
file print;
Ragout_Rabbit_Recipe = 1;

if (Ragout_Rabbit_Recipe = 1) then do;
	put 'You will need the following ingredients for this stew:';
	put '3 Pisco Seeds';
	put '5 Arequipa Leaves';
	put '5 Karim Water';
	put '8 Huriaca Beans';
	put '3 Pucalpa Leaves';
end;

/* [RESULT]
You will need the following ingredients for this stew:
3 Pisco Seeds
5 Arequipa Leaves
5 Karim Water
8 Huriaca Beans
3 Pucalpa Leaves
*/

How to string/join multiple conditions within an if-statement?
You can join multiple conditions within a conditional statement using AND or OR. If any of the conditions are reported false between AND, it will not run the actions within do-end statement. If any of the conditions are reported true between OR, it will run the actions within do-end statement. However, when using both AND-OR, you will need to use round brackets to determine the condition priority to check first.
If condition-1 is true and condition-2 is true, it will run.
if condition-1 is false and condition-2 is true, it will not run.
if condition-1 is false or condition-2 is false, it will not run.
if condition-1 is false or condition-2 is true, it will run.
if (condition-1 is true and condition-2 is false) or condition-3 is true; it will run.
if (condition-1 is true or condition-2 is false) and condition-3 is false; it will not run.

data recipe;
Abilpa_Beans = 1;
Sagu_Leaves = 2; 
Oola_Fish_Bones = 3;

if (Abilpa_Beans >= 1 and Sagu_Leaves >= 2 and Oola_Fish_Bones >= 3)
then do; 
put 'There are sufficient ingredients to make Soy Sauce.'; 
end;

/* [RESULT] There are sufficient ingredients to make Soy Sauce. */

data recipe;
Pneuma_Flower = 3;
Red_Flower = 5;

if (Pneuma_Flower >= 2 or Red_Flower >= 2)
then do; 
put 'There are sufficient ingredients to brew common flower tea.'; 
end;

/* [RESULT] There are sufficient ingredients to brew common flower tea.  */

Leave a Reply

Your email address will not be published. Required fields are marked *