Mastering FIRST. and LAST. Variables in SAS for Efficient Data Grouping and Summarization
As a SAS programmer, leveraging the full power of the DATA step is key to writing efficient and effective code. Two of the most useful tools in a SAS programmer‘s toolkit are the automatic FIRST. and LAST. temporary variables. When used with the BY statement, these variables allow you to easily identify and take action on the first and last observations in a group without needing to write complex conditional logic. Mastering FIRST. and LAST. will level up your SAS programming skills and enable you to solve a variety of common data transformation and aggregation tasks with minimal code.
How FIRST. and LAST. Variables Work
Whenever a BY statement is used in conjunction with a SET statement in a DATA step, SAS automatically creates two temporary variables for each variable listed in the BY statement:
- FIRST.variable
- LAST.variable
Where "variable" is the name of the BY variable. These temporary variables equal either 1 or 0 depending on the position of the current observation within its BY group:
- FIRST.variable = 1 when the observation is the first one in a BY group
- FIRST.variable = 0 when the observation is not the first one in a BY group
- LAST.variable = 1 when the observation is the last one in a BY group
- LAST.variable = 0 when the observation is not the last one in a BY group
The FIRST. and LAST. variables are available for use in the DATA step, but are not output to the final dataset since they are temporary. Their values allow you to detect the beginning and end of each BY group and take different actions accordingly, such as:
- Initializing totals or counters to 0 at the start of a new BY group
- Accumulating sums, retaining values, or concatenating strings across observations in a BY group
- Outputting aggregated summaries or results at the end of a BY group
By strategically using FIRST. and LAST., you can avoid the need to use lagging variables, retain totals across complex boundaries, or match-merge summary values back to the original data.
Example Use Case
To illustrate the usage of FIRST. and LAST. variables, let‘s walk through an example using a sample dataset. Suppose we have the following data on customer transactions:
Customer_ID | Transaction_Date | Amount
-------------------------------------
A | 2023-01-01 | 100.00
A | 2023-01-15 | 50.00
A | 2023-02-01 | 75.00
B | 2023-01-01 | 200.00
B | 2023-03-01 | 150.00
C | 2023-01-01 | 50.00
Our goal is to calculate the total number of transactions and total amount for each customer. We can accomplish this easily using FIRST. and LAST. Here‘s the SAS code:
PROC SORT DATA=transactions; BY Customer_ID; RUN;DATA customer_summary; SET transactions; BY Customer_ID;
IF FIRST.Customer_ID THEN DO; transaction_count = 0; total_amount = 0; END;
transaction_count + 1; total_amount + Amount;
IF LAST.Customer_ID THEN OUTPUT;
KEEP Customer_ID transaction_count total_amount; RUN;
Let‘s break this down step-by-step:
-
First, sort the data by Customer_ID using PROC SORT. This is necessary for the BY statement to work properly.
-
In the DATA step, use BY Customer_ID to group the observations by customer.
-
Check if FIRST.Customer_ID = 1, indicating the start of a new customer group. If so:
- Initialize transaction_count to 0
- Initialize total_amount to 0
-
For every observation:
- Increment transaction_count by 1
- Add the Amount to the running total_amount
-
Check if LAST.Customer_ID = 1, indicating the last observation for the current customer:
- If so, output the aggregated results as a new summarized observation
- Only keep the desired summary variables in the output dataset
The resulting dataset customer_summary contains:
Customer_ID | transaction_count | total_amount
----------------------------------------------
A | 3 | 225.00
B | 2 | 350.00
C | 1 | 50.00
By leveraging the power of FIRST. and LAST., we were able to aggregate the data by customer with concise, readable code. This technique can be extended to accommodate more complex logic, such as conditional counts, subtotals for multiple BY groups, and checks for missing or invalid records.
Other Uses and Alternatives
Apart from summarizing and aggregating data, FIRST. and LAST. are also commonly used for:
- Removing duplicate observations in each BY group (e.g. keep only the first or last record)
- Creating lagging or leading variables scoped to each BY group
- Identifying gaps or missing sequence numbers within each BY group
- Transposing data from long to wide format (e.g. pivot records to columns)
- Merging overlapping ranges or intervals by start/end identifiers
While FIRST. and LAST. are powerful and convenient, there are some limitations and alternatives to consider:
- They require the data to be sorted by the BY variables, which may not always be desirable or efficient for large datasets. Hash tables can be used to aggregate data without sorting.
- Complex filtering or subsetting logic can make the code more difficult to follow. In some cases, it may be simpler to use SQL summary functions like SUM() or COUNT() with GROUP BY.
- FIRST. and LAST. only detect the beginning and end of each BY group. If you need more granular control, like taking action on every nth record, you‘ll need additional counters or flags.
Despite these caveats, FIRST. and LAST. remain indispensable tools for any SAS programmer working with the DATA step. With practice, you‘ll be able to wield them effectively to solve a wide range of data manipulation challenges.
Conclusion
The automatic FIRST. and LAST. variables in SAS are essential for grouping observations and efficiently performing BY-group level calculations in the DATA step. By understanding how they work and leveraging them appropriately, you can write cleaner, more concise, and more efficient SAS code. We walked through a detailed customer transaction aggregation example to demonstrate their usage and discussed some best practices and alternatives.
Mastering FIRST. and LAST. will greatly elevate your SAS programming skills and productivity. The concepts and techniques covered here can be readily applied to real-world data transformation and analysis tasks across various domains. I encourage you to practice using FIRST. and LAST. in your own SAS programs and explore more advanced applications. With creativity and experience, you‘ll be able to solve complex data challenges with elegant, effective SAS code.