Forum Discussion
Calculation with previous month's value
I have excel calculation that I would like to replicate in Power Query.
Is this possible in Power Query?
kangx322 try this
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMtQ1ACElHSUjC6VYHSQxI6CYOaqQMUiZGaqYCVDMxABVzBQoZogiZGgGEgJqjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Value = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Value", Int64.Type}}), Value = #"Changed Type"[Value], Loop = List.Generate( ()=>[i=0,j=Value{i},k=j], each [i]<List.Count(Value), each [i=[i]+1, j=Value{i}, k=[k]*3+j*0.5], each[k] ), Custom1 = Table.FromColumns(Table.ToColumns(#"Changed Type")&{Loop},List.Combine({Table.ColumnNames(#"Changed Type"),{"cumulativeValue"}})) in Custom1
10 Replies
- smpa01Community Champion
kangx322 try this
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMtQ1ACElHSUjC6VYHSQxI6CYOaqQMUiZGaqYCVDMxABVzBQoZogiZGgGEgJqjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Value = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Value", Int64.Type}}), Value = #"Changed Type"[Value], Loop = List.Generate( ()=>[i=0,j=Value{i},k=j], each [i]<List.Count(Value), each [i=[i]+1, j=Value{i}, k=[k]*3+j*0.5], each[k] ), Custom1 = Table.FromColumns(Table.ToColumns(#"Changed Type")&{Loop},List.Combine({Table.ColumnNames(#"Changed Type"),{"cumulativeValue"}})) in Custom1- kangx322Frequent Visitor
Thank you.
Could you explain the code little bit?
What if I change my original column name to "Current"? which part of the code would change?Also, would this be only way? I am little worried about the performance as my real data is little big
- smpa01Community Champion
kangx322 if you change the column name Value to Current then you need to change the only one line in code, i.e. following line
Value =#"Changed Type"[Current]
I am not sure if there is any other way to achieve this, unless you are querying from a RDBMS and run a for loop on the server side
- ronrsnfldSuper User
Buffer the list.
Change the third line of code to:
Value = List.Buffer(#"Changed Type"[Value]), - smpa01Community Champion
there are few things you can try out.
A. If you are querying a database, run the loop on the server side.
B. Known PQ performance tuning
https://www.thebiccountant.com/speedperformance-aspects/
C. You can try List. Buffer as ronrsnfld mentioned
D. For calualtion if you prefre List.Generate, you can reduce one step like this
Loop = List.Generate( ()=>[i=0,k=Value{i}], each [i]<List.Count(Value), each [i=[i]+1, k=[k]*3+Value{i}*0.5], each[k] )E You can obtain same result by using an Accumulator too
Accumulator = List.Skip( List.Accumulate( Value, {0}, (state, current) => if current = Value{0} then state & {List.Last(state) + current} else state & {List.Last(state) * 3 + current * 0.5} ) )The combinded code is here and I am not sure wich one would give you better performance, you need to test it out.
The combined code is here.
let Source = Table.FromRows( Json.Document( Binary.Decompress( Binary.FromText( "i45WMjIwMtQ1ACElHSUjC6VYHSQxI6CYOaqQMUiZGaqYCVDMxABVzBQoZogiZGgGEgJqjQUA", BinaryEncoding.Base64 ), Compression.Deflate ) ), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Value = _t] ), #"Changed Type" = Table.TransformColumnTypes(Source, {{"Date", type date}, {"Value", Int64.Type}}), Value = #"Changed Type"[Value], Loop = List.Generate( () => [i = 0, k = Value{i}], each [i] < List.Count(Value), each [i = [i] + 1, k = [k] * 3 + Value{i} * 0.5], each [k] ), Accumulator = List.Skip( List.Accumulate( Value, {0}, (state, current) => if current = Value{0} then state & {List.Last(state) + current} else state & {List.Last(state) * 3 + current * 0.5} ) ), Custom1 = Table.FromColumns( Table.ToColumns(#"Changed Type") & {Accumulator}, List.Combine({Table.ColumnNames(#"Changed Type"), {"cumulativeValue"}}) ) in Custom1Would have been a lot easier performance wise, had it been achievable in DAX and I don't know if I can do recursion of this sort in DAXAlexisOlson
- AlexisOlsonSuper User
It's possible in DAX but complexity is O(n^2) rather than the O(n) in Power Query since you have to calculate each row from the beginning instead of the last row.
Cumulative = VAR Subtable = FILTER ( Query1, Query1[Date] <= EARLIER ( Query1[Date] ) ) VAR AddIndex = ADDCOLUMNS ( Subtable, "Index", RANKX ( Subtable, Query1[Date],, DESC ) ) VAR MaxIndex = MAXX ( AddIndex, [Index] ) RETURN SUMX ( AddIndex, POWER ( 3, [Index] - 1 ) * [Value] * IF ( [Index] = MaxIndex, 1, 0.5 ) )