Power BI: Subtract current row from previous row - powerbi

Hi I have a below requirement.
I have a table named forcast table with forecast version and values.
I need to initially calculate the sum of values for each forecast. and subtract the forecast from the previous row(for 2022.7: I need to take 2022.8 and subtract 2022.7, for 2022.8: I need to take 2022.9 and subtract 2022.8 and so on)
Atlast, I have to build a graph with the differences.
Please find the clear requirement in below link.
https://github.com/samantha280/powerbi/blob/main/Book2.xlsx

powerquery / M on your forecast table
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Forecast", type number}, {"Vals", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Forecast"}, {{"Vals", each List.Sum([Vals]), type nullable number}}),
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each try [Vals]-#"Added Index"{[Index]-1}[Vals] otherwise null),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([Custom] <> null)),
#"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"Vals", "Index"})
in #"Removed Columns"

Related

Adding random rows within a group in power bi

I would like to know how to create the last column, Audit. To determine whether it is Included or Not Included the sum of any rows in "Average meeting per Day" within the same Employee/Day should match the "Actual Meeting" the employee attended.
I've taken this as an Example dataset -
Further, use Group By and Conditional column to have the Audit added.
Group by -
Conditional Column -
Result -
Code -
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45W8s3PS0msVNJRMgRiAz1TMGkEJBOVYnVwSBtjShuBJQzhZBJYOqQ0tRhZuwlcHqg9=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Day = _t, Emp_ID = _t, #"Actual Meeting" = _t, #"Average Meeting/Day" = _t, Emp_Name = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Day", type text}, {"Emp_ID", Int64.Type}, {"Actual Meeting", type number}, {"Average Meeting/Day", type number}, {"Emp_Name", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Day", "Emp_ID"}, {{"Sum of avg", each List.Sum([#"Average Meeting/Day"]), type nullable number}, {"Actual Meeting", each List.Min([Actual Meeting]), type nullable number}}),
#"Added Conditional Column" = Table.AddColumn(#"Grouped Rows", "Audit", each if [Actual Meeting] = [Sum of avg] then "Included" else "Not Included")
in
#"Added Conditional Column"
Not sure this is going to help, but here goes. Note: not set up to work with duplicate values among the potential items to analyze. No idea if it will work with so many decimals, so that the sum of the decimals might be 0.0000001 off from total and thus not be recognized. Works for me with whole numbers
let
Process=(x as table) as table =>
// Bill Szysz 2017, all combinations of items in list, blows up with too many items to process due to large number of combinations
let ComboList=x[AMD],
find=x[AM]{0},
Source=Table.FromList(List.Transform(ComboList, each Text.From(_))),
AddIndex = Table.AddIndexColumn(Source, "Index", 0, 1),
ReverseIndeks = Table.AddIndexColumn(AddIndex, "RevIdx", Table.RowCount(AddIndex), -1),
Lists = Table.AddColumn(ReverseIndeks, "lists", each
List.Repeat(
List.Combine({
List.Repeat({[Column1]}, Number.Power(2,[RevIdx]-1)),
List.Repeat( {null}, Number.Power(2,[RevIdx]-1))
})
, Number.Power(2, [Index]))
),
ResultTable = Table.FromColumns(Lists[lists]),
#"Replaced Value" = Table.ReplaceValue(ResultTable,null,"0",Replacer.ReplaceValue,Table.ColumnNames(ResultTable )),
#"Added Index" = Table.AddIndexColumn(#"Replaced Value", "Index", 0, 1, Int64.Type),
totals = Table.AddColumn(#"Added Index", "Custom", each List.Sum(List.Transform(Record.ToList( Table.SelectColumns(#"Added Index",Table.ColumnNames(ResultTable )){[Index]}) , each Number.From(_)))),
#"Filtered Rows" = Table.SelectRows(totals, each ([Custom] = find)),
#"Kept First Rows" = Table.FirstN(#"Filtered Rows",1),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Kept First Rows", {"Custom", "Index"}, "Attribute", "Value"),
#"Filtered Rows1" = Table.SelectRows(#"Unpivoted Other Columns", each ([Value] <> "0")),
#"Removed Other Columns" = Table.SelectColumns(#"Filtered Rows1",{"Value"}),
FoundList = Table.TransformColumnTypes(#"Removed Other Columns",{{"Value", type number}}),
#"Merged Queries" = Table.NestedJoin(x, {"AMD"}, FoundList, {"Value"}, "output1", JoinKind.LeftOuter),
#"Expanded output1" = Table.ExpandTableColumn(#"Merged Queries", "output1", {"Value"}, {"Value"}),
#"Calculated Absolute Value" = Table.TransformColumns(#"Expanded output1",{{"Value", each if _=null then "Not Included" else "Included", type text}})
in #"Calculated Absolute Value",
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Day", type text}, {"Employee_ID", Int64.Type}, {"AM", Int64.Type}, {"AMD", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Day", "Employee_ID"}, {{"data", each _, type table [Day=nullable text, Employee_ID=nullable number, AM=nullable number, AMD=nullable number]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each Process([data])),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom",{"Custom"}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Other Columns", "Custom", {"Day", "Employee_ID", "AM", "AMD", "Value"}, {"Day", "Employee_ID", "AM", "AMD", "Value"})
in
#"Expanded Custom"

Power Query Transform data within Group/Buckets

I want to transform a column in Power query. Only the transformation should be applied within the group based on a condition. This is my data.
Here in the above table, I just want to transform Office based column to all 1 if any Office-based column is set to 1 on the particular ID group. But all the Office based column value is 0 on the particular ID group, it should not transform the column.
My expected result would be,
It would be fine, If an additional column can have the transformed column.
try this
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Item", type text}, {"Home Based", Int64.Type}, {"Office Based", Int64.Type}, {"Amount", Int64.Type}}),
// find all IDs with 1 in Office Based
#"Filtered Rows" = Table.SelectRows(#"Changed Type", each ([Office Based] = 1)),
#"Removed Other Columns" = Table.SelectColumns(#"Filtered Rows",{"ID"}),
#"Removed Duplicates" = Table.Distinct(#"Removed Other Columns"),
//merge that back in
#"Merged Queries" = Table.NestedJoin(#"Changed Type", {"ID"}, #"Removed Duplicates", {"ID"}, "Table2", JoinKind.LeftOuter),
#"Expanded Table2" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"ID"}, {"ID.1"}),
// if there was a match convert to 1 otherwise take original number
#"Added Custom" = Table.AddColumn(#"Expanded Table2", "OfficeBased2", each try if Text.Length([ID.1])>0 then 1 else [Office Based] otherwise [Office Based]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Office Based", "ID.1"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"OfficeBased2", "OfficeBased"}})
in #"Renamed Columns"
or the more compact version:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source,"Custom",(i)=>Table.SelectRows(Source, each [ID]=i[ID]) [Office Based]),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Office Based2", each if List.Contains([Custom],1) then 1 else [Office Based]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"Custom", "Office Based"})
in #"Removed Columns"
The first method probably works best for large data sets
Here's another method:
Group by ID
Apply the Table.TransformColumns operation to each subtable
Then re-expand
let
Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Item", type text}, {"Home Based", Int64.Type}, {"Office Based", Int64.Type}, {"Amount", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"ID"}, {
{"Xform", (t)=>Table.TransformColumns(t, {
{"Office Based", each if List.ContainsAny(t[Office Based],{1}) then 1 else 0}}) ,
type table
[ID=nullable text, Item=nullable text, Home Based=nullable number, Office Based=nullable number, Amount=nullable number]}
}),
#"Expanded Xform" = Table.ExpandTableColumn(#"Grouped Rows", "Xform",
{"Item", "Home Based", "Office Based", "Amount"},
{"Item", "Home Based", "Office Based", "Amount"})
in
#"Expanded Xform"

