Forum Discussion
Cumulative sum in powerquery editor
Your description is not clear to me. For example, you write:
- skips the datadays and unit values with an earlier expiry date than the dataday?
But there are no examples in your data where the expiry date occurs before the dataday date on the same row
- expiry date of 8 June for a 7 June dataday -- but 8 June occurs after 7 June not before
- expiry date of 8 June for a 8 June dataday -- again 8 June is not before 8 June
If what you really mean is to exclude those situations where the expiry date is the same as or before the data day, there is only a single instance (where they are the same.
If you mean something else, you can adjust the comparison operator in the code below.
- Group by Date and Aggregate by Sum of Volume
- Add running total column
- In the code below I chose to use List.Generate, as it does not require an additional Index column
let
//This group of lines is to transform the result of pasting your screenshot into Excel into something usable.
// replace them with your actual data source
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type date}, {"Column2", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Column2", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Column2.1", "Column2.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Column2.1", Int64.Type}, {"Column2.2", type date}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"Column1", "DataDay"}, {"Column2.1", "Volume"}, {"Column2.2", "ExpiryDay"}}),
//-----------------------------------
//Group Rows by DataDay Sum the Volume
#"Grouped Rows" = Table.Group(#"Renamed Columns", {"DataDay"}, {
{"Total", (t)=> List.Sum(Table.SelectRows(t, each [ExpiryDay]>[DataDay])[Volume]), type nullable number}}),
//Add Running Total Column
#"Running Total" =
let
vol = List.Buffer(#"Grouped Rows"[Total]),
runT = List.Generate(
()=>[rt = vol{0}, idx=0],
each [idx] < List.Count(vol),
each [rt = [rt] + vol{[idx]+1}, idx = [idx]+1],
each [rt]),
res = Table.FromColumns(
Table.ToColumns(#"Grouped Rows") & {runT},
type table[DataDay=date, Volume=Int64.Type, Volume Running Total=Int64.Type])
in
res
in
#"Running Total"
Results from your Data
If you want something else, please add sufficient detail
Hi, thank you very much for your reply, in the aggregate value for June 9 (and June 10), I would like to exclude these two values because these dates are earlier than June 9 (June 8 < June 9), so the correct value for June 9 would be 71 and the correct value for June 10 would be 92
- ronrsnfld3 years agoSuper User
Ok, I think I understand now. We will try the following:
- Group by DataDay and SUM the volume
- Sort the table in Date order ascending
- Group by ExpiryDay and SUM the volume
- Sort the table in Date order Ascending
- Add Running Total columns to each of the above Grouped tables
- Using a custom function for this so as to simplify the code
- Correct the RT column of the DataDay table by subtracting the last amount in the ExpiryDate column where the Date in ExpiryDay RT is less than that in the DataDay RT
Note that the first lines are merely to transform your data so I can use it, since you only provided a screenshot and not text information that could be copy/pasted
Running Total Custom Function
Rename fnRT
//Running Total Returns a Table //Rename: "fnRT" (tbl as table, col as text)=> let values = List.Buffer(Table.Column(tbl,col)), colNames= List.Buffer(Table.ColumnNames(tbl)), RT = List.Generate( ()=> [rt = values{0}, idx = 0], each [idx] < List.Count(values), each [rt = [rt] + values{[idx]+1}, idx = [idx]+1], each [rt] ), res = Table.FromColumns( Table.ToColumns(tbl) & {RT}, colNames & {col & " Running Total"} ) in resMain Query
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content], #"Changed Type" = Table.TransformColumnTypes(Source,{{"DataDay", type date}, {"Volume", Int64.Type}, {"ExpiryDay", type date}}), //Group Rows by DataDay; Sum the Volume #"Grouped DataDay" = Table.Group(#"Changed Type", {"DataDay"}, { {"Totals by DataDay", each List.Sum([Volume]), Int64.Type}}), #"Sorted DataDay" = Table.Sort(#"Grouped DataDay",{{"DataDay", Order.Ascending}}), //Group Rows by Expiry Day; Sum the Volume #"Group ExpiryDay" = Table.Group(#"Changed Type",{"ExpiryDay"},{ {"Totals by ExpiryDay", each List.Sum([Volume]), Int64.Type} }), #"Sorted ExpiryDay" = Table.Sort(#"Group ExpiryDay",{{"ExpiryDay", Order.Ascending}}), //Add Running Total Column by DataDay #"RT DataDay" = fnRT(#"Sorted DataDay","Totals by DataDay"), #"RT ExpiryDay" = fnRT(#"Sorted ExpiryDay", "Totals by ExpiryDay"), //Subtract ExpiryDays prior or equal to dataday #"Corr RT" = Table.AddColumn(#"RT DataDay", "Corrected Running Total", (c)=> c[Totals by DataDay Running Total] - (try Table.Last(Table.SelectRows(#"RT ExpiryDay", each [ExpiryDay] < c[DataDay]))[Totals by ExpiryDay Running Total] otherwise 0), Int64.Type), #"Removed Columns" = Table.RemoveColumns(#"Corr RT",{"Totals by DataDay", "Totals by DataDay Running Total"}) in #"Removed Columns"Data
Results
- streli3 years agoHelper I
Hi ronrsnfld, thank you very much for your reply, I will be able to check your solution proposal on Monday, but I see that the final result is correct 🙂
- streli3 years agoHelper I
Hi, thanks again for yor reply!! Can you help me how to do this?
- ronrsnfld3 years agoSuper User
- Paste the custom function as a new query into the Advanced Editor
- Rename it as per the instructions
- Paste the main query as a new query into the Advanced Editor
- Change the Source line to reflect your actual data source
- Paste the custom function as a new query into the Advanced Editor
- Group by DataDay and SUM the volume