Associative vs. Positional Indexing
When accessing an element of an array elements, you can identify the element by association or position.
Year has these elements:
Index Year :=
2007 2008 2009 2010 2011 2012
Earnings is an array indexed by
Variable Earnings :=
Year ▶ 2007 2008 2009 2010 2011 2012 4.5M 5.6M 6.6M 7.9M 9.0M 10.1M
Then we can access an element of Earnings by association:
Earnings[Year = 2009] → 6.6M
or by position:
Earnings[@Year = 3] → 6.6M
Subscript(Earnings, Year, 2009) → 6.6M
Slice(Earnings, Year, 3) → 6.6M
Positions in Analytica go from 1 up to Size(I).
For text elements, indexing by association is case-sensitive, e.g.,
A[L = 'low'] is not the same as
A[L = 'Low'].
Associative / Positional Duals
Most built-in functions that identify an index element by association also have a positional option, and vice versa, as shown here:
Associational Positional Notes A[I = x] A[@I = n] A[I = J] A[@I = @J] Variation referred to as re-indexing Subscript(A, I, x) Slice(A, I, n) Slice(I, n) @[I = x] Slice(I, n) : returns the «n»th element of an index.
@[I=x] : returns the position of element «x» in an index.
ArgMax(A, I) ArgMax(A, I, position: True) ArgMin(A, I) ArgMin(A, I, position: True) Choice(I, n) Choice(I, n, result: @I) The second parameter is always positional.
The return value here is the element of «I» or the position along «I».
For x:=I Do... For n := @I Do... IndexValue(I) @I The elements of an index or the position along an index. SubIndex(A, U, I) PositionInIndex(A, U, I) (no equiv) Rank(A, I) Rank is related to SortIndex, which returns positions.
There is no logical associational dual.
SortIndex(A, I) Index J := @I Do SortIndex(A[@I = @J], J) No built-in positional dual Subset(D)
- Subset(D, position: true)
D must be 1-D.
No built-in positional dual prior to release 4.2.
Unique(A, I) Unique(A, I, position: true) Only works in Analytica 4.0 and above.
When to Index by Association vs. Position
Indexing by Association (subscript) is generally more flexible. If you insert a new element into an index, say
Division, this expression
Expenses[Division = 'Marketing']
continues to refer to the correct data, where the positional equivalent,
Expenses[@Division = 6], would break if 'Marketing' is no longer the 6th element.
On the other hand, if an index has duplicate elements, indexing by association is ambiguous. In this case, you need to index by position to avoid the ambiguity. For this reason, it's often better to use positional indexing in User-Defined Functions, if you can't assume an index has unique elements. It is usually poor practice to create indexes with duplicate elements, but there are occasionally legitimate cases.
A second case where positional indexing is appropriate is when using a square matrix. A square matrix must have two indexes of the same length. If you can be sure that the two indexes have the same elements, indexing by association works fine, but in the more general case you can only assume the same length but not identical values, you should index by position.
Finally, some operations are inherently positional or associational by the nature of what is being done. For example, referring the the previous element of an array,
A[@I = @I-1], is inherently positional. An "outer join" of two arrays, such as
Salary_by_paygrade[Person = Paygrade_by_person], is naturally associational.
When an index changes, perhaps because a user inserted or deleted elements, or because something impacting the computation of its IndexValue changed, edit tables based on that index must be spliced. This means that rows may need to be moved around, deleted, or added (with empty or default values). This modification of existing edit tables is referred to as splicing.
For a given index, you can specify whether tables that depend on it should splice associationally or positionally when the index value changes. See Table Splicing for more information.