BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Golf
Pyrite | Level 9

Hi everyone,
I need help generating the first five lags of the first difference of inflation using a loop. However, I'm not getting any results for dinf_lag1 to dinf_lag5. Can someone assist me?

 

data use;
set use;

dinf = dif(inflation); /* Gerate first different of inflation */
array dinf_lag[5] ; /* Create an array of 5 variables */
do i = 1 to 5;
%let i;
%put dinf_lag[&i] = lag&i(dinf); /* Generating variable names dinf_lag1,...,dinf_lag5 */
end;
drop i; /* Drop the loop counter variable from the final dataset */
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
/*It is IML thing*/
data time_series;
input year inflation;
datalines;
1948 .
1949 -0.988480068
1950 1.053828352
1951 7.366171193
1952 2.227075801
1953 0.761468753
1954 0.351633428
1955 -0.262872574
1956 1.462744884
1957 3.277625189
1958 2.662459493
1959 0.909736704
1960 1.481626961
1961 1.058582189
1962 1.158617264
1963 1.236272118
1964 1.305567525
;
run;
proc iml;
use time_series;
read all var{inflation};
close;
dif=dif(inflation);
lag=lag(dif,1:5);
want=inflation||dif||lag;
vname={'inflation'}||('dinf_lag0':'dinf_lag5');
create want from want[c=vname];
append from want;
close;
quit;
proc print data=want;run;

Ksharp_0-1698233276147.png

 

View solution in original post

15 REPLIES 15
Patrick
Opal | Level 21

The macro statements will execute before your data step and though won't be affected in any way by your do loop.

Please provide some sample have data via working SAS datastep code and then show us the desired result for this sample data.

Golf
Pyrite | Level 9

Patrick,

Thank you for your assistance. Here's the output from the code. Additionally, can you provide a code to generate the lead variable: dinf(t+1), dinf(t+2), ..., dinf(t+5)?

Golf_0-1698215763576.png

 

This is the desired data. 

Golf_1-1698215905510.png

 

Patrick
Opal | Level 21

Please provide some sample have data via working SAS datastep code

I don't expect anyone being willing to re-engineer such source data for you based on a screenshot of a desired outcome. Please help us help you. 

We need such sample data to test whatever code we propose, we need the desired outcome and a narrative of the required logic to get from have to want. Plus actual sample have and want data also helps to remove a lot of ambiguity in narratives. 

 

Kurt_Bremser
Super User

Your code is equivalent to this:

%let i;
%put dinf_lag[&i] = lag&i(dinf);

data use;
set use;
dinf = dif(inflation);
array dinf_lag[5];
do i = 1 to 5;
end;
drop i;
run;

As you can see, the DATA step does nothing. Your first macro statement is invalid, as a %LET requires an equal sign, and the second will probably complain about the variable reference.

 

Since you seem to want five calls from LAG1 to LAG5, you either write those explicitly (no loop), or have them created in a %DO loop, for which you need to define a macro first.

%macro loop;
%do i = 1 %to 5;
  dinf_lag[&i] = lag&i(dinf);
%end;
%mend;

data use1; /* don't overwrite the dataset, or you run the risk of destroying your work up to that point */
set use;
dinf = dif(inflation);
array dinf_lag[5];
%loop
run;
Golf
Pyrite | Level 9

Hi Kurt_Bremser,

Thank you for helping me with this problem. Can you provide a code to generate the lead variable dinf(t+1), dinf(t+2), ..., dinf(t+5) using a loop?

@Kurt_Bremser 

Kurt_Bremser
Super User

@Golf wrote:

Hi Kurt_Bremser,

Thank you for helping me with this problem. Can you provide a code to generate the lead variable dinf(t+1), dinf(t+2), ..., dinf(t+5) using a loop?

@Kurt_Bremser 


Please supply example data in a working DATA step with DATALINES, and show the expected result.

Golf
Pyrite | Level 9

@Kurt_Bremser 

Here is my desired data for lead variables.

Golf_0-1698217792936.png

I use the simple codes as follows:

