Command Reference : EViews Programming : Control of Execution
  
Control of Execution
 
IF Statements
The FOR Loop
FOR Loops with Numerical Control Variables or Scalars
FOR Loops with String Variables and String Objects
The WHILE Loop
Execution Errors
Handling Errors
Stopping Programs
Exiting Loops
EViews provides you with several ways to control the execution of commands in your programs. Controlling execution in your program means that you can execute commands selectively or repeatedly under changing conditions. The tools for controlling execution will be familiar from other computer languages.
IF Statements
There are situations where you may want to execute commands only if some condition is satisfied. EViews uses IF and ENDIF, or IF, ELSE, and ENDIF statements to indicate the condition to be met and the commands to be executed.
An IF statement starts with the if keyword, followed by an expression for the condition, and then the word then. You may use AND/OR statements in the condition, using parentheses to group parts of the statement as necessary.
All comparisons in the IF statement follow the rules outlined in “String Relational Operators” and in “Numeric Relational Operators”. Note in particular that string comparisons are case-sensitive. You may perform caseless comparison using the @upper or @lower string functions as in
if (@lower(%x) = "abc") then
or
if (@upper(%x) = "ABC") then
If the expression is true, all of the commands until the matching endif are executed. If the expression is false, all of these commands are skipped. For example,
if !stand=1 or (!rescale=1 and !redo=1) then
series gnpstd = gnp/sqr(gvar)
series constd = cons/sqr(cvar)
endif
if !a>5 and !a<10 then
smpl 1950q1 1970q1+!a
endif
only generates the series GNPSTD and CONSTD and sets the sample if the corresponding IF statements are true. Note that we have indented the lines between the if and the endif statements. The indentation is added for program clarity and has no effect on the execution of the program lines.
The expression to be tested may also take a numerical value. In this case, 0 and NA are equivalent to false and any other non-zero value evaluates to true. For example,
if !scale then
series newage = age/!scale
endif
executes the series statement if !SCALE is a non-missing, non-zero value.
An IF statement may include a matching ELSE clause containing commands to be executed if the condition is FALSE. If the condition is true, all of the commands up to the keyword else will be executed. If the condition is FALSE, all of the commands between else and endif will be executed. For example:
if !scale>0 then
series newage = age/!scale
else
series newage = age
endif
(It is worth noting that this example performs a conditional recode in which the series NEWAGE is assigned using one expression if a condition is true, and a different expression otherwise. EViews provides a built-in @recode function for performing this type of evaluation; see @recode(s,x,y).)
IF statements may also be applied to string variables:
if %0="CA" or %0="IN" then
series stateid = 1
else
if %0="MA" then
series stateid=2
else
if %0="IN" then
series stateid=3
endif
endif
endif
Note that the nesting of our comparisons does not cause any difficulties.
You should note when using the IF statement with series or matrix objects that the comparison is defined on the entire object and will evaluate to false unless every element of the element-wise comparison is true. Thus, if X and Y are series, the IF statement
if x<>y then
[some program lines]
endif
evaluates to false if any element of X does not equal the corresponding value of Y in the default sample. If X and Y are identically sized vectors or matrices, the comparison is over each of the elements X and Y. This element-wise comparison is described in greater detail in “Relational Operators (=, >, >=, <, <=, <>)”.
If you wish to operate on individual elements of a series on the basis of element-wise conditions, you should use the @recode function or use smpl statements to set the observations you wish to change. Element-wise operations on a vector or matrix should use comparisons of individual element comparisons
if x(3)=7 then
x(3) = 2
endif
or the element-wise matrix functions (“Matrix Element Functions”).
The FOR Loop
The FOR loop allows you to repeat a set of commands for different values of numerical or string variables. The FOR loop begins with a for statement and ends with a next statement. Any number of commands may appear between these two statements.
The syntax of the FOR statement differs depending upon whether it uses numerical variables or string variables.
FOR Loops with Numerical Control Variables or Scalars
To repeat statements for different values of a control variable, you should follow the for keyword by a control variable initialization, the word to, and then an ending value. After the ending value you may include the word step followed by a number indicating an amount to change the control variable each time the loop is executed. If you don’t include step, the step is assumed to be 1. Consider, for example the loop:
for !j=1 to 10
series decile{!j} = (income<level{!j})
next
In this example, step=1 and the variable !j is twice used as a replacement variable, first for the ten series declarations DECILE1 through DECILE10 and for the ten variables LEVEL1 through LEVEL10.
We may add the step keyword and value to the FOR loop to modify the step:
for !j=10 to 1 step -1
series rescale{!j}=original/!j
next
In this example, the step is -1, and !J is used as a replacement variable in naming the ten constructed series RESCALE10 through RESCALE1 and as a control variable scalar divisor in the series ORIGINAL.
The commands inside the FOR loop are first executed for the initial control value (unless that value is already beyond the terminal value). After the initial execution, the control variable is incremented by step and EViews compares the new control variable value to the limit. If the limit is exceeded, execution stops.
One important use of FOR loops with control variables is to change the workfile sample using a smpl command. If you add a control variable to a date in a smpl command statement, you will get a new date as many observations forward as the current value of the control variable. Here is a FOR loop that gradually increases the size of the sample and estimates a recursive regression:
for !horizon=10 to 72
smpl 1970m1 1970m1+!horizon
equation eq{!horizon}.ls sales c orders
next
One other important case uses loops and control variables to access elements of a matrix object. For example,
!rows = @rows(vec1)
vector cumsum1 = vec1
for !i=2 to !rows
cumsum1(!i) = cumsum1(!i-1) + vec1(!i)
next
computes the cumulative sum of the elements in the vector VEC1 and saves it in the vector CUMSUM1.
To access an individual element of a series, you will need to use the @elem function and @otod to get the desired element
for !i=2 to !rows
cumsum1(!i) = @elem(ser1, @otod(!i))
next
The @otod function returns the date associated with the observation index (counting from the beginning of the workfile), and the @elem function extracts the series element associated with a given date.
You may nest FOR loops to contain loops within loops. The entire inner FOR loop is executed for each successive value of the outer FOR loop. For example:
matrix(25,10) xx
for !i=1 to 25
for !j=1 to 10
xx(!i,!j)=(!i-1)*10+!j
next
next
You should avoid changing the control variable within a FOR loop. Consider, for example, the commands:
' potentially confusing loop (avoid doing this)
for !i=1 to 25
vector a!i
!i=!i+10
next
Here, both the FOR assignment and the assignment statement within the loop change the value of the control variable !i. Loops of this type are difficult to follow and may produce unintended results. If you find a specific need to change a control variable inside the loop, you should consider using a WHILE loop (“The WHILE Loop”) as an alternative to the FOR loop.
You may execute FOR loops with scalars instead of control variables. However, you must first declare the scalar, and you may not use the scalar as a replacement variable. For example,
scalar i
scalar sum = 0
vector (10) x
for i=1 to 10
x(i) = i
sum = sum + i
next
In this example, the scalar objects I and SUM remain in the workfile after the program has finished running, unless they are explicitly deleted. When using scalar objects as the looping variable you should be careful that the scalar is always available white the FOR loop is active. You should not, for example, delete the scalar or change the workfile page within the FOR loop.
FOR Loops with String Variables and String Objects
To repeat statements for different values of a string variable, you may use the FOR loop to let a string variable range over a list of string values. You should list the FOR keyword, followed by the name of the string program variable, followed by the list of values. For example,
for %y gdp gnp ndp nnp
equation {%y}trend.ls {%y} c {%y}(-1) time
next
executes the commands
equation gdptrend.ls gdp c gdp(-1) time
equation gnptrend.ls gnp c gnp(-1) time
equation ndptrend.ls ndp c ndp(-1) time
equation nnptrend.ls nnp c nnp(-1) time
You may include multiple string variables in the same FOR statement—EViews will process the string values in sets. For example, we may define a loop with list three string variables:
for %1 %2 %3 1955q1 1960q4 early 1970q2 1980q3 mid 1975q4 1995q1 late
smpl %1 %2
equation {%3}eq.ls sales c orders
next
In this case, the elements of the list are taken in groups of three. The loop is executed three times for the different sample pairs and equation names:
smpl 1955q1 1960q4
equation earlyeq.ls sales c orders
smpl 1970q2 1980q3
equation mideq.ls sales c orders
smpl 1975q4 1995q1
equation lateeq.ls sales c orders
Both string objects and replacement variables may be used to specify a list for use in loops, by surrounding the object name or replacement variable with curly braces (“{ }”). For example,
string dates = "1960m1 1960m12"
%label = "year1"
for %1 %2 %3 {dates} {%label}
smpl {%1} {%2}
equation {%3}eq.ls sales c orders
next
finds the three strings for the loop by taking two elements of the string list and one element of the string variable:
smpl 1960m1 1960m12
equation year1eq.ls sales c orders
Note the difference between using a FOR loop with multiple string variables and using nested FOR loops. In the multiple string variable case, all string variables are advanced at the same time, while with nested loops, the inner variable is advanced over all choices, for each value of the outer variable. For example:
!eqno = 1
for %1 1955q1 1960q4
for %2 1970q2 1980q3 1975q4
smpl %1 %2
'form equation name as eq1 through eq6
equation eq{!eqno}.ls sales c orders
!eqno=!eqno+1
next
next
Here, the equations are estimated over the samples 1955Q1–1970Q2 for EQ1, 1955Q1–1980Q3 for EQ2, 1955Q1–1975Q4 for EQ3, 1960Q4–1970Q2 for EQ4, 1960Q4–1980Q3 for EQ5, and 1960Q4–1975Q4 for EQ6.
Note that you may use the exitloop command to exit a FOR loop early. See “Exiting Loops”.
The WHILE Loop
In some cases, we wish to repeat a series of commands several times, but only while one or more conditions are satisfied. Like the FOR loop, the WHILE loop allows you to repeat commands, but the WHILE loop provides greater flexibility in specifying the required conditions.
The WHILE loop begins with a while statement and ends with a wend statement. Any number of commands may appear between the two statements. WHILE loops can be nested.
The WHILE statement consists of the while keyword followed by an expression involving a control variable or scalar object. The expression should have a logical (true/false) value or a numerical value. In the latter case, zero is considered false and any non-zero value is considered true.
If the expression is true, the subsequent statements, up to the matching wend, will be executed, and then the procedure is repeated. If the condition is false, EViews will skip the following commands and continue on with the rest of the program following the wend statement. For example:
!val = 1
!a = 1
while !val<10000 and !a<10
smpl 1950q1 1970q1+!a
series inc{!val} = income/!val
!val = !val*10
!a = !a+1
wend
There are four parts to this WHILE loop. The first part is the initialization of the control variables used in the test condition. The second part is the WHILE statement which includes the test. The third part is the statements updating the control variables. Finally the end of the loop is marked by the word wend.
Unlike a FOR statement, the WHILE statement does not update the control variable used in the test condition. You need to include an explicit statement inside the loop to change the control variable, or your loop will never terminate. Use the F1 key to break out of a program which is in an infinite loop.
Earlier, we cautioned against this behavior creating FOR loops that explicitly change the control variable inside the loop and offered an example to show the resulting lack of clarity (here). Note that the equivalent WHILE loop provides a much clearer program:
!i = 1
while !i<=25
vector a{!i}
!i = !i + 11
wend
Note that you may use the exitloop command to exit a WHILE loop early. See “Exiting Loops”.
Execution Errors
By default, EViews will stop executing after encountering any errors. You can instruct the program to continue running even if errors are encountered by changing the maximum error count from the Run dialog (see “Executing a Program”), or by using the setmaxerrs command inside a program.
Handling Errors
You may wish to perform different tasks when errors are encountered. For example, you may wish to skip a set of lines which accumulate estimation results when the estimation procedure generated errors, or you may wish to overwrite the default EViews error with one of your own, using the seterr command.
EViews offers a number of different ways to test for and handle execution errors. For example, the @lasterrstr command will return a string containing the previous line's error. If the previous line of your program did not error, this string will be empty. Alternatively you could use the @errorcount function to check the number of errors currently encountered before and after a program line has been executed.
For example, to test whether the estimation of an equation generated an error, you can compare the number of errors before and after the command:
!old_count = @errorcount
equation eq1.ls y x c
!new_count = @errorcount
if !new_count > !old_count then
[various commands]
endif
Here, we perform a set of commands only if the estimation of equation EQ1 incremented the error count.
For additional error handling functions, see “Support Commands” and “Support Functions”.
Stopping Programs
Occasionally, you may want to stop a program based on some conditions. To stop a program executing in EViews, use the stop command. For example, suppose you write a program that requires the series SER1 to have nonnegative values. The following commands check whether the series is nonnegative and halt the program if SER1 contains any negative value:
series test = (ser1<0)
if @sum(test) <> 0 then
stop
endif
Note that if SER1 contains missing values, the corresponding elements of TEST will also be missing. But since the @sum function ignores missing values, the program does not halt for SER1 that has missing values, as long as there is no negative value.
Exiting Loops
Sometimes, you do not wish to stop the entire program when a condition is satisfied; you just wish to exit the current loop. The exitloop command will exit the current for or while statement and continue running the program.
As a simple example, suppose you computed a sequence of LR test statistics LR11, LR10, LR9, ..., LR1, say to test the lag length of a VAR. The following program sequentially carries out the LR test starting from LR11 and tells you the statistic that is first rejected at the 5% level:
!df = 9
for !lag = 11 to 1 step -1
!pval = 1 - @cchisq(lr{!lag},!df)
if !pval<=.05 then
exitloop
endif
next
scalar lag=!lag
Note that the scalar LAG has the value 0 if none of the test statistics are rejected.
If the exitloop is issued inside nested loops it will stop execution of the innermost loop. Execution of the remaining loops is unaffected.