DATA Step, Macro, Functions and more

CALL SYMPUT LOOPING PROBLEM

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 17
Accepted Solution

CALL SYMPUT LOOPING PROBLEM

Hello all !

I am actually running this code below which is supposed to create the variable "value_copy"  as a copy of variable "value"  using the call symput rountine ,but it s only keep repeating the last value for all lines .

Any idea of how to fixe that ?  Thank you

data test ; 
input value$ @@; 
datalines ; 
a b c d f g h r e s y z
; 
run ; 

proc sort data = test ; 
by value ; 
run ; 
 
data test ; 
	set test ;
		call symput("mv" , value) ;
		value_copy = "&mv" ; 
		
run ;

ResultResult

 


Accepted Solutions
Solution
a week ago
Super User
Posts: 6,936

Re: CALL SYMPUT LOOPING PROBLEM

something like

array nbimp2016 {*} nbimp201601-nbimp201606;
month_check = month(&date_risk);
if (nbimp2016{month_check} >= 3)
then HR_3 = 1;
else HR_3 = 0;

In the same vein, you could create a two-dimensional array with years and months.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Regular Contributor
Posts: 182

Re: CALL SYMPUT LOOPING PROBLEM

The macro variable created by call symput isn't available until the data step ends so if you ran this on a fresh session you would get a note in your log telling you it couldn't be resolved then on the second run it would hold the last value from the first run and so on....

 

If you tell us exactly why you want to do something like this (it isn't clear from the example) we can offer an alternative.

Trusted Advisor
Posts: 1,612

Re: CALL SYMPUT LOOPING PROBLEM

[ Edited ]

It's really unclear to me why you have macros here. And, agreeing with @ChrisBrooks, I don't even understand what you are trying to do or why are you doing this. Please explain the purpose of this program.

 

What about this?

 

data test ; 
	set test ;
	value_copy = value; 
run ;

Or this:

 

data test ; 
input value$ @@; 
value_copy=value;
datalines ; 
a b c d f g h r e s y z
; 
run ; 

 

Super User
Super User
Posts: 7,401

Re: CALL SYMPUT LOOPING PROBLEM

Macro and datastep are different things.  Macro is to create text not to do data processing.  From what you posted then:

data test;
  set test;
  value_copy=value;
run;

From the documentation:

http://support.sas.com/documentation/cdl/en/lefunctionsref/69762/HTML/default/viewer.htm#p1vvi5gjow5...

 

If you have a specific need to use symput, please define the scenario.

Super User
Posts: 6,936

Re: CALL SYMPUT LOOPING PROBLEM

Stop abusing the macro processor for something it is not designed for. This can be VERY simply done with data step code.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Occasional Contributor
Posts: 17

Re: CALL SYMPUT LOOPING PROBLEM

Yes i know,  i m just trying to give o basic example of my problem

what i want to do is much bigger than that

Super User
Posts: 6,936

Re: CALL SYMPUT LOOPING PROBLEM


Raitag wrote:

Yes i know,  i m just trying to give o basic example of my problem

what i want to do is much bigger than that


It is still a basic abuse of the macro processor. The data step language provides for several mechanisms to conserve values across observations (retain, lag functions, hash objects), which are much better suited for such tasks. The macro processor is designed to create dynamic code, NOT to handle data.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Occasional Contributor
Posts: 17

Re: CALL SYMPUT LOOPING PROBLEM

i m working on data about loans

for each loan demand i have :

- id_ demand

- date_dem : which is the date when the customer submit his demand ;

- nbimpYYYYMM : which refers to the number of registered umpaids at the end of the month YYYYMM

with YYYYMM going from 201601 to 201606 ;

 

What i want to do is to define the variable HR3 where :

HR3 = 1 if the Customer has 3 umpaids or more 3 month after the demand

(which means if nbimp(month demand + 3 months) >=3 ) else 0

 

date_arr is a global macro variable , it refers to the date when i m running the code (in general is the end of each month )

In my case 

date_arr  = 31/06/2017 ( i m working on some old data) 

 

Here is my code :

data hr.all_products_bis ; 
	set  hr.all_products_bis ;  
	date_check = intnx(month,&date,3,e); 
	if (date_check <= &date_arr.) then do ; 
		month_check = 100*year(&date_risk)+ month(&date_risk)) ; /* I m looking for how to save this value so that i can access the variable in the if condition below */
		if (nbimp&month_check.>=3 ) then HR_3= 1 ; 
					else  HR_3= 0 ;  
			end; 
		end; 
