1. Home
  2. FOR directive

FOR directive

Introduces a loop; subsequent statements define the contents of the loop, which is terminated by the directive ENDFOR.

Options

NTIMES = scalar Number of times to execute the loop; default is to execute as many times as the length of the first parameter list or once if the first list is null
INDEX = scalar Records the loop index
START = scalar Defines an integer initial value for the loop index; default 1
END = scalar Defines an integer final value for the loop index
STEP = scalar Defines an integer amount by which to increase the index each time the loop is executed; default 1
VALUES = variate Defines a set of values to be taken successively by the loop index (overrides START, END and STEP if these are specified too)

Parameters

  Any number of parameter settings of the form identifier = list of data structures; the identifier is set up as a dummy which is then used within the loop to refer, in turn, to the structures in the list

Description

The FOR loop is a series of statements that is repeated several times. The FOR directive introduces the loop and indicates how many times it is to be executed. In its simplest form FOR has no parameters, and the number of times is indicated by the NTIMES option. For example, the following loop calculates the mean of three sets of data stored in the file attached to channel 2:

FOR [NTIMES=3]

  READ [CHANNEL=2] X

  CALCULATE Mean = MEAN(X)

  PRINT Mean; DECIMALS=4

ENDFOR

The INDEX option allows you to record the loop index in a scalar. By default this is the number of the time that the loop is currently being executed. So, in the statement below, the index Count will take the values 1, 2 and 3.

FOR [NTIMES=3; INDEX=Count]

The options START, END and STEP allow you to define a loop index that does not start at one, and does not increase by one each time the loop is executed. They should all be set to integers; any non-integer value is rounded to the nearest integer. (Integer calculations are exact, so this avoids inaccuracies due to numerical round-off when loops are executed many times.) START specifies the INDEX value on the first time that the loop is executed (default 1). STEP defines how it changes between one time that the loop is executed and the next (default 1). So, for example, on the second time INDEX will be START + STEP. END provides an alternative way of specifying how many times to execute the loop – it stops when the next index will go beyond END. For example, the statement below

FOR [INDEX=Count; START=3; END=8; STEP=2]

defines a loop that will be executed three times, with the index variable Count taking the values 3, 5 and 7; the next value would be 9, which goes beyond 8. The default STEP is one. STEP can also be negative. So, this statement

FOR [INDEX=Count; START=3; END=-4; STEP=-2]

defines a loop that will be executed four times, with the index variable Count taking the values 3, 1, -1 and -3; the next value would be -5, which goes beyond -4. If you specify NTIMES as well as END, they must both define the same number of times to execute the loop.

The VALUES option allows you to specify an arbitrary sequence of values for the loop index, and these need not be integers. The setting is a variate. So, for example, here

VARIATE [VALUES=0, 0.5, 1, 1.5, 2, 1.5, 1, 0.5, 0] Cvals

FOR [INDEX=Count; VALUES=Cvals]

Count will first increase from 0 to 2 in steps of 0.5, and then decrease back down to 0. The number of values in the VALUES variate must be the same as the value supplied by NTIMES if both options are specified. VALUES overrides START, END and STEP if these are specified too.

The INDEX is defined automatically as a scalar if it has not already been declared. If VALUES is set, its default number of decimals is set to be the same as the number defined for the VALUES variate (see the DECIMALS parameter of the VARIATE and SCALAR directives), or to take the default number if no decimals have been defined for VALUES. Otherwise the default number of decimals is set to zero.

The parameters of FOR allow you to write a loop whose contents apply to different data structures each time it is executed. Unlike other directives, the parameter names of FOR are not fixed for you by Genstat: you can put any valid identifier before each equals sign. Each of these then refers to a Genstat dummy structure; so you must not have declared them already as any other type of structure. The first time that the loop is executed, they each point to the first data structure in their respective lists, next time it is the second structure, and so on. The list of the first parameter must be the longest; other lists are recycled as necessary.

If you specify parameters you do not need to specify NTIMES but, if you specify both, the value of NTIMES must be the same as the length of the first parameter list.

You can specify as many parameters as you need. For example

