{"id":418,"date":"2018-07-13T08:41:22","date_gmt":"2018-07-13T06:41:22","guid":{"rendered":"http:\/\/cwiok.pl\/?p=418"},"modified":"2018-07-13T08:41:22","modified_gmt":"2018-07-13T06:41:22","slug":"accumulating-lists-in-power-query-using-list-acculumate","status":"publish","type":"post","link":"https:\/\/cwiok.pl\/index.php\/en\/2018\/07\/13\/accumulating-lists-in-power-query-using-list-acculumate\/","title":{"rendered":"Accumulating lists in Power Query using&#8230; List.Acculumate()"},"content":{"rendered":"<p>List.Accumulate is a very powerful function that is often overlooked, when doing Power Query transformations. Its basic behaviour is explained in the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/query-bi\/m\/list-accumulate\">reference<\/a>. How this function works is accumulates a result from a specified operation <strong>(accumulator function)<\/strong> starting from the initial value &#8211; seed &#8211;\u00a0 and going row by row till the end of a specified list. <a href=\"http:\/\/radacad.com\/list-accumulate-hidden-gem-of-power-query-list-functions-in-power-bi\">Radacad<\/a> greatly explained the possibilities of the function. I treat List.Accumulate as a function that lets me access a previous row. Something that is very often expected by customers using Excel sheets as data sources. This enables me to e.g. detect a change in ID or date \u2013 from my experience 90% of the cases.<\/p>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-451\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png\" alt=\"\" width=\"1200\" height=\"628\" srcset=\"https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png 1200w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-300x157.png 300w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-768x402.png 768w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-1024x536.png 1024w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<p>But how do to it? Examples provided by Radacad are great, but I want to truely accumulate lists in Power Query\u2026<\/p>\n<p>Let us go through the syntax basing on an easy example of cummulative sum. In this case I have a simple list with 10 numbers.<\/p>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-420\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image.png\" alt=\"\" width=\"181\" height=\"267\" \/><\/a><\/p>\n<p>To create a cummulative sum using List.Accumulate, I type:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">Cumulative_new  = List.Accumulate(#\"Changed Type\"[Values],{0}, (sum,index) =&gt;  if index = #\"Changed Type\"[Values]{0} then {#\"Changed Type\"[Values]{0}} else sum&amp; {List.Last(sum) + index})<\/pre>\n<p>The result is a list with cummulative values:<\/p>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-422\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-1.png\" alt=\"\" width=\"128\" height=\"266\" \/><\/a><\/p>\n<p>But first let us go through the syntax:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">List.Accumulate(#\"Changed Type\"[Values],{0}, (sum,index) =&gt;  if index = #\"Changed Type\"[Values]{0} then {#\"Changed Type\"[Values]{0}} else sum&amp; {List.Last(sum) + index})\r\n\r\n<\/pre>\n<p>First part points to the list that we will iterate through. In our case it is a single column with numbers 1 to 10:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">#\"Changed Type\"[Values]<\/pre>\n<p>Next part is our seed \u2013 initial value of the accumulator. In our case {0} &#8211; a list with a single value 0:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">{0}<\/pre>\n<p>And finally the accumulator:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">(sum,index) =&gt;  if index = #\"Changed Type\"[Values]{0} then {index} else sum&amp; {List.Last(sum) + index})<\/pre>\n<p>For a reference: index \u2013 this is the current value of the row in the list you are iterating through, sum \u2013 this is the result of the accumulator.<\/p>\n<p>If the current value of the list is the first value of the list, the result of the accumulator is a list with the first value \u2013 which is index, thus writing it as {index}. Below line is important, because we do not want the seed to be the first value.We cannot set the seed to the first value, because accumulator will try to add seed to the first value.<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">if index = #\"Changed Type\"[Values]{0} then {index}<\/pre>\n<p>Code below states: If index is not the first value of the iterated list, I want to append the list (remember {}) containing one value \u2013 List.Last(sum) + index to the result of the accumulator (in the second step, this would be {1}). List.Last(sum) + index means that I want to take the last value of the accumulator and add index to it. This will produce a list with one value e.g.{3} which I will append to the list \u2013 resulting in {1,3}. After repeating steps 10 times I will end up with a list of cumulative sums.<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">else sum&amp; {List.Last(sum) + index})<\/pre>\n<p>The final step is combining the table with the list:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">#\"Converted to Table\" = Table.FromList(Cumulative_new, Splitter.SplitByNothing(), null, null, ExtraValues.Error),    \r\n\/\/I merge two columns into a table\r\nAdd_columns= Table.FromColumns(Table.ToColumns( #\"Changed Type\")&amp;{Cumulative_new})<\/pre>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-424\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-2.png\" alt=\"\" width=\"320\" height=\"298\" srcset=\"https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-2.png 320w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-2-300x279.png 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/p>\n<p>My whole code:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\" title=\"Whole code\">let\r\n     Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText(\"i45WMlSK1YlWMgKTxmDSBEyagkkzMGkOJi3ApCWYNDRQio0FAA==\", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Values = _t]),\r\n     #\"Changed Type\" = Table.TransformColumnTypes(Source,{{\"Values\", Int64.Type}}),\r\n      Cumulative_new  = List.Accumulate(#\"Changed Type\"[Values],{0}, (sum,index) =&gt;  if index = 1 then {index} else sum&amp; {List.Last(sum) + index}),\r\n      #\"Converted to Table\" = Table.FromList(Cumulative_new, Splitter.SplitByNothing(), null, null, ExtraValues.Error),\r\n  Cumulative_new_new  = List.Accumulate(#\"Changed Type\"[Values], {0}, (sum,index) =&gt;   sum&amp;{ index}),\r\n     \r\n     \/\/I merge two columns into a table\r\n     Add_columns= Table.FromColumns(Table.ToColumns( #\"Changed Type\")&amp;{Cumulative_new})\r\n   \r\nin\r\n     Add_columns<\/pre>\n<p><a href=\"https:\/\/community.powerbi.com\/t5\/Desktop\/Adding-conditional-index-based-on-changing-field-in-Power-Query\/m-p\/436951\/highlight\/true#M201532\">Another example<\/a> is straight out of the PowerBI forum. The case is simple, create a special index that grows whenever the column with the product changes:<\/p>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-434 size-full\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/image-3.png\" alt=\"\" width=\"264\" height=\"300\" \/><\/a><\/p>\n<p>The whole code for the solution:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\" title=\"Solution from the forum\">let\r\n     Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText(\"i45WclSK1UElPTFIRxxsuEgsAA==\", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Category = _t]),\r\n     #\"Changed Type\" = Table.TransformColumnTypes(Source,{{\"Category\", type text}}),\r\n     #\"Added Index\" = Table.AddIndexColumn(#\"Changed Type\", \"Index\", 0, 1),\r\n    \r\n     New_app = List.Accumulate(#\"Added Index\"[Index],{0}, (state,current) =&gt;  if current = 0 then {1} else if #\"Added Index\"{current-1}[Category] = #\"Added Index\"{current}[Category] then state &amp; {List.Last(state)} else state &amp; {List.Last(state)+1}),\r\n     Add_columns= Table.FromColumns(Table.ToColumns(#\"Added Index\")&amp;{New_app}),\r\n    \r\n     #\"Removed Columns1\" = Table.RemoveColumns(Add_columns,{\"Column2\"}),\r\n     #\"Renamed Columns\" = Table.RenameColumns(#\"Removed Columns1\",{{\"Column1\", \"Product\"}, {\"Column3\", \"Index\"}})\r\nin\r\n     #\"Renamed Columns\"<\/pre>\n<p>The line worth mentioning is:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true \">New_app = List.Accumulate(#\"Added Index\"[Index],{0}, (state,current) =&gt;  if current = 0 then {1} else if #\"Added Index\"{current-1}[Category] = #\"Added Index\"{current}[Category] then state &amp; {List.Last(state)} else state &amp; {List.Last(state)+1}),<\/pre>\n<p>It is very similar to the previous example. Only exception is if else condition which evaluates expression:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">#\"Added Index\"{current-1}[Category] = #\"Added Index\"{current}[Category]<\/pre>\n<p>Mind that we iterate through index column. This line checks if Category in the current row is the same as in the previous one. If it is, it appends the list with the last value:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">state &amp; {List.Last(state)}<\/pre>\n<p>If it isn\u2019t, adds 1 to the last value:<\/p>\n<pre class=\"toolbar:2 wrap:true scroll:true lang:default decode:true\">state &amp; {List.Last(state)+1}),<\/pre>\n<p><a href=\"https:\/\/community.powerbi.com\/t5\/Desktop\/Repeat-last-date-for-each-row\/m-p\/441429\/highlight\/true#M203838\">Here<\/a> is my yet another example from the forum.<\/p>\n<p>And that is it! Let me know, what you think if this approach to List.Accumulate()!<\/p>\n<p>Thanks!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>List.Accumulate is a very powerful function that is often overlooked, when doing Power Query transformations. Its basic behaviour is explained in the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/query-bi\/m\/list-accumulate\">reference<\/a>. How this function works is accumulates a result from a specified operation <strong>(accumulator function)<\/strong> starting from the initial value &#8211; seed &#8211;  and going row by row till the end of a specified list. <a href=\"http:\/\/radacad.com\/list-accumulate-hidden-gem-of-power-query-list-functions-in-power-bi\">Radacad<\/a> greatly explained the possibilities of the function. I treat List.Accumulate as a function that lets me access a previous row. Something that is very often expected by customers using Excel sheets as data sources. This enables me to e.g. detect a change in ID or date \u2013 from my experience 90% of the cases.<\/p>\n<p><a href=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-451\" src=\"http:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png\" alt=\"\" width=\"1200\" height=\"628\" srcset=\"https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08.png 1200w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-300x157.png 300w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-768x402.png 768w, https:\/\/cwiok.pl\/wp-content\/uploads\/2018\/07\/artyku\u0142_08-1024x536.png 1024w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<div class=\"tech_read_more\"><a href=\"https:\/\/cwiok.pl\/index.php\/en\/2018\/07\/13\/accumulating-lists-in-power-query-using-list-acculumate\/\">Read More<\/a><\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[],"class_list":["post-418","post","type-post","status-publish","format-standard","hentry","category-power-query"],"_links":{"self":[{"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/posts\/418","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/comments?post=418"}],"version-history":[{"count":1,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/posts\/418\/revisions"}],"predecessor-version":[{"id":1305,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/posts\/418\/revisions\/1305"}],"wp:attachment":[{"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/media?parent=418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/categories?post=418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cwiok.pl\/index.php\/wp-json\/wp\/v2\/tags?post=418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}