6.1 SAS Array Processing for Multi-Variable Transformations
Key Takeaways
- An ARRAY statement defines a temporary grouping of SAS variables (existing or new) for repetitive processing within a DATA step; arrays themselves are not saved to the output dataset.
- Array dimensions can be explicitly declared with numerical ranges [n] or [lower:upper], or implicitly bound using asterisk notation [*] paired with variable list shortcuts like _NUMERIC_, _CHARACTER_, or OF qtr1-qtr4.
- The DIM(array_name) function dynamically calculates the upper bound (number of elements) of an array dimension, preventing hardcoded loop boundary errors during DATA step execution.
- The _TEMPORARY_ keyword creates temporary array elements in memory that are automatically retained across DATA step iterations, updated directly, and excluded from the output dataset descriptor.
- Array elements can be initialized with starting values using standard syntax ARRAY name[dim] ($) (initial_values); character arrays require specifying the dollar sign ($) before optional length and values.
6.1 SAS Array Processing for Multi-Variable Transformations
In real-world data engineering and analytics, datasets frequently contain groups of related variables representing repetitive measurements across time, categories, or survey items—such as monthly sales (Sales_Jan through Sales_Dec), quarterly revenues (Qtr1 through Qtr4), or psychometric test items (Item1 through Item50). Writing individual assignment statements or conditional logic for dozens of columns is inefficient, error-prone, and difficult to maintain.
SAS array processing allows programmers to group multiple variables under a single collective name and perform repetitive operations using iterative DO loops. Understanding how SAS handles arrays in memory during DATA step processing is a core requirement for the SAS Base Programming Specialist exam (A00-231).
1. What is a SAS Array?
It is vital to understand what a SAS array is and what it is not:
- What it is: A SAS array is a temporary grouping of SAS variables defined strictly within the context of a single DATA step. It provides an alternative, indexed method for referencing variables in memory during DATA step execution.
- What it is NOT: A SAS array is not a physical data structure, table, or variable stored in the output SAS dataset descriptor. Once the DATA step finishes executing, the array structure vanishes, leaving only the underlying dataset variables.
/* Traditional non-array approach to recalculate 4 quarterly figures */
data work.sales_adjusted;
set work.sales_raw;
Qtr1 = Qtr1 * 1.05;
Qtr2 = Qtr2 * 1.05;
Qtr3 = Qtr3 * 1.05;
Qtr4 = Qtr4 * 1.05;
run;
/* Equivalent array processing approach */
data work.sales_adjusted;
set work.sales_raw;
array qtr{4} Qtr1-Qtr4;
do i = 1 to 4;
qtr{i} = qtr{i} * 1.05;
end;
drop i; /* Drop loop index variable from output dataset */
run;
2. ARRAY Statement Syntax & Subscript Declaration
The ARRAY statement is a compile-time statement that defines the array name, dimensions, element type, variable elements, and optional initial values.
General Syntax
ARRAY array_name {dimension} [$] [length] [variable_list] [(initial_values)];
- Brackets/Parentheses/Braces: Array subscripts can be enclosed in curly braces
{ }, square brackets[ ], or parentheses( ). Braces or square brackets are widely preferred to visually distinguish array references from SAS functions. - Dimensioning Methods:
- Explicit Integer Count: Specifying a fixed number of elements, e.g.,
{4}or{12}. - Explicit Range: Specifying a starting and ending index, e.g.,
{1995:2025}or{-5:5}. This allows non-1 lower bounds. - Asterisk
[*]Notation: Instructs SAS to automatically count the number of variables listed invariable_listduring compilation.
- Explicit Integer Count: Specifying a fixed number of elements, e.g.,
| Array Declaration Example | Type | Elements / Variables Referenced | Subscript Index Range |
|---|---|---|---|
array month{12} m1-m12; | Numeric | m1, m2, m3, ..., m12 | 1 through 12 |
array year{1990:1995} Y1990-Y1995; | Numeric | Y1990, Y1991, Y1992, ..., Y1995 | 1990 through 1995 |
array status[*] $1 Active Inactive Pending; | Character | New variables Active, Inactive, Pending | 1 through 3 |
array metrics[*] _NUMERIC_; | Numeric | All numeric variables in PDV at declaration | 1 through total count |
/* Example of non-standard lower bounds */
data work.temperature_anomaly;
set work.climate_data;
/* Access using actual calendar year as index */
array temp{2020:2024} Temp2020-Temp2024;
do yr = 2020 to 2024;
if temp{yr} > 100 then ExtremeHeat_Flag = 1;
end;
run;
3. Variable List Shortcuts in Arrays
When declaring arrays, SAS provides special variable list shortcuts to streamline code authoring:
- Numbered Range Lists:
Qtr1-Qtr4expands toQtr1, Qtr2, Qtr3, Qtr4. Requires digits to be sequential. - Name Range Lists:
sales_jan--sales_decincludes all variables positioned betweensales_janandsales_decin the Program Data Vector (PDV) order. - Type Special Lists:
_NUMERIC_: Includes all numeric variables previously compiled in the PDV._CHARACTER_: Includes all character variables previously compiled in the PDV._ALL_: Includes all variables (requires all variables in array to share data type).
Exam Tip: When using
_NUMERIC_or_CHARACTER_, the array only references variables that exist in the PDV prior to or at the point of theARRAYstatement. Variables created later in the DATA step are excluded.
4. Iterative DO Loops & Dynamic Array Bounds (DIM Function)
Hardcoding loop upper bounds (e.g., do i = 1 to 12;) introduces maintenance risks if variables are added or removed from the array list. The DIM() function evaluates the number of elements in an array dynamically at compilation and execution.
Array Bounds Functions
DIM(array_name): Returns the total number of elements in the specified array dimension (defaults to 1st dimension).HBOUND(array_name): Returns the upper bound (highest index) of the array.LBOUND(array_name): Returns the lower bound (lowest index) of the array (crucial when index lower bound $\ne$ 1).
/* Dynamic Array Processing with DIM and LBOUND/HBOUND */
data work.survey_cleaned;
set work.survey_raw;
array response[*] Q1-Q25;
/* Dynamically loop through all elements regardless of array size */
do i = 1 to dim(response);
/* Replace invalid survey values (-9, 99) with SAS missing value */
if response{i} in (-9, 99) then response{i} = .;
end;
drop i;
run;
5. Temporary Arrays (_TEMPORARY_ Keyword)
In many analytical applications, you need array elements to store constants, baseline values, or intermediate calculations without saving those elements as columns in the final dataset. The _TEMPORARY_ keyword creates temporary data elements in memory.
Key Attributes of _TEMPORARY_ Arrays
- No Dataset Variables: Elements do not correspond to existing or new variables in the output dataset. They exist only in RAM during DATA step execution.
- Automatic Retention: Values in
_TEMPORARY_array elements are automatically retained across DATA step iterations (no explicitRETAINstatement needed). - High Performance: Eliminates PDV overhead and disk write operations, making lookup comparisons significantly faster.
- Initialization Syntax: Specified using parentheses after
_TEMPORARY_.
/* Benchmarking quarterly sales against fixed targets using a _TEMPORARY_ array */
data work.bonus_eligibility;
set work.quarterly_sales;
/* Define temporary target lookup table (Q1=1000, Q2=1200, Q3=1100, Q4=1500) */
array targets{4} _TEMPORARY_ (1000, 1200, 1100, 1500);
array sales{4} Qtr1-Qtr4;
MetTarget_Count = 0;
do i = 1 to dim(sales);
if sales{i} >= targets{i} then MetTarget_Count + 1;
end;
drop i;
run;
6. Common Pitfalls & Exam Watchouts
- Subscript Out of Range: Referencing an index outside array bounds (e.g.,
qtr{5}when array dimension is 4) terminates DATA step execution with anERROR: Array subscript out of range. - Unwanted Index Variables: The index variable used in a
DOloop (e.g.,iindo i = 1 to dim(arr);) is added to the PDV and written to the output dataset unless dropped withDROP i;or defined as a temporary variable. - Data Type Mismatch: An array must contain exclusively numeric variables or exclusively character variables. Mixing types in a single array causes a compilation error unless multiple dimensions or distinct arrays are defined.
A SAS programmer executes the following DATA step: data work.scores_updated; set work.scores_raw; array test{*} Score1-Score10; do i = 1 to dim(test); if test{i} < 60 then test{i} = 60; end; run; What is the primary advantage of using the DIM(test) function in the DO loop condition instead of specifying 10?
Which statement correctly describes the behavior of an array declared with the TEMPORARY keyword?
Given the following array statement: array sales{2021:2024} rev_2021-rev_2024; What is the value returned by LBOUND(sales) and what is the valid subscript range to access rev_2023?
A dataset contains numeric variables Height, Weight, and Age, followed by character variable Name. Consider the following code: data work.summary; set work.health_data; array num_vars[] NUMERIC; array char_vars[] CHARACTER; run; If a programmer references num_vars{4} during execution, what occurs?