Advanced Programming Using SAS 9.4
SAS Certified Professional Exam Guide
1 Exam Overview
The SAS Certified Professional: Advanced Programming Using SAS 9.4 exam is designed for experienced SAS programmers who want to demonstrate advanced programming skills.
Exam Code: A00-232
Duration: 2 hours
Questions: 60-65 multiple choice questions
Passing Score: 68%
Prerequisites: SAS Certified Specialist: Base Programming Using SAS 9.4
2 Exam Content Areas
2.1 1. SQL Processing with SAS (35%)
2.1.1 Create Tables and Views
- Use PROC SQL to create tables
- Create views for data access
- Understand table aliases
/* Example: Creating tables with PROC SQL */
PROC SQL;
CREATE TABLE work.sales_summary AS
SELECT
region,
product,
SUM(sales) AS total_sales,
AVG(price) AS avg_price,
COUNT(*) AS num_transactions
FROM work.sales_data
GROUP BY region, product
HAVING total_sales > 10000
ORDER BY total_sales DESC;
QUIT;
/* Creating a view */
PROC SQL;
CREATE VIEW work.high_value_customers AS
SELECT customer_id, customer_name, total_purchases
FROM work.customers
WHERE total_purchases > 5000;
QUIT;
2.1.2 Query and Subset Data
- Use SELECT, WHERE, and HAVING clauses
- Implement complex filtering logic
- Use subqueries
/* Example: Complex queries */
PROC SQL;
SELECT a.employee_id,
a.employee_name,
a.department,
b.salary
FROM work.employees AS a
INNER JOIN work.salaries AS b
ON a.employee_id = b.employee_id
WHERE b.salary > (SELECT AVG(salary) FROM work.salaries)
ORDER BY b.salary DESC;
QUIT;
2.1.3 Joins
- Inner joins
- Left, right, and full outer joins
- Self joins
- Cross joins
/* Example: Various join types */
PROC SQL;
/* Inner join */
SELECT a.*, b.sales
FROM work.customers AS a
INNER JOIN work.transactions AS b
ON a.customer_id = b.customer_id;
/* Left join */
SELECT a.*, b.sales
FROM work.customers AS a
LEFT JOIN work.transactions AS b
ON a.customer_id = b.customer_id;
/* Self join */
SELECT a.employee_name AS employee,
b.employee_name AS manager
FROM work.employees AS a
LEFT JOIN work.employees AS b
ON a.manager_id = b.employee_id;
QUIT;
2.2 2. Macro Processing (25%)
2.2.1 Create and Use Macro Variables
- Create macro variables with %LET
- Use automatic macro variables
- Understand macro variable scope
/* Example: Macro variables */
%LET year = 2024;
%LET region = 'East';
PROC PRINT DATA=work.sales;
WHERE year = &year AND region = ®ion;
TITLE "Sales Report for ®ion Region in &year";
RUN;
/* Using CALL SYMPUT */
DATA _NULL_;
SET work.summary;
WHERE region = 'West';
CALL SYMPUT('west_total', total_sales);
RUN;
%PUT Total West Sales: &west_total;
2.2.2 Create and Use Macros
- Define macros with %MACRO and %MEND
- Use macro parameters
- Implement conditional logic in macros
/* Example: Creating macros */
%MACRO generate_report(dataset=, year=, output=);
PROC MEANS DATA=&dataset NOPRINT;
WHERE year = &year;
VAR sales revenue;
OUTPUT OUT=&output
SUM(sales)=total_sales
SUM(revenue)=total_revenue;
RUN;
PROC PRINT DATA=&output;
TITLE "Summary Report for Year &year";
RUN;
%MEND generate_report;
/* Calling the macro */
%generate_report(dataset=work.sales_data,
year=2024,
output=work.summary_2024);
2.2.3 Macro Functions
- %EVAL and %SYSEVALF
- %SUBSTR, %SCAN, %UPCASE
- %STR and %NRSTR
/* Example: Macro functions */
%MACRO process_data(start_year=, end_year=);
%DO year = &start_year %TO &end_year;
PROC PRINT DATA=work.sales_&year;
TITLE "Sales for Year &year";
RUN;
%END;
%MEND process_data;
%process_data(start_year=2020, end_year=2024);
2.3 3. Advanced DATA Step Programming (20%)
2.3.1 Array Processing
- Create and use one-dimensional arrays
- Create and use multi-dimensional arrays
- Process array elements
/* Example: Array processing */
DATA work.quarterly_analysis;
SET work.sales;
ARRAY quarters{4} q1 q2 q3 q4;
ARRAY pct_change{3} pct_q2 pct_q3 pct_q4;
/* Calculate percentage changes */
DO i = 2 TO 4;
pct_change{i-1} = (quarters{i} - quarters{i-1}) / quarters{i-1} * 100;
END;
/* Calculate annual total */
annual_total = SUM(OF quarters{*});
DROP i;
RUN;
2.3.2 Hash Objects
- Create and use hash objects
- Implement efficient lookups
- Use hash iterators
/* Example: Hash object for lookup */
DATA work.enriched_data;
IF _N_ = 1 THEN DO;
DECLARE HASH lookup(DATASET: "work.reference_data");
lookup.DEFINEKEY('id');
lookup.DEFINEDATA('category', 'description');
lookup.DEFINEDONE();
END;
SET work.main_data;
rc = lookup.FIND();
IF rc = 0 THEN output;
DROP rc;
RUN;
2.3.3 DO Loop Processing
- Iterative DO loops
- DO WHILE and DO UNTIL loops
- Nested loops
/* Example: Advanced DO loops */
DATA work.compound_interest;
principal = 10000;
annual_rate = 0.05;
DO year = 1 TO 10;
interest = principal * annual_rate;
principal = principal + interest;
OUTPUT;
END;
RUN;
/* DO UNTIL example */
DATA work.convergence;
x = 1;
iteration = 0;
DO UNTIL (ABS(x - x_prev) < 0.001 OR iteration > 100);
x_prev = x;
x = x / 2 + 1 / x;
iteration + 1;
OUTPUT;
END;
RUN;
2.4 4. Advanced Techniques (20%)
2.4.1 Using PROC FCMP
- Create custom functions
- Use custom functions in DATA steps
/* Example: Creating custom functions */
PROC FCMP OUTLIB=work.funcs.math;
FUNCTION calculate_discount(amount, rate);
discount = amount * rate;
RETURN(discount);
ENDSUB;
QUIT;
OPTIONS CMPLIB=work.funcs;
DATA work.with_discounts;
SET work.sales;
discount = calculate_discount(price, 0.10);
final_price = price - discount;
RUN;
2.4.2 Using Indexes
- Create simple and composite indexes
- Understand when to use indexes
- Use WHERE vs. subsetting IF
/* Example: Creating and using indexes */
PROC DATASETS LIBRARY=work NOLIST;
MODIFY sales;
INDEX CREATE customer_id;
INDEX CREATE region_product = (region product);
QUIT;
/* Indexes are automatically used with WHERE statements */
DATA work.subset;
SET work.sales;
WHERE customer_id = '12345'; /* Uses index */
RUN;
2.4.3 Combining Data Vertically and Horizontally
- Advanced merging techniques
- Update and modify operations
- Interleaving data sets
/* Example: UPDATE statement */
DATA work.master;
UPDATE work.current_data work.changes;
BY id;
RUN;
/* Example: Interleaving */
DATA work.combined;
SET work.data2020 work.data2021 work.data2022;
BY date;
RUN;
3 Study Resources
3.1 Official SAS Resources
- SAS Programming 2: Data Manipulation Techniques - Official SAS training
- SAS Programming 3: Advanced Techniques and Efficiencies - Official SAS training
- SAS Macro Language 1: Essentials - Official SAS training
- SAS SQL 1: Essentials - Official SAS training
3.2 Practice Tips
- Master SQL
- SQL accounts for 35% of the exam
- Practice complex joins and subqueries
- Understand the differences between SQL and DATA step
- Understand Macros
- Practice writing parameterized macros
- Learn macro debugging techniques
- Understand macro quoting functions
- Advanced DATA Step
- Master array processing
- Learn hash object techniques
- Practice complex DO loops
- Performance Optimization
- Understand when to use indexes
- Learn efficient data processing techniques
- Compare SQL vs. DATA step performance
4 Common Pitfalls
- Macro quoting issues - Use %STR, %NRSTR, %BQUOTE correctly
- Hash object syntax - Remember to declare and define before using
- SQL vs. DATA step confusion - Understand when to use each approach
- Scope issues with macro variables - Understand local vs. global scope
5 Sample Questions
5.1 Question 1
What is the purpose of the %NRSTR function?
Answer: %NRSTR prevents macro resolution and removes the meaning of special characters and mnemonic operators during compilation, including the ampersand (&) and percent sign (%).
5.2 Question 2
Which join type returns all rows from both tables?
A. Inner Join B. Left Join C. Right Join D. Full Outer Join
Answer: D - Full Outer Join returns all rows from both tables, with NULL values where there’s no match.
6 Next Steps
After completing Advanced Programming certification:
- Apply advanced techniques in real-world scenarios
- Consider specialized certifications (Clinical Trials, Data Mining, etc.)
- Contribute to the SAS community