FOR Ind=Age,Name,Salary; Dir='descending','ascending'

  SORT [INDEX=Ind; DIRECTION=#Dir] Name,Age,Salary

  PRINT Name,Age,Salary

ENDFOR

is equivalent to the sequence of statements

SORT [INDEX=Age; DIRECTION='descending'] Name,Age,Salary

PRINT Name,Age,Salary

SORT [INDEX=Name; DIRECTION='ascending'] Name,Age,Salary

PRINT Name,Age,Salary

SORT [INDEX=Salary; DIRECTION='descending'] Name,Age,Salary

PRINT Name,Age,Salary

printing the units of the text Name, and variates Age and Salary, first in order of descending ages, then in alphabetic order of names, and finally in order of descending salaries.

You can put other control structures inside the loop. So, for example, you can have loops within loops.

When you are using loops interactively, you may find it helpful to use the PAUSE option of SET to request Genstat to pause after every so many lines of output. Another useful directive is BREAK, which specifies an explicit break in the execution of the loop.

Options: NTIMES, INDEX, START, END, STEP, VALUES.

Parameters: names defining the dummies used within the loop.

See also

Directives: ENDFOR, EXIT, CASE, IF.

Commands for: Program control.

Example

" Example 2:6.18.3 "
" Abundances of 16 grass species on 9 plots of land:
  part of Table 1.1 in Digby & Kempton (1987)."
UNITS [NVALUES=16]
READ  [SERIAL=yes] Abund[1...6]
15.5  2.5  7.2  0.2 1.0 0.0 2.2 33.2 0.0  0.3 6.1 0.0 6.9 0.7 0.0 0.1 :
 4.0  1.0 13.1  6.1 1.6 0.0 1.5 11.7 3.6 12.0 9.5 0.0 0.0 2.5 0.3 0.4 :
 1.0 28.8  6.1 37.6 0.0 0.0 7.8  1.0 0.0  0.6 2.9 0.0 0.0 5.3 1.0 1.4 :
 0.0 36.8  0.3 37.0 0.0 1.3 2.7  0.0 0.0  0.0 0.0 0.0 0.0 0.7 1.5 4.5 :
19.6  0.0  9.5  0.0 0.0 0.0 0.0 48.7 0.0  0.0 4.8 0.1 0.3 1.0 2.7 0.7 :
82.7  0.0 17.2  0.0 0.0 0.0 0.0  0.1 0.0  0.0 0.0 0.0 0.0 0.0 0.0 0.0 :
CALCULATE   LogAbund[1...6] = LOG10(Abund[1...6] + 1)
&           PrsAbund[1...6] = Abund[1...6] > 0
" Form similarity matrices using 5 different methods
  on suitably transformed copies of the data."
FSIMILARITY [SIMILARITY=Sjaccard] PrsAbund[]; Jaccard
&           [SIMILARITY=Ssmc]     PrsAbund[]; simplematching
&           [SIMILARITY=Scity]    LogAbund[]; cityblock
&           [SIMILARITY=Secol]    LogAbund[]; ecological
&           [SIMILARITY=Spythag]  LogAbund[]; Pythagorean
POINTER     [NVALUES=7] Config
MATRIX      [ROWS=16; COLUMNS=6] Config[]
LRV         [ROWS=16; COLUMNS=6] Pcol
" Use PCO on each similarity matrix, to get 5 ordinations',\ 
  of 16 points in 6 dimensions."
FOR         Dsim=Sjaccard,Ssmc,Scity,Secol,Spythag; Dcpco=Config[1...5]
  PCO       Dsim; LRV=Pcol
  CALCULATE Dcpco = Pcol[1]
ENDFOR
" Use correspondence analysis on the data, and the data
  transformed to presence/absence, to get 2 more
  ordinations of 16 points in 6 dimensions."
MATRIX      [ROWS=16; COLUMNS=6] MatAbund
CALCULATE   MatAbund$[*; 1...6] = Abund[]
CORANALYSIS [METHOD=digby] MatAbund; ROW=Config[6]
CALCULATE   MatAbund = MatAbund > 0
CORANALYSIS [METHOD=digby] MatAbund; ROW=Config[7]
TEXT        [VALUES=Jc,SM,CB,Ec,Py,CA,CP] Points
SYMMETRICMATRIX [ROWS=Points] MPdist
" Use multiple Procrustes analysis to compare
  the 7 different ordination methods."
PCOPROCRUSTES Config; LRV=MPLRV; DISTANCE=MPdist
PRINT       MPdist; FIELD=8; DECIMALS=4
CALCULATE   MPscore[1,2] = MPLRV[1]$[*; 1,2]
FRAME       3; SCALING=xyequal
XAXIS       3; TITLE='Dimension 1'; LOWER=-0.55; UPPER=0.55
YAXIS       3; TITLE='Dimension 2'; LOWER=-0.55; UPPER=0.55
PEN         1; SYMBOLS=0; LABELS=Points; SIZE=1.5; COLOUR='blue'
DGRAPH      [TITLE='Multiple Procrustes analysis: first two dimensions';\
            WINDOW=3; KEY=0] MPscore[2]; MPscore[1]
PRINT    !T('The 7 methods are plotted as the points:',\ 
            '   Jc  Jaccard similarity coefficient;',\ 
            '   SM  simple-matching similarity coefficient;',\ 
            '   CB  city-block similarity coefficient;',\ 
            '   Ec  ecological similarity coefficient;',\ 
            '   Py  Pythagorean similarity coefficient;',\ 
            '   CA  correspondence analysis of data;', \
            '   CP  correspondence analysis of presence/absence.'); \
         JUSTIFICATION=left
Updated on March 11, 2022

Was this article helpful?