DYNAMICLINEAR Procedure

Simultaneous Graphical Dynamic Linear Models

This example is designed to demonstrate the process of defining a simultaneous graphical dynamic linear model (SGDLM) within PROC DYNAMICLINEAR. SGDLMs, known for their advanced approach in handling dynamic, multivariate time series data, offer a robust framework for modeling complex interactions over time. For a deeper dive into the mechanics and applications of SGDLMs, including their unique strengths and how they can be effectively used in various scenarios, see the section Simultaneous Graphical Dynamic Linear Models.

The following DATA step loads the sample data:

data mylib.test_data;
   input t MMDDYY10. y1 y2 y3 y4 y5 BEST12.;
   format t MMDDYY10. y1 y2 y3 y4 y5 BEST12.;
datalines;
01/03/2002  1.158633277 -0.165838131 -0.220000432  0.08356095   0.097975091
01/04/2002 -0.995606401 -0.557778703  0.677071567  0.854087381  1.521078958
01/07/2002  1.494689626  1.200269513 -0.757267367 -0.468820299  1.558016222
01/08/2002  0.336831213  0.21765148   0.178311073  0.718694403 -1.277531854
01/09/2002  2.605081293  0.088138021 -0.95800973  -0.440623956  0.027367858
01/10/2002  1.365290757  0.207851726 -0.778749273  0.483102741 -0.259593807
01/11/2002  1.287939549 -0.625462152 -0.844034609  0.841906761  0.108750805
01/12/2002 -0.951405914 -0.272690273 -0.261733034 -2.068829141  0.671949044
01/13/2002  0.679413851  1.228575289 -0.840836877  1.124017627  0.185222142
01/14/2002  0.012315804  1.449826749 -0.424428315 -0.841630952 -0.431210039
;

Parental sets play a pivotal role in the structure and effectiveness of SGDLMs. According to Gruber and West (2016) and Gruber and West (2017), SGDLMs are adept at extracting correlations among time series, largely because of their sophisticated structural design that involves parental sets. For a more comprehensive understanding of parental sets, including their definition and importance in SGDLMs, see the sections PARENTALSET Statement and Parental Sets of Simultaneous Graphical Dynamic Linear Models. The following code produces the parental sets for the provided sample data, illustrating their configuration within the model:

data mylib.adj_table;
   input ChildID ParentID;
datalines;
2               1
3               1
3               2
4               2
2               3
4               3
2               4
3               4
3               5
4               5
1               5
;

In SGDLMs, it is assumed that the observations adhere to a normal-gamma distribution, and their progression is tracked using the Kalman filter. PROC DYNAMICLINEAR offers multiple methods of defining the initial posterior distribution of these models. The following SAS code shows how to create input data tables that determine the initial means and covariances for SGDLMs. These tables are subsequently used in the INITIALDISTRIBUTION statement to set up the model’s initial state.

data mylib.init_mean;
   input varname $1-4  varid parmname $24-40 parmid parmvalue;
datalines;
y1                1    Const                  1     0.008596271
y1                1    ParSet_1               2     0.041964947
y1                1    ParSet_2               3     0.367778311
y2                2    Const                  1    -0.004223895
y2                2    ParSet_1               2    -0.002395241
y2                2    ParSet_2               3     0.022385176
y3                3    Const                  1     0.003904836
y3                3    ParSet_1               2     0.047429031
y3                3    ParSet_2               3    -0.489922549
y4                4    Const                  1    -0.05762658
y4                4    ParSet_1               2     0.075128833
y4                4    ParSet_2               3    -0.224003793
y5                5    Const                  1    -0.104497114
y5                5    ParSet_1               2    -2.129695978
y5                5    ParSet_2               3     0.047091226
y5                5    ParSet_3               4    -0.31115146
;

data mylib.init_cov;
   input ParmValue_1 ParmValue_2  ParmValue_3 ParmValue_4  RowID;
datalines;
0.008068698      -0.000016642     -0.000191582       0                   1
-0.000016642      0.040067528     -0.000022887       0                   2
-0.000191582     -0.000022887      0.350903386       0                   3
0.003999164      -6.19E-7         -3.51E-6           0                   4
-6.19E-7          0.002287045     -6.4E-8            0                   5
-3.51E-6         -6.4E-8           0.021373754       0                   6
0.003699612      -8.63E-6         -0.000071039       0                   7
-8.63E-6          0.04528632      -0.000021115       0                   8
-0.000071039     -0.000021115      0.46764184        0                   9
0.049313412      -0.000182135     -0.000713341       0                   10
-0.000182135      0.07172781      -0.000022758       0                   11
-0.000713341     -0.000022758      0.213791508       0                   12
0.270791097      -0.001387886     -0.064982122      -0.019065019         13
-0.001387886      0.10090566      -0.000259538      -0.000076145         14
-0.064982122     -0.000259538      4.712605925      -0.003565199         15
-0.019065019     -0.000076145     -0.003565199       0.29606287          16
;

