Error Messages/40901


Error message

The first parameter to Sysfunction Subset must be a one-dimensional array (unless the optional «resultIndex» parameter is provided). The parameter passed has 2 dimensions.

Cause

You've passed a multi-dimensional array (having 2 or more dimensions) to Subset. There are two likely causes for this error. You may have intended to identify a subset of rows based on some particular criteria, such as one particular column, but you forgot to select out that column inside the parameter. The second case is that you may want to array abstract over multiple scenarios, each scenario having its own subset. Let's consider these individually.

Error in your logic

In the first case, suppose you have a value such as:

Var Rent_income :=
Time ▶
Property ▼ 2010 2011 2012 2013 2014
Bldg A $15243 $15243 $13100 $13100 $12900
Bldg B $17010 $18120 $18000 $18100 $17952
Bldg C $8900 $8950 $9000 $9050 $9100

You want to identify properties that are expected to have a decline from a previous year, so you write (incorrectly):

Subset(Uncumulate(rent_income, Time) < 0)

When you write this, you're thinking that any time there is a decline, Uncumulate will be negative, so if the condition is ever true, then we want to keep that property in our subset. The flaw in our logic here is that Uncumulate will return a 2-D array -- for every property and every Time point, we'll have a boolean indicating if that property declined in that time period. This creates an ambiguity for Subset -- do you want the subset of properties that declined in a given year? Or the subset of year in which a given property declined? In either case, we also have a problem that each subset will be a list with a different number of elements, so those can't be combined into a single multi-D array. The flaw here is a logical one in the way we wrote the expression. What we really want to say is "there exists a time point in which Uncumulate(...) < 0". We can write this (correctly) as:

Subset(Min(Uncumulate(rent_income, Time), Time) < 0)

or equivalently:

Subset(Max(Uncumulate(rent_income, Time) < 0, Time))

These express the correct logic and provide Subset with a 1-D parameter.

Need to Array Abstract

The second case that may result in this error is where you really do want to array abstract. In the previous example with rent_income, suppose for each property we wish to identify the subset of years in which rent is projected to decline. This may be a different number of years for each property.

Subset is one of a small handful of functions in Analytica that will not allow you to array abstract in this fashion - the reason being that its result is a list, and may have a different number of elements in each scenario (or in the example, a different number of points for each property). If you could array abstract, you'd end up with a non-rectangular array. Arrays in Analytica are inherently rectangular, hence the problem.

There are two approaches to array abstracting in this fashion. The first is to map the result of each property onto a pre-defined result index -- where the index hopefully has at least as many elements as the longest subset. When the number of points is fewer than the length of the result index, we'll fill those cells with Null. When this is your intention, Subset makes this easy by allowing you to specify the result index in an optional parameter, as in the following example:

Subset(Uncumulate(rent_income, Time < 0), resultIndex: Time) →
Time ▶
Property ▼ 2010 2011 2012 2013 2014
Bldg A 2012 2014 «null» «null» «null»
Bldg B 2012 2014 «null» «null» «null»
Bldg C «null» «null» «null» «null» «null»

We could have used a result index other than Time here - but of course Time is convenient since we know it is guaranteed to have enough elements to capture all transition points.

A second approach to array abstract is to place the result for each property inside a reference, so that the result is an array indexed by property, where each cell contains a reference to a list of years. The following accomplishes this:

Two tricks being used here -- we've told Analytica that the intermediate result, decreases, should be treated as if it is indexed only by Time, and second we're returning a reference to the subset result (the backslash), rather than just the result. So here we get an array of references:

Var decreases[Time] := Uncumulate(rent_income, Time) < 0 Do \Subset(decreases) →
Property ▼
Bldg A \[2012, 2014]
Bldg B \[2012, 2014]
Bldg C \[]

See Also

Comments


You are not allowed to post comments.