BookmarkSubscribeRSS Feed
Nasser_DRMCP
Lapis Lazuli | Level 10

data have ;
length contrat classe_1 classe_2 classe_3 $15. ; 
input contrat $ classe_1 $ classe_2 $ classe_3 $ ;
cards ;
123456789 PLNEXTIMP2 PLNEXT PLNEXT PLNEXT
;
run;


%macro change_classe ;

data want ;
set have ;
%do i=1 %to 3  ;
	%let classe_curr = classe_&i;
	%let classe_prev = classe_%eval(&i-1) ;
	%put ===>&classe_curr / &classe_prev ;

%if &classe_curr = "PLNEXT" and &classe_prev  ne "PLNEXT" %then entree_&i = "YES" ;
%end ;
run ;
%mend ;

%change_classe ;

Hello,

this is a dataset "have" with dummy data to expose my problem.

I would like to identify whenver the contract changes classe . from previous classe not PLNEXT to next class PLNEXT

thanks a lot iin advance

Nasser

10 REPLIES 10
Nasser_DRMCP
Lapis Lazuli | Level 10

hello

 

by replacing %if and %then by if and then ; it works

 

PaigeMiller
Diamond | Level 26

@Nasser_DRMCP wrote:

hello

 

by replacing %if and %then by if and then ; it works

 


Not obvious how this works with IF and THEN, as you need to add in an ARRAY statement, and then it should work properly. Use ARRAYs in DATA steps you need to perform some task across columns; do not use macros in this situation.

--
Paige Miller
Tom
Super User Tom
Super User

Turn on the MPRINT option before running your macro to see why it now works.  You will see that you macro %DO loop has now generate three IF/THEN statements.  You will also notice that one of them seems invalid since it is referencing an input variable that doesn't exist.

MPRINT(CHANGE_CLASSE):   data want ;
MPRINT(CHANGE_CLASSE):   set have ;
===>classe_1 / classe_0
MPRINT(CHANGE_CLASSE):   if classe_1 = "PLNEXT" and classe_0 ne "PLNEXT" then entree_1 = "YES" ;
===>classe_2 / classe_1
MPRINT(CHANGE_CLASSE):   if classe_2 = "PLNEXT" and classe_1 ne "PLNEXT" then entree_2 = "YES" ;
===>classe_3 / classe_2
MPRINT(CHANGE_CLASSE):   if classe_3 = "PLNEXT" and classe_2 ne "PLNEXT" then entree_3 = "YES" ;
MPRINT(CHANGE_CLASSE):   run ;

NOTE: Variable classe_0 is uninitialized.
NOTE: There were 1 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 1 observations and 8 variables.

See how your generate SAS code is trying to reference the variable CLASSE_0 that does not exist.

It actually will probably work, but just because the test you are doing will treat the missing CLASSE_0 values in a way that works for your test.

 

andreas_lds
Jade | Level 19

I don't see the need to use macro-code at all. Using arrays seems to be the way to solve the problem you have. Did you had a working version of the data-step that was free of macro code, before you added macro-statements?

Nasser_DRMCP
Lapis Lazuli | Level 10

no I don't have a working version of the data-step that was free of macro code

PaigeMiller
Diamond | Level 26

@Nasser_DRMCP wrote:

no I don't have a working version of the data-step that was free of macro code


If you can't get it to work without macro code, then by adding macro code then you still have the same problem and it won't work with macro code.

--
Paige Miller
Nasser_DRMCP
Lapis Lazuli | Level 10

sorry, I do not had understood your question. i dit not test without macro but directly code inside a macro. maybe I should not have

Kurt_Bremser
Super User

Since the macro code is resolved before the resulting data step code is sent to the compiler, it never has access to values that will exist while the data step executes.

Macro code is used to create code that later has to solve tasks. Macro code itself does never solve a task. See Maxim 11.

You want to solve a data issue, for which you use the data step. That's it. No macro code necessary.

 

As soon as you find out that you are using the same code snippet repeatedly and want to reduce your code writing load, then you start to look at macro coding.

VDD
Ammonite | Level 13 VDD
Ammonite | Level 13

@Nasser_DRMCP your data step is missing a column on the input statement.

data have ;
length contrat classe_1 classe_2 classe_3 $15. ; 
input contrat $ classe_1 $ classe_2 $ classe_3 $ ;
cards ;
123456789 PLNEXTIMP2 PLNEXT PLNEXT PLNEXT
;
run;

you have 4 fields being read by the input and 5 field values.

how can it be working?

Nasser_DRMCP
Lapis Lazuli | Level 10

Hello,

 

only 123456789 PLNEXTIMP2 PLNEXT PLNEXT are loaded in the table.

Inside the dataset step I have coded %if %then and it does not work. by replacing it with if then (without %) then it works

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 10 replies
  • 1089 views
  • 0 likes
  • 6 in conversation