This initial setup is crucial, because it forms the foundation on which the model builds its subsequent forecasts and analyses. For a thorough understanding of how to configure the initial distribution in SGDLMs, see the section INITIALDISTRIBUTION Statement.

The INITIALDISTRIBUTION statement enables you to continue analyzing a previously saved SGDLM. This is particularly effective when you use it along with the OUTFILTERINFO= option in the FILTER statement. Together, these features allow for a seamless continuation of model analysis from a saved state, ensuring the integrity and consistency of the SGDLM’s progression over time.

DLMs use discount factors to regulate the proportion of state evolution error variance that is considered during the model’s evolution. For more information, see the section Discount Factors in Dynamic Linear Models. The following code shows how to use PROC DYNAMICLINEAR to fit an SGDLM to a given data set. In this example, the discount factors are defined using the DISCOUNTFACTOR statement.

proc dynamicLinear data=mylib.test_data;
   id t;
   model y1-y5;
   parentalSet inAdjacency=mylib.adj_table;
   filter out(percentiles=(2.5 50 97.5))=mylib.out_filter back=0;
   forecast out(percentiles=(2.5 50 97.5))=mylib.out_forecast lead=3;
   initialDistribution inMean=mylib.init_mean inCovariance=mylib.init_cov
      shape=(positions=(1 2 5) values=(20 30 40));
   discountFactor deltaGamma=(positions=(3 5) values=(0.997 0.998));
run;

Upon successful execution of the preceding code, you can review the model’s summary tables in Figure 1, which provides insight into the fit and performance of the SGDLM.

Figure 1: Model Summary

The DYNAMICLINEAR Procedure

Model Information
Number of Variables Used5
Simulation Size10000
Random Number Seed12345
Forecast Lead3
Filter Back0
Filter Lead1

Number of Observations10
Number of Observations Used10

Input Tables
NameContentsNumber of RowsNumber of Columns
TEST_DATAData106
ADJ_TABLEAdjacency Matrices112
INIT_MEANMeans165
INIT_COVCovariances (Full)165

Output CAS Tables
CAS LibraryNameNumber
of Rows
Number
of Columns
CASUSER(chuaxu)OUT_FORECAST328
CASUSER(chuaxu)OUT_FILTER928


An example output of the forecasting results that the model generates is shown in Figure 2. The following PROC PRINT code prints the forecasting statistics that are generated by the OUT= option in the FORECAST statement:

proc print data=mylib.out_forecast;
run;

Figure 2: Example Output of Forecasting Results

ObstLeadStepMean_y1Variance_y1P2_5_y1P50_y1P97_5_y1Mean_y2Variance_y2P2_5_y2P50_y2P97_5_y2Mean_y3Variance_y3P2_5_y3P50_y3P97_5_y3Mean_y4Variance_y4P2_5_y4P50_y4P97_5_y4Mean_y5Variance_y5P2_5_y5P50_y5P97_5_y5RowID
101/14/200210.05622878431.6740409231-2.5510301490.06173297672.58535549590.00300488960.2458605001-0.980921870.00123535020.9947060545-0.0193794040.6742365123-1.63017889-0.0218606371.60881527660.02497641760.9116031811-1.9170113530.0333187871.88369820770.39637923870.6318790441-1.1287079870.39415735692.0158043291
201/14/200220.0517924141.689381942-2.6311421910.06907829012.62539355280.00264591880.2477405635-0.9754750030.00316446770.983248444-0.0157770410.6780195983-1.638780493-0.0199073681.62046972680.02789518030.9193195028-1.8708954880.03311196371.89756156870.39537981750.6299070777-1.1689208070.39298883961.98602436512
301/14/200230.05403131571.6909249168-2.6041985310.0621650892.62756298850.00279799180.2484346856-0.9876496830.00067231751.0001381185-0.0177782130.6803869184-1.653028696-0.0190503421.61396031590.02398344210.9381107425-1.9073748260.03058629021.91752055010.39805156110.6431627646-1.1530803090.39559470842.00305554693


