GAUSS>

Table of Contents

Goals, Objectives and Prerequisites

Goals

The goal of this document is to provide the new Gauss user at American University with the basic framework for writing statistical programs.

Objectives

After reading this document, the new GAUSS user should be able to:

  1. Write a Gauss program.
  2. Use Gauss comment commands to label program results, as well as to write comments within the program.
  3. Conduct statistical analysis using Gauss procedures.

Prerequisites

This document is for people who:

  1. Need to utilize the Gauss programming language.
  2. Have taken, or are taking, an Econometrics course at American University.

Introduction

Gauss is a mathematical programming language used mostly in economics and engineering. At American University, Gauss can be accessed from work stations in the Social Science Research Lab (Hurst Lab) or in the Business School Computer Lab (KOGOD Lab). NOTE: In the Hurst Lab, Gauss is available on ONLY two designated work stations.

Creating Programs

Gauss can be used interactively OR in the EDIT MODE. It is recommended that you use the EDIT MODE to create your program and run the entire program.

Entering the EDIT MODE

If you wish to use the program interactively, then you just enter commands at the Gauss prompt. But if you wish to create a batch (program) file you must enter the following command in order to go into the EDIT mode:

EDIT DRIVE:FILENAME

where FILENAME refers to the name of the file into which the program is to be stored, and DRIVE refers to the drive containing
the computer disk. Therefore, if the disk is in drive A and the
file name is CP1.PRG, then write the command as:

EDIT A:CP1.PRG

If the file already exists it will be displayed ready to be edited. But if the file does not exist, a message NEW FILE will be displayed for about one second, and then a blank screen will appear. The new file can be created using the normal editing commands. If you want to modify a file that already exist but still want to keep the original file, it is recommended that you use the keystroke ALT-O to rename your modified file first before you press F-2 or ALT-W to save/execute the file. Otherwise, the original file will be overwritten.

Exiting Edit Mode

Exiting the EDIT mode is accomplished by pressing ALT-X. A menu bar will appear:

WRITE Write edited file to disk.
QUIT Quit edit without saving file.
EXECUTE Save and execute file. Execution time line number will not be tracked.
RUN Save and execute file. Track execution time line numbers.

Block Commands

Block commands can be used to cut and paste blocks of text and to form the scrap bin, print, write, delete, indent or execute blocks of text. The commands for block operation are:

ALT-L Toggle block on and off.
ALT-P Print block.
ALT-W Write block to file.
CTRL-X Execute block.
DELETE Keypad Delete block.
INSERT Keypad Insert scrap at cursor line.
GRAY/KEYPAD + Copy block to scrap, then press INSERT to get it pasted at cursor.
GRAY/KEYPAD - Cut block to scrap.

Keystroke List

The following is a list of the editing keys supported in the GAUSS editor.

ALT-D Delete line.   CTRL-PGDN Delete below cursor.
ALT-G Go to line______.   CTRL-PGUP Delete above cursor.
ALT-P Print block.   CTRL-ENTER Carriage return.
ALT-R Read in file at cursor.   F1 Save file and exit; recall previous screen.
ALT-I Toggle insert mode.   SHIFT-F1 Edit last edited line.
F5,ALT-S Search.   F7 View error log file.
SHIFT_F6 Search next.   CTRL-F3 Edit last output file.
CTRL-E Save screen to file.   SHOW Displays the global symbol table.
CTRL-R Delete word right.   F2 SAVE and EXECUTE the program.
CTRL-X Execute block.   F6,ALT-T Translate (replace) text.
CTRL-N Insert hard linefeed.   SHIFT-F6 Translate again.
ESCAPE Exit GAUSS.   CTRL-F5 Toggle case.

 

Gauss Syntax

The ORDER of commands sometimes makes a great difference in how Gauss processes data. Pay close attention to manuals detailing instructions regarding the order of commands and related options, subcommands, and variables. The reader should also be aware that all variables in Gauss are treated as matrices. This means that all operations must adhere to the rules of matrix algebra. Finally, all Gauss statements end with a semicolon.

Defining Data Data definition parts of the program tell Gauss the following:

  1. The NAMES of all the VARIABLES in the DATA SET
  2. The POSITION of each VARIABLE in the DATA SET
  3. The names of NEW VARIABLES created from the VARIABLES in the DATA SET