run ;

i hope you understand the problem

i appreciate your help

thank you Smiley Happy

Occasional Contributor
Posts: 17

Re: CALL SYMPUT LOOPING PROBLEM

sorry

 

the YYYYMM go from 201601 to 201706

Super User
Posts: 6,936

Re: CALL SYMPUT LOOPING PROBLEM

Declare an array over your nbimpYYMM variables, calculate the index from your month_check, and use that. No macro necessary.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Trusted Advisor
Posts: 1,612

Re: CALL SYMPUT LOOPING PROBLEM


Raitag wrote:

Yes i know,  i m just trying to give o basic example of my problem

what i want to do is much bigger than that


But you still haven't explained to us the problem

 

And without that explanation, you're not going to get anywhere in this forum or any other forum.

Super User
Posts: 5,081

Re: CALL SYMPUT LOOPING PROBLEM

As part of a bigger problem, perhaps macro language would be appropriate.  It's too difficult to tell from this vantage point.  At least be open to the possibility that a DATA step might be all you need.  Regardless, what you ask for is relatively simple:

 

data test;

set test;

call symput("mv", value);

value_copy = symget('mv');

run;

 

Some of the wrinkles:  CALL SYMPUT does not remove trailing blanks (but switching to CALL SYMPUTX would).  So &MV may contain trailing blanks.  And the length of VALUE_COPY is (by default, unless you set the length earlier in the DATA step) 200.

Super User
Super User
Posts: 6,499

Re: CALL SYMPUT LOOPING PROBLEM

You have a basic timing problem.  The SAS macro processor resolves the macro code to text and then SAS compiles the data step then it run the data step.  So look at this step.

data test ; 
  set test ;
  call symput("mv" , value) ;
  value_copy = "&mv" ; 
run ;

So if the value of the macro variable MV is set to z with 7 spaces after it then this is code that SAS will compile and run.

data test ; 
  set test ;
  call symput("mv" , value) ;
  value_copy = "z       " ; 
run ;

If you really need to retrieve the value of macro variable that might have changed since the data step was compiled then use the SYMGET() function.

data test ; 
  set test ;
  call symput("mv" , value) ;
  value_copy = symget("mv");
run ;
Occasional Contributor
Posts: 17

Re: CALL SYMPUT LOOPING PROBLEM

i m working on data about loans

for each loan demand i have :

- id_ demand

- date_dem : which is the date when the customer submit his demand ;

- nbimpYYYYMM : which refers to the number of registered umpaids at the end of the month YYYYMM

with YYYYMM going from 201601 to 201706 ;

 

What i want to do is to define the variable HR3 where :

HR3 = 1 if the Customer has 3 umpaids or more 3 month after the demand

(which means if nbimp(month demand + 3 months) >=3 ) else 0

 

date_arr is a global macro variable , it refers to the date when i m running the code (in general is the end of each month )

In my case 

date_arr  = 31/06/2017 ( i m working on some old data) 

 

Here is my code :

data hr.all_products_bis ; 
	set  hr.all_products_bis ;  
	date_check = intnx(month,&date,3,e); 
	if (date_check <= &date_arr.) then do ; 
		month_check = 100*year(&date_risk)+ month(&date_risk)) ; /* I m looking for how to save this value so that i can access the variable in the if condition below */
		if (nbimp&month_check.>=3 ) then HR_3= 1 ; 
					else  HR_3= 0 ;  
			end; 
		end; 
run ;

i hope you understand the problem

i appreciate your help

thank you Smiley Happy

Occasional Contributor
Posts: 17

Re: CALL SYMPUT LOOPING PROBLEM

ps :

month_check = 100*year(&date_check)+ month(&date_check))
☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 19 replies
  • 194 views
  • 0 likes
  • 7 in conversation