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 ;
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.
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.
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 ;
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:
If you have a specific need to use symput, please define the scenario.
Stop abusing the macro processor for something it is not designed for. This can be VERY simply done with data step code.
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
@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.
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 🙂
sorry
the YYYYMM go from 201601 to 201706
Declare an array over your nbimpYYMM variables, calculate the index from your month_check, and use that. No macro necessary.
@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.
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.
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 ;
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
ps :
month_check = 100*year(&date_check)+ month(&date_check))
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.