Filter a column in Power Query so that it contains only the last date of each year

Can anyone please advise on how to filter this column in Power Query so that it contains only the last date of each year?
So, this should contain only 3 rows:
31/12/2019
31/12/2020
31/03/2021
Try this
Add custom column to pull out the year
= Date.Year([EndDate])
Add custom column to pull out the max date for each matching year
= (i)=>List.Max(Table.SelectRows(#"Added Custom" , each [Year]=i[Year]) [EndDate])
Add custom column to check the two dates against each other
= if [EndDate]=[MaxDate] then "keep" else "remove"
Filter on that column
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"EndDate", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Year", each Date.Year([EndDate])),
#"Added Custom2" = Table.AddColumn(#"Added Custom","MaxDate",(i)=>List.Max(Table.SelectRows(#"Added Custom" , each [Year]=i[Year]) [EndDate]), type date ),
#"Added Custom1" = Table.AddColumn(#"Added Custom2", "Custom", each if [EndDate]=[MaxDate] then "keep" else "remove"),
#"Filtered Rows" = Table.SelectRows(#"Added Custom1", each ([Custom] = "keep"))
in #"Filtered Rows"
~ ~ ~
another way probably better for larger lists
Add custom column to pull out the year
= Date.Year([EndDate])
Group on year and take the Maximum of the EndDate Column
Merge that back to original data with left outer join and filter
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"EndDate", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Year", each Date.Year([EndDate])),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Year"}, {{"MaxDate", each List.Max([EndDate]), type date}}),
#"Merged Queries" = Table.NestedJoin(#"Changed Type",{"EndDate"}, #"Grouped Rows" ,{"MaxDate"},"Table2",JoinKind.LeftOuter),
#"Expanded Table2" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"MaxDate"}, {"MaxDate"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded Table2", each ([MaxDate] <> null))
in #"Filtered Rows"
This is an older thread, but for those who are looking for the easiest solution, you can use :
= Table.SelectRows(#"Converted to Table", each [Date] = Date.EndOfYear( [Date] ) )
If you want to see the entire code in action, you can paste this in the advanced editor:
let
Source = List.Dates( #date( 2010, 1, 1), Duration.Days( #date( 2022, 12, 31) - #date( 2010, 1, 1 ) ) + 1 , #duration(1,0,0,0) ),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), type table[ Date = Date.Type ] , null, ExtraValues.Error),
#"Filtered Rows" = Table.SelectRows(#"Converted to Table", each [Date] = Date.EndOfYear( [Date] ))
in
#"Filtered Rows"
Hope that helps!
Rick de Groot
https://gorilla.bi

Getting this error: "Expression.Error: The column 't_count' of the table wasn't found. Details: t_count" while executing cummulative sum

Hi I am trying to create a Cummulative sum for "t_count" field in Power BI but everytime I try to run the this formula: List.Sum(List.Range(#"Added Index"[t_count],0,[Hire_Count])) I am getting error that t_count field was not found in the table. Can anyone help me in creating cummulative sum without getting this error? I am sharing full code from advance editor.
let
Source = Excel.Workbook(File.Contents("C:\Users\rabi.jaiswal\Desktop\hr_analytics\EMPLOYEE_ATTRITION_DATA.xlsx"), null, true),
Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Emp_Id", Int64.Type}, {"Emp_Name", type text}, {"email", type text}, {"Join_Date", type date}, {"Joined_As", type text}, {"Department", type text}, {"Manger_Name", type text}, {"Current_Designation", type text}, {"Current_Designation_Start_Date", type date}, {"Work Hours", Int64.Type}, {"Standard_Work_Hours", Int64.Type}, {"Term_Date", type date}}),
#"Removed Columns" = Table.RemoveColumns(#"Changed Type",{"Emp_Id", "Emp_Name", "email", "Joined_As", "Department", "Manger_Name", "Current_Designation", "Current_Designation_Start_Date", "Work Hours", "Standard_Work_Hours"}),
#"Sorted Rows" = Table.Sort(#"Removed Columns",{{"Join_Date", Order.Ascending}}),
#"Added Index" = Table.AddIndexColumn(#"Sorted Rows", "Index", 1, 1, Int64.Type),
#"Renamed Columns" = Table.RenameColumns(#"Added Index",{{"Index", "Hire_Count"}}),
#"Added Conditional Column" = Table.AddColumn(#"Renamed Columns", "t_count", each if [Term_Date] = null then 0 else 1),
#"Added Custom" = Table.AddColumn(#"Added Conditional Column", "Term_total", each List.Sum(List.Range(#"Added Index"[t_count],0,[Hire_Count])))
in
#"Added Custom"
your index starts with one, so try
#"Added Custom" = Table.AddColumn(#"Added Conditional Column", "Term_total", each List.Sum(List.FirstN(#"Added Conditional Column"[t_count],[Index]))),
if your index started from zero, it would be
#"Added Custom" = Table.AddColumn(#"Added Conditional Column", "Term_total", each List.Sum(List.FirstN(#"Added Conditional Column"[t_count],[Index]+1))),

Calculate the sum of Value for the last 365 days - with Power Query

This is how my table looks like in Power Query:
For each combination of date and Customer No (No), I need to calculate the sum of Value for the last 365 days.
I need this in Power Query, I know I could do it with DAX.
Are you looking for a 365 day total as of each and every date in the table? If so, then this seems to work
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"No", Int64.Type}, {"Value", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type" ,"RunningTotal",(i)=>List.Sum(Table.SelectRows(#"Changed Type" , each [No]=i[No] and [Date]>Date.AddDays(i[Date],-365) and [Date]<=i[Date] ) [Value]), type number )
in #"Added Custom"
Or, 365 days before a specific date like 1980/12/31?
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
MaxDate = #date(1980,12,31),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"No", Int64.Type}, {"Value", Int64.Type}}),
#"Filtered Rows" = Table.SelectRows(#"Changed Type", each [Date] <= MaxDate and [Date] > Date.AddDays(MaxDate,-365)),
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"No"}, {{"Total", each List.Sum([Value]), type number}})
in #"Grouped Rows"