Additionally, an example of the filtering results that the model generates is shown in Figure 3. The following PROC PRINT code prints the first three observations of the forecasting statistics that are generated by the OUT= option in the FILTER statement:

proc print data=mylib.out_filter(obs=3);
run;

Figure 3: Example Output of Filtering Results

ObstLeadStepMean_y1Variance_y1P2_5_y1P50_y1P97_5_y1Mean_y2Variance_y2P2_5_y2P50_y2P97_5_y2Mean_y3Variance_y3P2_5_y3P50_y3P97_5_y3Mean_y4Variance_y4P2_5_y4P50_y4P97_5_y4Mean_y5Variance_y5P2_5_y5P50_y5P97_5_y5RowID
101/03/20021-0.054443041855.25543349-3.0496098810.01593666822.87341030270.1601617164577.91896746-1.052842183-0.018472810.9765916156-1.64424254150108.636773-4.4961042560.02519240044.60383039850.996414312625474.95232-3.679928735-0.0560308223.630336531-0.48101555141789.705442-10.42614548-0.09158167110.8676443771
201/04/20021-0.265953197415.77670547-2.1586010340.0329608542.2092917348-0.0303856222.8241685107-0.997871327-0.0205012440.94193122130.40693386081480.2701993-3.6337211890.01486927153.3896686134-0.271851459520.40410236-2.839657981-0.0389346392.884275991-0.52444044226815.660623-13.48600250.879755224114.7314931332
301/07/20021-0.363511487428.55045744-1.9194943270.00098721121.9481959368-0.06454362828.362208296-0.920294573-0.0322850130.87038514270.4065960356647.68497031-2.0752842730.00868311182.1646463090.1948211869675.7931971-1.9085740620.03472321432.02848606390.76927506561807.6712956-3.1217397761.12227318885.51487199723


The following SAS code is designed to create a visual representation of the empirical confidence interval for the variable y1. An empirical confidence interval offers an estimate of the range within which you expect to find the true value of y1 a certain percentage of the time, according to the sample data. This code produces a plot that showcases the variability of y1, with the empirical confidence interval demarcated, thus providing a visual assessment of the precision of y1’s estimated values within the model. The results are shown in Figure 4.

data y1_comb;
   format t MMDDYY10. Mean_y1 P2_5_y1 P50_y1 P97_5_y1 Best12.;
   set mylib.out_filter(keep=Mean_y1 P2_5_y1 P50_y1 P97_5_y1);
   set mylib.test_data(keep=t y1 where=(t>'03Jan2002'd));
run;

proc sort data=y1_comb;
   by t;
run;

proc sgplot data=y1_comb;
   band x=t upper=P2_5_y1 lower=P97_5_y1 / transparency=.3
      legendlabel='95% Empirical C.I.s';
   series x=t y=y1 / legendlabel='Actual Values of y1'
      markers markerattrs=(color=red size=5 symbol=circlefilled)
      lineattrs=(color=red pattern=shortdash);
   series x=t y=Mean_y1 / legendlabel='Mean_y1'
      markers markerattrs=(color=blue size=5 symbol=triangle)
      lineattrs=(color=blue pattern=solid);
   series x=t y=P50_y1 / legendlabel='Median_y1'
      markers markerattrs=(color=cyan size=5 symbol=circle)
      lineattrs=(color=cyan pattern=solid);
   label t="Date" y1="Values";
run;

Figure 4: Empirical Confidence Intervals of Variable y1

Empirical Confidence Intervals of Variable y1


The prior example demonstrates how to specify parental sets, initial distributions, and discount factors in PROC DYNAMICLINEAR. It is important to note that these statements are optional, offering flexibility according to the user’s needs and expertise. Additionally, for generating plots of confidence intervals, the data that are specified in the OUT= option of the FILTER statement are essential.

PROC DYNAMICLINEAR is designed with a high degree of flexibility to cater to a wide range of users. This includes those who are primarily interested in forecasting outcomes but might not have extensive knowledge of model configuration. For such users, a simpler and more concise code setup can be just as effective. The following code is an example of such a streamlined configuration, which is aimed at maximizing ease of use and accessibility:

proc dynamicLinear data=mylib.test_data;
   id t;
   model y1-y5;
   parentalSet inAdjacency=mylib.adj_table;
   forecast out=mylib.out_forecast lead=3;
run;

This simplified approach enables users to take advantage of the powerful forecasting capabilities of PROC DYNAMICLINEAR without the need to delve into more complex configuration details.

Last updated: July 09, 2026