- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
I work in models risk development and i my team is having some problems in making a macro code to work properly.
For example:
In table 1 i have some contracts and their historical interest rates along their lifetime period:
the field:
- firstvalue Identifies the first month of life of the contract;
- lastvalue Identifies the last month of life of the contract;
- contador identified the number of months in which the contract was alive;
- k enumerates each contract;
from this table i construct table 2 (tab1 in the code below), which identifies the months in which there were changes in the interest rate of the contracts:
From here, our goal is to calculate the median of the duration in months until a new repricing occurs, meaning that we want to obtain table3, in which the fields "contador_1, _2, _3" count the number of months that each contract mantained the same interest rate. The final step will then be the calculation of the median of these fields "contador_1, _2, _3" for each contract.
The code we are using to obtain table 3 (tab2 in the code below) from table 2 (tab1 in the code below), is where we are having problems and it is the following:
rsubmit; %macro teste1; %global first dif; data median.tab2; set median.tab1 ; %do i=1 %to 10; call symput('first',firstvalue); call symput('dif',dif_&i.); %put &i.; %put &first.; %put &dif.; %if (&i. >= %sysfunc(inputn(&first. ,best31.)) and %sysfunc(inputn(&dif.,best31.)) = 0 ) %then %do; contador_&j. = contador_&j. + 1; %end; %else %if (&i. >= %sysfunc(inputn(&first. ,best31.)) and %sysfunc(inputn(&dif.,best31.)) = 1 ) %then %do; %let j= %eval(&j.+1); %put condicao else if &j. ; contador_&j. = 1 ; %end; %else %do; %put condicao do &j. ; %put condicao do &i.; %end; %end; run; %mend teste1; %teste1; endrsubmit;
this code seems right but it is not producing the results we want (there aren't any errors but the results are not correct). We think that the problems has something to do with "call symput" because we are having problems in defining the variables correctly.
Can you please help us understand what we are doing wrong in this code?
Thank you.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
" We think that the problems has something to do with "call symput" because we are having problems in defining the variables correctly."
Why do you think that? What is the evidence?
One thing, the MACRO pre-processor does all its work before the data step executes. So macros do not see the value of data step variables. Second, macro variables created with Symput or Symputx don't exist at the time the macro pre-processor does its thing either. So the created "variables" don't exist either.
Placing yellow text on a white background makes trying to follow your example tedious. This has been known since the Middle ages, i.e. a thousand years or so. If you highlight in a contrasting color like red, blue or green your post is more legible.
I am not sure that I actually follow the connection between: "changes in the interest rate" and " months until a new repricing occurs".
There is NO need for any of the syput, %sysfunc(input ). The proper tool to do the same calculations using multiple variables like this would be an array, or likely two arrays.
Here is a brief example of examining the values of a loop counter, Firstvalue and DIF variables.
data example; set median.tab1 ; array d (*) dif1-dif10; array c (10) contador_1 - contador_10; do i=1 to dim(d); if i ge firstvalue and d[i] =0 then put "first compare " i= firstvalue=- d[i]= ; else if i ge firstvalue and d[i] = 1 then put "second compare " i= firstvalue=- d[i]= ; else put "third block " i= firstvalue=- d[i]= ; end; run;
Your code does not show where "&j" is set so I can't attempt to translate your code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
This doesn't answer your question directly, but macros are not needed here. An ARRAY in a data step can work, and would be much simpler than macros.
One of the problems in your code is that CALL SYMPUT creates a macro variable from within a data step, but that macro variable is not usable in that data step, it is not available until that specific data step where it is created ends. Which is another argument for using ARRAYs, which do not have this limitation.
Paige Miller
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
" We think that the problems has something to do with "call symput" because we are having problems in defining the variables correctly."
Why do you think that? What is the evidence?
One thing, the MACRO pre-processor does all its work before the data step executes. So macros do not see the value of data step variables. Second, macro variables created with Symput or Symputx don't exist at the time the macro pre-processor does its thing either. So the created "variables" don't exist either.
Placing yellow text on a white background makes trying to follow your example tedious. This has been known since the Middle ages, i.e. a thousand years or so. If you highlight in a contrasting color like red, blue or green your post is more legible.
I am not sure that I actually follow the connection between: "changes in the interest rate" and " months until a new repricing occurs".
There is NO need for any of the syput, %sysfunc(input ). The proper tool to do the same calculations using multiple variables like this would be an array, or likely two arrays.
Here is a brief example of examining the values of a loop counter, Firstvalue and DIF variables.
data example; set median.tab1 ; array d (*) dif1-dif10; array c (10) contador_1 - contador_10; do i=1 to dim(d); if i ge firstvalue and d[i] =0 then put "first compare " i= firstvalue=- d[i]= ; else if i ge firstvalue and d[i] = 1 then put "second compare " i= firstvalue=- d[i]= ; else put "third block " i= firstvalue=- d[i]= ; end; run;
Your code does not show where "&j" is set so I can't attempt to translate your code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your help!