proc expand data= ch6dols.time_series out=ch6dols.time_series;

convert dinf = dinf_lead1 / transform=(lead 1);
convert dinf = dinf_lead2 / transform=(lead 2);
convert dinf = dinf_lead3 / transform=(lead 3);
convert dinf = dinf_lead4 / transform=(lead 4);
convert dinf = dinf_lead5 / transform=(lead 5);
convert dinf;
run;

 

I would like to know how to generate this dataset in a loop. It would be helpful to generate longer leads and lags.

 

Thank You.

 

Kurt_Bremser
Super User

Please supply example data in a working DATA step with DATALINES.

 

We need to see with what you start initially (the original ch6dols.time_series, before conversion).

No pictures, code text which we can copy to our program windows.

Golf
Pyrite | Level 9

@Kurt_Bremser 

Here is the codes:

PROC IMPORT DATAFILE="/home/u45083887/my_content/SM518/SM518 Ch5/time_series_ex1.xlsx"
OUT=Ch6DOLS.time_series
DBMS=XLSX
REPLACE;
RUN;

data ch6dols.time_series;
set ch6dols.time_series;
dinf = dif(inflation);

proc expand data= ch6dols.time_series out=ch6dols.time_series;

convert dinf = dinf_lead1 / transform=(lead 1);
convert dinf = dinf_lead2 / transform=(lead 2);
convert dinf = dinf_lead3 / transform=(lead 3);
convert dinf = dinf_lead4 / transform=(lead 4);
convert dinf = dinf_lead5 / transform=(lead 5);
convert dinf;
run;

proc print data = ch6dols.time_series;
var dinf dinf_lead1 dinf_lead2 dinf_lead3 dinf_lead4 dinf_lead5;
run;

Thank You.

andreas_lds
Jade | Level 19

While having a cup of coffee, i repeat what as been asked twice already:

Please supply example data in a working DATA step with DATALINES.

We don't have access to your Excel file and many of us won't open excel files attached to posts.

Golf
Pyrite | Level 9
Here it is.
data time_series;
input year inflation;
datalines;
1948 .
1949 -0.988480068
1950 1.053828352
1951 7.366171193
1952 2.227075801
1953 0.761468753
1954 0.351633428
1955 -0.262872574
1956 1.462744884
1957 3.277625189
1958 2.662459493
1959 0.909736704
1960 1.481626961
1961 1.058582189
1962 1.158617264
1963 1.236272118
1964 1.305567525
;
run;

Thanks
Kurt_Bremser
Super User

When I combine your data with the picture of the wanted data, I think I see this:

  • you create, for every observation, the difference to the previous year
  • then, you look ahead for this difference 1 to 5 years

To do this with DATA step logic, you first have to calculate the difference, and then do the look-ahead. One method for this look-ahead is to sort the intermediate dataset in reverse and use LAG1 to LAG5; another method is a 6-way MERGE of the intermediate dataset with itself, where you use increasing FIRSTOBS= options.

Golf
Pyrite | Level 9

@Kurt_Bremser 

Thank you for your help. I will try your suggestion.

Ksharp
Super User
/*It is IML thing*/
data time_series;
input year inflation;
datalines;
1948 .
1949 -0.988480068
1950 1.053828352
1951 7.366171193
1952 2.227075801
1953 0.761468753
1954 0.351633428
1955 -0.262872574
1956 1.462744884
1957 3.277625189
1958 2.662459493
1959 0.909736704
1960 1.481626961
1961 1.058582189
1962 1.158617264
1963 1.236272118
1964 1.305567525
;
run;
proc iml;
use time_series;
read all var{inflation};
close;
dif=dif(inflation);
lag=lag(dif,1:5);
want=inflation||dif||lag;
vname={'inflation'}||('dinf_lag0':'dinf_lag5');
create want from want[c=vname];
append from want;
close;
quit;
proc print data=want;run;

Ksharp_0-1698233276147.png

 

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 15 replies
  • 3878 views
  • 5 likes
  • 5 in conversation