1
votes

I am quite new to SAS, but as far as I know I need to run Proc Nlin procedure to estimate a curve fit. I have a time series data for around 100 days, so this means I will have to come up with output consisting of 100 sets of parameters. The input data I have in Excel is:

     Date\Years 0,25    0,5 0,75    1   2   3   4   5   6   7   10
04/01/10    1,24    1,39    1,4865  1,583   2,319   2,373   2,948   2,964   3,342   3,287   3,642
05/01/10    1,26    1,39    1,4885  1,587   2,319   2,377   2,941   2,966   3,351   3,286   3,64
06/01/10    1,26    1,39    1,4895  1,589   2,318   2,376   2,945   2,974   3,32    3,276   3,635
07/01/10    1,25    1,39    1,49    1,59    2,332   2,376   2,955   2,976   3,349   3,369   3,641
08/01/10    1,25    1,39    1,4945  1,599   2,347   2,384   2,969   2,984   3,352   3,338   3,64
11/01/10    1,28    1,41    1,501   1,592   2,345   2,391   2,975   2,982   3,353   3,348   3,645
12/01/10    1,29    1,41    1,5055  1,601   2,336   2,389   2,991   2,981   3,396   3,354   3,643
13/01/10    1,31    1,43    1,5285  1,627   2,45    2,568   3,038   3,003   3,422   3,42    3,712
14/01/10    1,28    1,43    1,5265  1,623   2,424   2,558   3,04    2,998   3,384   3,287   3,686
15/01/10    1,28    1,42    1,5195  1,619   2,423   2,423   3,012   2,994   3,383   3,277   3,678
18/01/10    1,27    1,42    1,5195  1,619   2,424   2,597   3,012   2,991   3,359   3,386   3,666
19/01/10    1,29    1,44    1,5305  1,621   2,42    2,596   3,017   2,998   3,192   3,387   3,675

The model to be run:

proc nlin data=_3 method=newton;
  parms a1 = 0.05 a2 = 0.05
  a3 = 0.05 beta = 1;
   model yield=a1+(a2+a3)*(beta/years)*(1-exp(-years/beta))-a3*exp(-years/beta);

So this models fits the data well for one day, but how do I make it run for every date in my sample and store the parameters in output?

Thanks.

1

1 Answers

0
votes

proc nlin supports SAS' standard by group processing, which means that you can request that a separate analysis be carried out for each group of values in a variable (assuming the data is sorted by that variable).

To do this, first make sure the data is correctly sorted:

proc sort data = _3;
    by date;
run;

Then request by group processing with the by statement:

proc nlin data=_3 method=newton;
    by date;
    ...
run;

Further details can be found here


Edit: Answer to further question from comments.

In order to achieve what you want you need to structure your data so that the procedure can understand it. The data needs to have one date, term and rate in each row. The code below takes some sample data in the form you gave and transposes it. Then your code is used with the by statement.

/* Create some dummy data for this example */
data have;
    input date ddmmyy8. y0_25 y0_5 y0_75 y1 y2 y3 y4 y5 y6 y7 y10;
    format date yymmdd10.;
    datalines;
04/01/10 1.24 1.39 1.4865 1.583 2.319 2.373 2.948 2.964 3.342 3.287 3.642
05/01/10 1.26 1.39 1.4885 1.587 2.319 2.377 2.941 2.966 3.351 3.286 3.640
06/01/10 1.26 1.39 1.4895 1.589 2.318 2.376 2.945 2.974 3.320 3.276 3.635
;
run;

/* Transpose data so we have one row for each date/term/rate */
proc transpose data = have out = trans;
    by date;
    var y:;
run;
/* Get the term value from the column names */
data trans;
    set trans;
    years = input(compress(tranwrd(_NAME_, "_", "."), "y"), best.);
    rename COL1 = yield;
    drop _:;
run;

/* Use by group processing, store estimates, plot the line */
proc nlin data = trans method = newton outest = want plots = fit noitprint;
    by date;
    parms a1 = 0.05 a2 = 0.05 a3 = 0.05 beta = 1;
    model yield = a1 + (a2 + a3) * (beta / years) * (1 - exp(-years / beta)) - a3 * exp(-years / beta);
run;

A couple of thoughts:

  • It looks like your rates a coming from two different sources (for odd and even terms, check the graphs), I would confirm that you are picking up what you want from your source
  • Remember to include longer terms in the fitting data rather than extrapolating if you need a longer horizon