Gauss data sets are treated as matrices. Suppose we have three data points for three variables X, Y, and Z. Then we can define the matrix W containing this data in two different ways:

1) W = {1 4 7, 3 5 9, 2 3 7};

2) LET W[3,3] = 1 4 7 3 5 9 2 3 7;

The matrix W has dimensions (3 x 3); there are three data points for each of the three variables. Suppose that all the data for variable X is located in the first row, all of W's in row 2, and all of Z's in row 3. In option number 1 above, this is indicated by separating the rows with a comma. In the second option a LET statement is used to define W. The variables X, Y, and Z can be defined in the following way:

X = W[1,.];

Y = W[2,.];

Z = W[3,.];

This says that the values of the variables X, Y, and Z are in rows one, two, and three, respectively. And the variables are interpreted by Gauss as being (1 x 3) matrices (vectors). The column and row position of each variable is given by the expression in the square bracket next the matrix name W. The first number within the brackets denotes the row position, and the character after the comma indicates the column position. If a period is used to denote column position, it means that all columns of W are included. Suppose, however, that instead of specifying all of the columns, we only want the first two. Then we can, say, define a variable C as:

C = W[1,1:2];

This new vector contains all of the values of vector X, except for the one in the third column. Finally, variables can also be defined as the columns of a given matrix. Suppose that instead of defining X, Y, and Z as being the rows of W we define them as being, respectively, the first, second, and third columns of W. Then we can write X, Y, and Z in Gauss code as:

X = W[.,1];

Y = W[.,2];

Z = W[.,3];

Reading Data

Data can be read into the Gauss program from three (3) sources. Firstly, data may be read into Gauss from within the Gauss Program file itself. This method of reading the data is described in the Defining Data section of this document. A second way you may read data into Gauss is by using an external ASCII file containing the data. If the data for matrix W (see the defining data section of this document) was present in an ASCII text file (called A:MYFILE.DAT) in the following form:

1 4 7

3 5 9

2 3 7

then, the information could be read into Gauss using the LOAD command.

LOAD W[3,3] = A:MYFILE.DAT;

NOTE: For this command to work, the external file (A:MYFILE.DAT) must exist, and must have 3 rows and 3 columns of data. You will get an error message from Gauss if the external file referenced here has more than three columns and/or more than three rows. Also, the file must exist on the A: drive. Lastly, data once read into Gauss, can be saved as a ``GAUSS DATA SET''. Gauss data sets can be external files that may be read in other GAUSS programs without redefining the variable names. Defining Gauss Data Sets allows you to give columns of the matrix specific variable names, which is useful in some procedures. However, the syntax for defining Gauss Data Sets is more complex and beyond the scope of this document. You may refer to the Gauss Manuals to learn more about defining Gauss Data Sets.

Data Transformation

To repeat, all variables defined in Gauss are treated as matrices. Even a variable containing a single value (a scalar) is defined as a (1 x 1) matrix. This means that operations can only be performed if matrices are conformable, and if they satisfy the conditions set by the theory of matrices. For example, two matrices can be summed only if they have the same dimensions. And, obviously, only nonsingular matrices can be inverted.

A = X + Y; A is the sum of X and Y   A = (C*B)+D; The above operations can be combined.
A = X+Y[2,.]; A is the sum of X and row 2 of Y.   A = B'; A is the transpose of B.
A = X - Y; A is the difference of X and Y.   A = A'; A is redefined to equal its transpose.
A = X[.,1]-Y; A is the difference of the first of X and Y.   Y = X!; This computes the factorial of every element in the matrix X.
A = X * Y; A is the product of X and Y.   Y = X.*Z; This is an element-by-element multiplication. The "outer product" or "table" of the two will be computed if X is a column vector, and
Z is a row vector (or vice versa).
A = X'Y; A is the product of X transpose and Y.    
A = X[1,.]*Y; A is the product of the first row of X and Y.    
    Y = X.*.Z; Y is the Kroneckor (tensor) product of X and Z.

There are also a large number of relatively complex operations which can be performed using a single command. Some of the most important ones are listed below:

A = INV(B); A is the inverse of matrix B.
A = SQRT(B); A contains the square root of the elements of B.
A = DIAG(B); A contains the elements in the principal diagonal of B.
A = SUMC(B); A contains the sum of the elements in each column of B.
A = SUMC(B'); A contains the sum of the elements in each row of B.
A = STDC(B); A contains the standard deviations of the elements in each column of B.
A = LAG1(B); A contains the lagged values of B by one period.
A = LAGN(B,N); A contains the lagged values of B by N periods.
A = PACKR(B); A contains only those rows of B that do not have missing values in any of their elements.
A = ONES(10,1); A is a 10x1 matrix and all the elements of A equal to 1.
A = ZEROS(10,1); A is a 10x1 matrix and all the elements of A equal to 1.
A = EYE(10); A is a 10x10 identity matrix.
A = RNDN(r,c); A is a rxc matrix of normal random numbers having a mean of zero and a standard deviation of one.
A = ABS(B); A contains the absolute values of B.
Y = ROWS(B); Y is the number of rows in B.
Y = COLS(B); Y is the number of columns in B.
Y = DET(B); Y is the determinant of B.

Do Loops

Do Loop allows code to be executed in a loop. The following is a simple example:

a = zeros(10,1);
i = 1;
do while i<11;
a(i,1) = i;
i = i + 1;
endo;
"a=";; a;


With Do While, loop will be executed if the scalar expression followed is true; With Do Until, it is just the opposite.

How To Use Help On Gauss

Getting general help for Gauss is obtained by pressing ALT-H, then typing ? will give you the index of help, you can keep pressing pagedown keypad till you see the information you need. Typing ?? will give you list of all the operators in Gauss, type h and it will ask for the name of operator, put in the name of the operator and it will show the detail information on the operator. The help system also includes context sensitive help while in all of the pop-up menus and input screen.

Utility Commands

The utility commands are used to print titles, subtitles, or other comments in your program, and to generate comments as part of your program output. Visual reading of Gauss programs is often facilitated by the use of comments written in the program. Comments can be used to maintain track of the different functions being performed, as well as for ``debugging'' the program if it contains errors. They can be written into the program using the following syntax:

/* COMMENT */

As an example, consider

/* Computation of OLS Parameter Estimates */

Notice that writing a comment into a program requires no more than opening the comment with /* and closing it with */. If this is not done correctly, Gauss will attempt to read your comment as a command. Gauss will respond to this by stopping command execution until the error is eliminated. Comments are also frequently used to describe the type of output being produced. These comments are generated by inserting the appropriate commands in the Gauss program.

"COMMENT";

Consider the following example:

"OLS Parameter Estimates";

bhat;


Notice, first, that the comment OLS Parameter Estimates is part of a Gauss command. (Both lines in the example above end in a semicolon.) Second, comments are enclosed within quotation marks. The first line of the example indicates which comment is to be generated as part of the output. The second line tells Gauss to print out the OLS parameter estimates, bhat. In the output, a print out of bhat will immediately follow the comment command because this is the order of commands.

Procedures

Since Gauss is a programming language, it can do an undetermined number of procedures--any procedure can be programmed in Gauss. Procedures are separately defined sections of the program. In most statistical programs, like SAS and SPSSx, procedures are invoked by simply writing one or two key words. Unfortunately, calling up a procedure in Gauss is usually more difficult. First of all, most procedures must be written by the user. In prepackaged programs like SAS and SPSSx, they are preprogrammed. For example, a researcher applying the Seemingly Unrelated Regressions (SUR) technique in SAS simply enters a single command. In Gauss, however, to estimate the SUR coefficients the researcher must define the "stacked" model and the contemporaneous covariance matrix, and perform numerous manipulations (such as inverting the covariance matrix and multiplying matrices).

Defining a Procedure

The following is an example of the syntax used to define a procedure:

PROC(1)=NAME(X,Y);

LOCAL A,B,C;

A = SQRT(X);

B = SQRT(Y);

C = A*INV(B)'X;

RETP(C);

ENDP;


This is an example of a procedure which is assigned the name NAME(X,Y). The matrix arguments of this procedure are X and Y. More specifically, the procedure incorporates matrices X and Y in order to return the matrix C (defined as C = A*INV(B)'X). The RETP statement is used to return the desired matrix (or matrices). Notice that in the above example only one matrix is being returned. This is why the number one has been placed in parenthesis next to the word PROC. If, on the other hand, two matrices were being returned, then the number in parenthesis would be changed from one to two. The two matrices would be specified in the RETP statement and separated by a comma. However, if the desire is to return no items, then the RETP statement is optional. The LOCAL statement in the second line of the sample procedure is used to declare local variables. Local variables are variables known only to the procedure being defined. The names used in the argument list of the PROC statement are always local. If all variables in the procedure are local, the LOCAL statement may be written as:

LOCAL *;

Finally, the procedure must end with the ENDP statement. If this statement is not used, the program will not be fully executed, and an error message will be given.

Invoking a Procedure

Procedures are invoked (called) like so:

  1. No returns from the procedure
    CALL NAME(X,Y);
  2. One return
    W = NAME(X,Y);
  3. Multiple returns
    {W,Z} = NAME(X,Y);
The example of multiple returns does not correspond to the sample procedure given above since only one return was specified. An example of a multiple return procedure is:

PROC(2)=NAME(X,Y);

LOCAL A,B,C,D;

A = SQRT(X);

B = SQRT(Y);

C = A*INV(B)'X;

D = X'X;

RETP(C,D);

ENDP;


Several Points To be noted in Writing a Gauss Program

  • Always write ``New;" in the beginning of your program, so the program when run, will reset all existing matrixes (dataset) from the memory. This is useful in avoiding conflicting matrix/sector/scalar names.
  • To save the output file on your disk, write output file=DRIVE:FILENAME.ext reset; immediately after New;, so output can be saved with the name given, and reset will allow the output file to be overwritten instead of being appended every time you run the program. FILENAME refers to the name of the file into which the output is to be stored, and DRIVE refers to the drive containing the computer disk. If you forget to specify your drive, then the file will not be saved on the disk you want to save on, and you may not be able to view it.
  • Write output off; end; at the end of the program.
  • To print out the syntax and output file (both of them are ASCII files), open the file in any word processor (WP, MS, or DOS editor), and print it using the print feature of that word processor. After printing, remember to save the file under another name if you need to run the original program later.

The following is an example including output file location and name declaration; random number generation; definition of a procedure (a simple OLS estimation); calling of the procedure; comments; and displaying/writing results to the defined output file.

New;
output file=A:cpr.out reset;
x=rndn(100,1);
y=rndn(100,1);
proc(1)=est(x,y);
local C;
C=inv(x'x)*x*y;
retp(C);
endp;
A=est(x1,y1); /* You have to load the variable
x1 and y1 before you call this procedure.*/
"A=";
A;
output off;
end;

A more complex example of Iterated Cochrane-Orcutt estimation procedure will be provided here for reference. This as well as other source code can be obtained from the GAUSS Source Code Archive at American University created and maintained by Alan G. Isaac at http://gurukul.ucc.american.edu/econ/gaussres/GAUSSIDX.HTM.

/*****************************************************************

Proc: CORC
Author: Alan G. Isaac aisaac@american.edu
Last Update: August 1996
Format: bt = corc(y,x,rho);
Purpose: computes iterated Cochrane-Orcutt regression estimates and t-ratios.
Remarks: A constant is _added_.
There is _no_ checking for missing values.
User may wish to change tol or max_iter.

Inputs:
y - the LHS variable as a nobs x 1 vector,
(first element must be the first observation)
x - the RHS variables as a nobs x K matrix
(no constant: a constant will be *added*)
rho - an initial value of rho (usu. zero)

Output:
bt - (K+2)x2 matrix, b~t, the parameter estimates b with
associated t-ratios t
(constant first,rho last, the rest ordered as is x)

References:
Hamilton, J., Time Series Analysis, 1994, p.223
Davidson R. & J. MacKinnon, 1993, Estimation and Inference
in Econometrics, p.339

*****************************************************************/

proc (1) = corc(y,x,rho);
local tol,max_iter,iter,x_,x_1,y_,y_1,oldrho,
nobs,b,xx,xy,xr,yr,u,u_1,e,df,ssr,sst,ee,t,invxx,cov;
tol=10^-8; @convergence criterion@
max_iter=25; @maximum allowable iterations@
x = ones(rows(x),1)~x; @add constant term@
x_=trimr(x,1,0);y_=trimr(y,1,0); @transform data for use in do loop@
x_1=trimr(lag(x),1,0);y_1=trimr(lag(y),1,0);
oldrho=rho+1; @so test criterion satisfied on first iteration@
iter=0;
do while abs(rho-oldrho)>tol;
iter=iter+1;
if iter>max_iter;
" Did not converge in "$+ftocv(max_iter,1,0)$+" iterations.
Exit without convergence. Consider increasing max_iter.";stop;
endif;
oldrho=rho; @store value of rho at beginning of interation@
xr=x_-rho*x_1;
yr=y_-rho*y_1;
xx=xr'xr;xy=xr'yr;
invxx=invpd(xx);
b=invxx*xy; @OLS regression of yr on xr@
u=y-x*b;
u_1=trimr(lag1(u),1,0);u=trimr(u,1,0);
rho=(u_1'u)/(u_1'u_1);
endo;
nobs=rows(yr); @rows(y)-1@
e=yr-xr*b;
@Davidson & MacKinnon covariance matrix calculation:@
xx=(xr~u_1)'(xr~u_1);
invxx=invpd(xx);
cov = (e'e/(nobs-cols(invxx))) * invxx;
b=b|rho;
t = b./sqrt(diag(cov));
retp(b~t);
endp; @corc()@

Preprogrammed Procedures

Gauss has some preprogrammed procedures that can be called up. Here is a frequently used one:

{VNAM,M,B,STB,VC,STDERR,SIGMA,CX,RSQ,RESID,DWSTAT}=OLS(DATASET,DEPVAR,INDVARS);

This procedure, named OLS, computes OLS parameter estimates and generates a variety of regression statistics. The procedure is called up in the program like any other procedure-by its name. The arguments enclosed within the curly brackets are the return values, and the arguments in parenthesis are the variables used in the procedure. The resulting output is:

VNAM variable names   SIGMA standard deviation of residual
M cross product moment matrix   CX correlation matrix of variables with the dependent variable as the last column
B least squares estimates of parameters    
STB standardized coefficients   RSQ coefficient of determination
VC variance covariance matrix of estimates   RESID residuals
STDERR the standard errors of the estimated parameters   DWSTAT Durbin-Watson statistic

The procedure takes in the dataset, the list of dependent variables, and independent variables. The dataset refers to a Gauss dataset. If you do not have a Gauss dataset, for example, if you only have Y and X as your dependent and independent variables, use 0 in the place of dataset instead. There is also an operator in Gauss that is often used to do a regression. However, this operator will not automatically generate the regression output provided by the OLS procedure we just discussed. This operator is simply the slash symbol "/". Here is an example:

BHAT = Y/X;

In this example, Y is the vector containing the values of the dependent variable, and X is the regressor matrix. BHAT is the vector containing the regression parameter estimates.

Publication Quality Graphics

Gauss is capable of making complex graphs. Printing of these graphs depends specifically on the capabilities of the printer and computer you are using. However, Gauss has the capability of exporting its graphics to a variety of file formats such as Lotus (PIC) or Postcript (EPS) files, which can then be imported into standard WordProcessing software. At the American University it is advisable to export the graphics to the Lotus PIC file format so that these graphics can then be imported into WordPerfect for Windows and printed from there. NOTE: To print your graphics from Gauss you need to be on a computer that is directly connected to a printer. Since most of the printing in the computer labs at American University is done via networked printers, the only way to print the graphics is to incorporate them into a WordPerfect document that CAN print on networked printers. This is the only way you can print graphics from the Hurst Lab.

Graph Types

Gauss can create a variety of Graph types. Each of them has a distinct predefined procedure name and hence must be called up as one. Following is the list of graph types that Gauss can create and the procedure names associated with each.

BAR Generate bar graph   LOGLOG Scatter plot with logarithmic X and Y axes
BOX Graph data using box graph percentile method   LOGX Scatter plot with logarithmic X axis
CONTOUR Graph contour data   LOGY Scatter plot with logarithmic Y axis
DRAW Supply additional graphic elements to graphs   POLAR Polar plots
HIST Compute and graph frequency histogram   SURFACE Graph 3-D surface
HISTF Graph histogram given vector of frequencies   XY Scatter plot
HISTP Graph percent frequency histogram of a vector   XYZ Graph 3-D scatter plot

Creating and Exporting Graphs

Before you can create a Graph in Gauss, you need to invoke the Graphics Library by using the command LIBRARY PGRAPH;. Also all data (or matrices/vectors) that are used in the graph generation must be defined before using them. Once these pre-requisites are met, the graphing procedure can be called up with the required syntax. The detailed syntax for all the various graph types are given in the manuals. As an appendix to this document we have included some example of commonly used graph types and the resulting outputs. Exporting a Gauss graph to the Lotus (PIC) format is done using the GRAPHPRT procedure. (If you are creating graph in Gauss using application in one of the campus computer labs, please use the GRAPHPRT option to export your graph to a lotus PIC file, so that you can import it into a word processor software and print. Printing graph directly from Gauss is possible as long as the printer device is directly connected to the machine you are using Gauss on). The parameters that need to be specified for this procedure must all be defined as characters (i.e. enclosed in "quotes"). The procedure must be called before the creation of the graph with the following syntax:

GRAPHPRT("-C=2 -CO=P -CF=A:MYGRAPH.PIC -W=2");

where -C=2 exports to a Lotus PIC file (-C=1 would export to an EPS file); the -CO=P option specifies the orientation of the exported graph (-CO=L would cause the exported file to be oriented landscape); the -CF=A:MYGRAPH.PIC option specifies the name of the exported file (you can change it to any name); and the -W=2 options specifies the time that the graph should be displayed on the Gauss screen before the program continues. If the -W options is not specified, then Gauss will pause at the graph screen until you hit the ESC (escape) key on the keyboard. If more than one graphs are being generated within the program, you should use GRAPHPRT command before each graph is generated so as to export all the graphs to separate PIC files. Graphs can be customized using a number of procedures available or by resetting globals (preset options) within your program. For information on the syntax for each specific kind of graph, the customizing procedures, or resetting of globals refer to the Gauss manual.

Use the Manual

Gauss can do many more procedures. To invoke these procedures and to learn more about the commands reviewed in this document (as well as the commands not reviewed here), please refer to the Gauss manual.

Examples of Creating Graphs

Example 1: Scatter Plot of Two random variables

new;
x=rndn(100,1); /*Generate x data*/
y=rndn(100,1); /*Generate y data*/
library pgraph; /*Invoking PGRAPH library*/
graphset; /*Resetting all globals*/
_pgrid = { 2, 2 }; /*defining global*/
_plctrl = { -1 }; /*defining global*/
_pstype = { 7 }; /*defining global*/
_pdate = 0; /*excluding date*/
title("Title of the Graph"); /*setting TITLE*/
ylabel("The Y-Axis label"); /*setting Y label*/
xlabel("The X-axis label"); /*setting X label*/
graphprt("-c=2 -co=1 -cf=a:xy.pic -w=1") ; /*Setting Export parameters*/
xy(y,x); /*generating the Graph*/
end;

Example 2: Generating Two Histograms

new;
x1=rndn(100,1);
x2=5 + 2*rndn(100,1);
library pgraph;
graphset;
_pdate = 0;
/* defining the first histogram */
title("Histogram Number 1");
xlabel("Categories of X1");
graphprt("-c=2 CO=1 CF=a:\xy21.pic -w=1");
hist(x1,20);
/* defining the second histogram */
title("Histogram Number 2");
xlabel("Categories of X2");
graphprt("-c=2 CO=1 CF=a:\xy22.pic -w=1");
hist(x2,20);

end;

Example 3: Surface Graph

library pgraph;
x=seqa(-10,0.1,50)';
y=seqa(-10,0.1,50);
z=cos(5*sin(x) - y);
graphset;
_pdate = 0 ;
title("Just a Fancy Surface Graph");
xlabel("X Axis");
ylabel("Y Axis");
scale3d(miss(0,0),miss(0,0),-5|5);
graphprt("-c=2 CO=1 CF=a:\xyz.pic -w=1");
surface(x,y,z);
end;

Example 4: Windowed Graphs

new;
x1=rndn(100,1);
x2=5 + 2*rndn(100,1);
library pgraph;
graphset;
_pdate = 0 ;
graphprt("-c=2 CO=1 CF=a:\xy4.pic -w=1");
begwind;
window(1, 2, 0); /*Create two tiled windows (1 row, 2 column)*/
setwind(1); /*graph #1, left corner*/
title("Histogram Number 1");
xlabel("Categories of X1");
hist(x1,20);
nextwind; /*graph #2, right corner*/
title("Histogram Number 2");
xlabel("Categories of X2");
hist(x2,20);
endwind; /* end window processing, and display graph */
end;