Hi everyone, I have a Macro that performs a Do loop over a list of elements (numbers). This do loop executes good for the first element. But strangerly, it ignores the rest of the list, and there is no error message displayed. My question is the following : How do I rewrite my macro so that the Do loop performs for all elements of the list, not just the first one ? I could not transpose solutions from the post : https://communities.sas.com/t5/SAS-Programming/Macro-loop-stuck-in-the-first-element/td-p/507723 My case is probably slighty different. The situation : creating a table with N deleted observations I have the following situation : - a dataset "table_name" with 2 columns : "Time" and "Quantities" - I want to create a new table "table_name_N" in which I delete the last N observations of "Quantities" - To make it easier, I created a 3rd column named "Back" that takes "Time" from the end (see below for utility) For example, if N=4, we can compare my initial data and "table_name_4" : Initial Data : Time Back Quantities 1 50 100 2 49 100.4 ... ... 46 5 108 47 4 108.3 48 3 108.5 49 2 108.9 50 1 109.4 New table : "table_name_4" Time Back Quantities 1 50 100 2 49 100.4 ... ... 46 5 108 47 4 . 48 3 . 49 2 . 50 1 . The goal : dynamic creation of tables, whatever the number of tables I would like a macro that performs this automatically, e.g. : A) for any value of N B) for any number of tables I want to create. That is, if my macro takes as argument the list "4 8 12", I should obtain 3 tables : - a table "table_name_4" with 4 deleted observations - a table "table_name_8" with 8 deleted observations - a table "table_name_12" with 12 deleted observations My code : what works I have the code that performs A) and produces the table "table_name_4" or any kind of "table_name_N" : data WORK.Table_Name_4.;
set WORK.Table_Name ;
/* We use the "Back" column to control how many observations we delete */
DO i = 1 TO 4 ;
if Back=i then Quantities =. ;
END ;
run ;
My code : what does not work The following code is what should generalize A) so that I can perfom B) Strangely enough, it does work for the first element of the list, and it does not produce error messages. But other elements of the list are ignored. I get the table "table_name_4", but not the tables for 8 and 12 periods. Code that does not work (1) : the Macro Definition %macro Dynamic_Table_Creation (periods = );
/* periods is a list of numbers : 4 8 12 or 1 2 3 4, etc...) */
/* local macro-variables for the outer loop */
%local i next_element ;
/* outer loop : controls how many tables we create */
/* %sysfunc(countw(&periods.)) is the upper bound of the loop, it indicates how many distinct tables are created */
%do i=1 %to %sysfunc(countw(&periods.));
/* next_element contains the running number index */
/* for the value taken by "next_element", we create a table whose suffix is "next_element" */
%let next_element = %scan(&periods., &i.);
data WORK.table_name_&next_element.;
set WORK.table_name ;
/* inner loop */
/* We use the "Back" column to control how many observations we delete */
%DO i = 1 %TO %eval(&next_element.) ;
if Back=&i. then Quantities=.;
%END ;
run ;
%end ;
%mend ;
Code that does not work (2) : the Macro execution %Dynamic_table_creation (periods = 4 8 12) ; /* 4 8 12 can be replaced with any other list of numbers, like 1 2 3 4 5 */ Now if I execute my macro it does good for the first element of my list. That means "table_name_4" is created. But strangely, the loop ignores the rest of the list (numbers 8 and 12). How should I modify my code so that my loop perform for every element of the list ? That is, so that my loop creates 3 tables ? I work under SAS Enterprise Guide, and my version of SAS is SAS 9.1.3 I'm clearly a beginner for Data Management in SAS, so I'm sorry if this trivial... but I've been stuck on this single issue for days now and can't find what I did wrong. Thanks in advance, any help would be greatly appreciated.
... View more