Accumulators - Access additional list / column

I have a table created like below.

 

t:(c: 30 40 25 20 4 4; c1: 10 20 5 25 5 4)

 

c2 is calculated Column (value from c1 or prev c2 is used based on evaluation).

prev value is taken as 0 for first row / if not available

 

Below are the calculations.

 

|

c

|

c1

|

c2

|

 

|

c1>prev c2

|

OR

|

prev c < prev c2

|

?

|

c1

|

prev c2

|
|

30

|

10

|

10

|

 

|

10>0 (True)

|

OR

|

No need of evaluation

|

?

|

10

|

 

|
|

40

|

20

|

20

|

 

|

20>10(True)

|

OR

|

No need of evaluation

|

?

|

20

|

 

|
|

25

|

5

|

20

|

 

|

5>20(False)

|

OR

|

40<20(False)

|

?

|

 

|

20

|
|

20

|

25

|

25

|

 

|

25>20(True)

|

OR

|

No need of evaluation

|

?

|

25

|

 

|
|

4

|

5

|

5

|

 

|

5>25(False)

|

OR

|

20<25(True)

|

?

|

5

|

 

|
|

4

|

4

|

4

|

 

|

4>5(False)

|

OR

|

4<5(True)

|

?

|

4

|

 

|

 

What I have till now

 

update c2: 0{?[y>x;y;0N]}\c1 from t

 

How can I OR the condition prev c < prev c2 along with this? Can column c be accessed? Something like below.

 

update c2: 0{?[y>x|0^c <x;y;x]}\c1 from t

   

Looking at your expected c2 this logic may be what you are looking for:

 

q)update c2:fills ?[(c1>prev c1) or c<prev c1;c1;0N] from t c c1 c2 -------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4

 

Thanks rocuinneagain,

Works for most scenarios. I have added one more row at the end where I get a different result than expected. The value for c2 in last row should be 4 instead of 3.

t:(c: 30 40 25 20 4 4 1; c1: 10 20 5 25 5 4 3)

 

| c  | c1 | c2 |   | c1>prev c2  | OR | prev c < prev c2 | ?  | c1 | prev c2 |
| 30 | 10 | 10 |   | 10>0 (True) | OR | No need of evaluation | ? | 10 |   |
| 40 | 20 | 20 |   | 20>10(True) | OR | No need of evaluation | ? | 20 |   |
| 25 | 5 | 20 |   | 5>20(False) | OR | 40<20(False) | ? |   | 20 |
| 20 | 25 | 25 |   | 25>20(True) | OR | No need of evaluation | ? | 25 |   |
| 4 | 5 | 5 |   | 5>25(False) | OR | 20<25(True) | ? | 5 |   |
| 4 | 4 | 4 |   | 4>5(False) | OR | 4<5(True) | ? | 4 |   |
| 1 | 3 | 4 |   | 3>4(False) | OR | 4<4(False) | ? |   | 4 |

 

update c2:fills ?[(c1>prev c1) or c<prev c1;c1;0N] from t c c1 c2 -------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4 1 3 3

 

 

changing c to prev[c] looks to be what was missing

 

q)update c2:fills ?[(c1>prev c1) or prev[c]<prev c1;c1;0N] from t c c1 c2 -------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4 1 3 4

 

Somehow not being able to use the previous calculated value of c2 directly is causing fallout for different combination of data. Last value of c2 will be 4 as per the logic but we get 3.5

t:(c: 30 40 25 20 4 4 4.5 4.5; c1: 10 20 5 25 5 4 3 3.5)

 

| c  | c1 | c2 |   | c1>prev c2  | OR | prev c < prev c2 | ?  | c1 | prev c2 |
| 30 | 10 | 10 |   | 10>0 (True) | OR | No need of evaluation | ? | 10 |   |
| 40 | 20 | 20 |   | 20>10(True) | OR | No need of evaluation | ? | 20 |   |
| 25 | 5 | 20 |   | 5>20(False) | OR | 40<20(False) | ? |   | 20 |
| 20 | 25 | 25 |   | 25>20(True) | OR | No need of evaluation | ? | 25 |   |
| 4 | 5 | 5 |   | 5>25(False) | OR | 20<25(True) | ? | 5 |   |
| 4 | 4 | 4 |   | 4>5(False) | OR | 4<5(True) | ? | 4 |   |
| 4.5 | 3 | 4 |   | 3>4(False) | OR | 4<4(False) | ? |   | 4 |
| 4.5 | 3.5 | 4 |   | 3.5>4(False) | OR | 4.5<4(False) | ? |   | 4 |

 

update c2:fills ?[(c1>prev c1) or prev[c]<prev c1;c1;0N] from t c c1 c2 ----------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4 4.5 3 4 4.5 3.5 3.5

 

Yes in that case an accumulator is needed. One method you could choose would be to pass a table through to accumulate while also allowing you to look back to previous rows:

q)update c2:1_@[;c2]{y[c2]:enlist $[(y[c1][0]&gt;last x[c2]) or ((last x[c])&lt;last x[c2]);y[c1][0];last xc2];x,y}/[enlist each {(1#0#x),x}update c2:0 from cc1#t] from t c c1 c2 ---------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4 4.5 3 4 4.5 3.5 4

I was trying something like below. I am not sure if it works in all scenarios. 

I will validate your solution as well and revert soon.

Thanks much for your patience. KX community support and response is just excellent 

update c2: {?[((y>x)|(z<x));y;x]}[0;c1;0^prev c] from t c c1 c2 ---------- 30 10 10 40 20 20 25 5 20 20 25 25 4 5 5 4 4 4 4.5 3 4 4.5 3.5 4

 

 

Yes that’s much cleaner - as you only ever compute one value c2 and only look back 1 step. this will do exactly as you need.

From the Primary Accumulator list, select 0. From the First list, select Increment primary. From the Second list, select Use primary.Defines a custom accumulator operator. Accumulators are operators that maintain their state (e.g. totals, maximums, minimums,  click test   and related data) as documents . If you have access to Accumulator manager, you can access the Accumulator … To locate a record, you can sort each column alphabetically, …

Thanks for confirming. I checked both solutions and the result column matches exactly for my bigger data set.