Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayFormula that refers to the previous row? (Circular dependency error)

I'm having trouble with what seems like it would be quite a common requirement: an array formula calculation that incorporates prior rows. The issue seems to be that all cells in the array formula are evaluated at once, and so it thinks there's a circular dependency, and gives that error.

I've mocked up a toy example on Google Spreadsheet which you should be able to see and comment on. (I've disallowed edit access to prevent vandalism.)

It looks like this, where everything is in row 2, and bullets 1,2,3,4 refer to columns A,B,C,D respectively:

  1. 'Change' - blank for manual entry
  2. 'Ex. interest' - =ARRAYFORMULA(IF(ROW(B2:B)>2, OFFSET(D2:D, -1, 0) + A2:A,))
  3. 'Interest rate' - blank for manual entry
  4. 'Balance' - =ARRAYFORMULA(IF(ROW(D2:D)=2, 0, B2:B*(1+C2:C)))

The idea is to have the interest compound (with a possibly variable rate) and the option of a plus/minus capital change on each row, however, cells B2 and D2 (points 2, 4) error #REF, and on hover report a 'circular dependency'.

I've tried everything I can think of: OFFSET, INDIRECT, D1:D (instead of 2), even a helper column to do nothing but refer to the previous row of D (that just caused a three-column circular dependency instead).

How can I have the 'ex. interest' column refer to the 'balance' column of the previous row in an array formula without causing this error?

Similar questions solve this with SUMIF over the rows, conditioned on the row being less than the 'current' row in the array formula. I can't see that this could work in my case, since I would need to multiply the whole running sum by the interest at each step. I tried SUMIF(... "="&DATE(...) ...) to refer to the previous single row; this works in a helper column to print the offset balance, but trying to use it (with iterative calculation on per below) just behaves like it's zero.

At @JackBrown's suggestion, I enabled iterative calculation which rids the circular dependency error, however it still doesn't work - the second filled row gets a value of 0 from the previous row, despite the previous row having a non-zero value. As if it took the value on an early iteration, and didn't update on change.

like image 309
OJFord Avatar asked May 10 '17 18:05

OJFord


People also ask

Why does the filter formula have a circular dependency detected error?

As you can see in the image below, the FILTER formula has a "circular dependency detected" error. This is being caused by the reference to the source range, which is one column too wide (considering where the filter formula has been placed). If the formula refers to the range A2:D, which contains column D, the formula cannot be placed in column D.

How do you fix the circular dependency error in Excel?

To fix the error, we can either move the formula to another cell, or change the reference in the formula so that it refers to another cell. In this case we will change the cell reference to cell B1. As you can see in the image below, this adjustment has fixed the circular dependency error.

What is circular dependency error in CloudFormation?

A circular dependency, as the name implies, means that two resources are dependent on each other or that a resource is dependent on itself: Resource A is dependent on Resource B, and Resource B is dependent on Resource A. When AWS CloudFormation assesses that this type of condition exists, you will get a circular dependency error ...

What is circular dependency detected error in Google Sheets?

A common situation where you might experience the "circular dependency detected" error, is when you are summing in Google Sheets. This will happen most often when your SUM formula is in the same column that it refers to, and when the formula reference captures the entire column.


Video Answer


1 Answers

Excel

In excel make smart table and use formula:

=If(row()=2,A2*(1+B2),(A1+C1)*(1+B2))

Please download sample file here: https://drive.google.com/file/d/0B79ClRnKS87QTTR5VDBld0plajg/view?usp=sharingenter image description here


Google Sheets

I've made a research in order to try solving your problem. Short answer: I can't do this and I believe that's impossible.

Background

I simplified the case to the task of finding future rate value with changing rates:

Rate+   Recursive formula for rate
1.00%   101.0000%    =(1+A2)
1.50%   102.5150%    =B2*(1+A3)
1.10%   103.6427%    =B3*(1+A4)
1.10%   104.7827%    =B4*(1+A5)

Then I've made an array by hand to get the same result and got this:

={1+A2;
  1+A2+(1+A2)*A3;
  1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4;
  1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4+(1+A2+(1+A2)*A3+(1+A2+(1+A2)*A3)*A4)*A5}

As you see, the number of arguments grows very fast:

1  = 2 ^1 - 1   1+B2         
3  = 2 ^2 - 1   1+B2+(1+B2)*B3 
7  = 2 ^3 - 1   1+B2+(1+B2)*B3+(1+B2+(1+B2)*B3)*B4   
15 = 2 ^4 - 1   1+B2+(1+B2)*B3+(1+B2+(1+B2)*B3)*B4 + ... 

And to calculate the result for final row we need 2^n - 1 variables:

  • for row 32 this number is 4 294 967 295!

That's why arrayformula can't handle calculations even when you enable Iterative calculation= On


Workaroud But this is very simple task for recursive functions or scripts, because they can remember the last found value. So I suggest writing script and use it as custom arrayformula:

function futureValue(values, rates) {

  var result = [];
  var resultCurrent = 0;

  for (var i = 0, len = values.length; i < len; i++)
  {
    resultCurrent = (+values[i] + resultCurrent) * (1 + +rates[i]);
    result.push(resultCurrent);
  }

  return result;

}

Links:

  1. Sample file with the script working
  2. Guide on custom functions
like image 192
Max Makhrov Avatar answered Sep 27 '22 20:09

Max Makhrov