Power Query - Weighted average - excel

I have the following table on Power Query that contains a quantity of a product bought and his price:
I want to create another third column with the current average purchase price, however, I need to consider the history and the average should be weighted:
Can anyone help me?

To calculate a running weighted average, you merely have to generate a running total cost column (Price x Quantity) and a running total quanity column, then divide one by the other:
There are various ways to do this, and you don't need to do this by adding columns to the table, but I did it so you can examine the steps involved.
M-Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Month", type text}, {"Quantity", Int64.Type}, {"Price", type number}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Cost", each [Quantity]*[Price]),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "runTotCost", each List.Sum(List.Range(#"Added Custom"[Cost],0,[Index]))),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "runTotQuant", each List.Sum(List.Range(#"Added Custom"[Quantity],0,[Index]))),
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Weighted Average", each [runTotCost] / [runTotQuant]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom3",{"Index", "Cost", "runTotCost", "runTotQuant"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Weighted Average", type number}})
in
#"Changed Type1"
For better understanding, I suggest you do an internet search for methods of generating running totals. There are other methods that are more complicated, but more efficient.

Related

Excel (or) Power BI, Rolling Sum

Is there any way in Excel Pivot or Power BI to do the rolling sum of the given data (let say monthly)?
Let say I have a list of cases, each row represent case count and amount. The project start date and end date varied as follows.
For, simplicity, if I demonstrate the data graphically, would be as follows.
What I'm try to do is to aggregate how much case counts and amounts in total for each chunk of month.
My goal is to produce below list using Pivot (if Pivot is not possible, then by Power Query) directly.
I could produce monthly aggregates using Filter function and Sum, then pivot that data to produce above result.
If there is a direct way of producing that aggregates in one step, that would be better. Please suggest it for me.
Please see sample data in below link
https://docs.google.com/spreadsheets/d/1vAKElb2-V_If-MMlPwHk_VGhYr8pkOg_gQfRYRrkbtc/edit?usp=share_link
Excel file in Zip
https://drive.google.com/file/d/1QqgNUrJlBuvin7iecsxsvexrGZXFIt-g/view?usp=share_link
Thank you in advance
LuZ
You can load the data into powerquery and transform from left to data table on right
code for that is
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom1" = Table.AddColumn(Source, "Date", each List.Generate(()=>[x=[Start Date],i=0], each [i]<12, each [i=[i]+1,x=Date.AddMonths([x],1)], each [x])),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom1", "Date"),
#"Added Custom" = Table.AddColumn(#"Expanded Custom", "Year", each Date.Year([Date])),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "Month", each Date.Month([Date])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Start Date", "End Date", "Date"})
in #"Removed Columns"
Afterwards, load the powerquery back into excel as pivot report and generate your table
Alternatively, just use use
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom1" = Table.AddColumn(Source, "Date", each List.Generate(()=>[x=[Start Date],i=0], each [i]<12, each [i=[i]+1,x=Date.AddMonths([x],1)], each [x])),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom1", "Date"),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Custom",{"Start Date", "End Date"}),
#"Grouped Rows" = Table.Group(#"Removed Columns", {"Date"}, {{"Amount", each List.Sum([Amount]), type number}, {"Case Count", each List.Sum([Case Count]), type number}}),
#"Changed Type" = Table.TransformColumnTypes(#"Grouped Rows",{{"Date", type date}, {"Amount", type number}, {"Case Count", type number}})
in #"Changed Type"
to generate this table, then graph it

Powery Query - return last value from list of dates

I have a query that is indexed with dates. I have a running total that I need to know the last value based on the last row for that date. A picture for context,
If possible, I would like to create a custom column to show the last value for that specified date.
Try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Index", Int64.Type}, {"Amount", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type","data",(i)=>Table.Last(Table.SelectRows(#"Changed Type", each [Date]=i[Date]))[Amount])
in #"Added Custom"
Similarly, for specific person within date
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Index", Int64.Type}, {"Amount", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type","data",(i)=>Table.Last(Table.SelectRows(#"Changed Type", each [Person]=i[Person] and [Date]=i[Date]))[Amount])
in #"Added Custom"
Or if rows are out of order, and you need to sort on index before looking for last row
#"Added Custom" = Table.AddColumn(#"Changed Type","data",(i)=>Table.Last(Table.Sort(Table.SelectRows(#"Sorted Rows", each [Person]=i[Person] and [Date]=i[Date]),{{"Index", Order.Ascending}}))[Amount])
You could also group, get last row, then expand
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Grouped Rows" = Table.Group(Source, {"Date", "Person"}, {
{"expandme", each _, type table},
{"data", each Table.Last(_)[Amount], type number}
}),
#"Expanded" = Table.ExpandTableColumn(#"Grouped Rows", "expandme", {"Index"}, {"Index"})
in #"Expanded"

Finding max function in custom column in Power query

I am trying to create two custom column for flag in in Power query .On the basis County ,Year , month I am trying to find the Latest month in a country Flag and latest common month available in all the country.The data looks like below:
I have tried below measure...:
=var year_x= CALCULATE(MAX([Year]),ALLEXCEPT('tblename','tablename'[Country]))
var month_x = CALCULATE(max([Month No]),FILTER(ALLEXCEPT('tablename','tablename'[CountryI]),'tablename'[Year]=year_x))
return month_x
But this will not solve my problem as I want to create one custom flag in the power query.I know we can do this in Power BI...but no idea in Excel power query
Please help me to find one option for this
Try:
M-Code
let
Source = Excel.CurrentWorkbook(){[Name="Table20"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,
{{"Country", type text}, {"Year", Int64.Type}, {"Month No", Int64.Type}}),
//Country List
countries = List.Distinct(Table.Column(#"Changed Type","Country")),
//Calculate full date
#"Added Custom" = Table.AddColumn(#"Changed Type", "fullDate", each #date([Year],[Month No],1),type date),
//determine latest month flag by country
#"Grouped Rows" = Table.Group(#"Added Custom", {"Country"}, {{"grouped",
each _, type table [Country=nullable text, Year=nullable number, Month No=nullable number, fullDate=date]},
{"latest fullDate", each List.Max([fullDate]), type date}}),
#"Expanded grouped" = Table.ExpandTableColumn(#"Grouped Rows", "grouped", {"Year", "Month No", "fullDate"}, {"Year", "Month No", "fullDate"}),
#"Added Custom1" = Table.AddColumn(#"Expanded grouped", "Latest Month Flag", each if [latest fullDate] = [fullDate] then 1 else 0),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"latest fullDate"}),
//Determine latest month flag for ALL countries
#"Grouped Rows1" = Table.Group(#"Removed Columns", {"fullDate"}, {{"Grouped", each _, type table [Country=nullable text, Year=nullable number, Month No=nullable number, fullDate=nullable date, Latest Month Flag=number]}}),
#"Added Custom2" = Table.AddColumn(#"Grouped Rows1", "Latest month ALL countries", each List.Count(
List.RemoveMatchingItems(countries, Table.Column([Grouped],"Country"))) = 0),
#"Grouped Rows2" = Table.Group(#"Added Custom2", {"Latest month ALL countries"}, {{"Grouped", each _, type table [fullDate=nullable date, Grouped=table, Latest month ALL countries=logical]}, {"maxAll", each List.Max([fullDate]), type nullable date}}),
#"Expanded Grouped" = Table.ExpandTableColumn(#"Grouped Rows2", "Grouped", {"fullDate", "Grouped"}, {"fullDate", "Grouped.1"}),
#"Added Custom3" = Table.AddColumn(#"Expanded Grouped", "Latest month ALL countries Flag", each if [maxAll] = [fullDate] and
[Latest month ALL countries] = true
then 1 else 0),
#"Expanded Grouped.1" = Table.ExpandTableColumn(#"Added Custom3", "Grouped.1", {"Country", "Year", "Month No", "fullDate", "Latest Month Flag"}, {"Country", "Year", "Month No", "fullDate.1", "Latest Month Flag"}),
#"Removed Columns1" = Table.RemoveColumns(#"Expanded Grouped.1",{"Latest month ALL countries", "fullDate", "fullDate.1", "maxAll"}),
#"Sorted Rows" = Table.Sort(#"Removed Columns1",{{"Country", Order.Descending}, {"Year", Order.Ascending}, {"Month No", Order.Ascending}})
in
#"Sorted Rows"
Original Data
Results
*Note: If there are no common dates in one of the countries, there will be no flag in the ALL countries column
Try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom", each Number.From([Year])*100+Number.From([Month No])),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Country"}, {{"Count", each List.Max([Custom]), type number}}),
Maxcommon = List.Min(Table.Group(#"Added Custom", {"Country"}, {{"Count", each List.Max([Custom]), type number}})[Count]),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "latest common", each if [Custom]=Maxcommon then 1 else 0),
#"Merged Queries" = Table.NestedJoin(#"Added Custom1" ,{"Country"},#"Grouped Rows",{"Country"},"Table2",JoinKind.LeftOuter),
#"Expanded Table2" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"Count"}, {"Count"}),
#"Added Custom2" = Table.AddColumn(#"Expanded Table2", "latest month Flag", each if [Custom]=[Count] then 1 else 0),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Custom", "Count"})
in #"Removed Columns"

Max if with multiple criteria in Power query

I have table with sales
I want to find the Product for each SalesName with Maximum Revenue By Month.
And if this Value (Revenue) is > the 70% of TotalRevenue of SalesName By Month (Sum of all products sold during the month), then I need the Product Name.
Else I need to find the Product Names of 2 Larges Revenues during the month.
[Please see the attached image]
Sample solution below
The hardest part would be getting top products. You do this by grouping and adding an index, then filtering. The rest is just merging all the tables together and adding a custom column to decide which answer to show
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"SalesName", type text}, {"Product", type text}, {"Month", type text}, {"Revenue", Int64.Type}}),
// find top 2 Product for Salesname/Month
#"Grouped Rows" = Table.Group(#"Changed Type", {"SalesName","Month"}, {{"All", each Table.AddIndexColumn(Table.Sort(_,{{"Revenue", Order.Descending}}),"Index",1,1), type table}}),
#"Expanded All" = Table.ExpandTableColumn(#"Grouped Rows", "All", {"Product", "Revenue", "Index"}, {"Product", "Revenue", "Index"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded All", each ([Index] =1 or [Index]=2)),
// Combine the two Products into one row separated by a ;
Top2= Table.Group( #"Filtered Rows", {"SalesName", "Month"}, {{"Top2", each Text.Combine([Product], "; "), type text}}),
//70% of Revenue for Salesname/Month
Percent70 = Table.Group(#"Changed Type", {"SalesName", "Month"}, {{"70%Revenue", each .7*List.Sum([Revenue]), type number}}),
//Top product each month for SaleName
#"Filtered Rows2" = Table.SelectRows(#"Expanded All", each [Index] =1),
// Merge in Top2
#"Merged Queries" = Table.NestedJoin(#"Filtered Rows2",{"SalesName", "Month"},Top2,{"SalesName", "Month"},"Top2",JoinKind.LeftOuter),
#"Expanded Top2" = Table.ExpandTableColumn(#"Merged Queries", "Top2", {"Top2"}, {"Top2"}),
// Merge in 70% Revenue
#"Merged Queries2" = Table.NestedJoin(#"Expanded Top2",{"SalesName", "Month"},Percent70,{"SalesName", "Month"},"70Percent",JoinKind.LeftOuter),
#"Expanded 70Percent" = Table.ExpandTableColumn(#"Merged Queries2", "70Percent", {"70%Revenue"}, {"70%Revenue"}),
// Compare revenue to 70% revenue and pick either Product or top 2 Products
#"Added Custom" = Table.AddColumn(#"Expanded 70Percent", "Custom", each if [Revenue]>[#"70%Revenue"] then [Product] else [Top2]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index", "Top2", "70%Revenue"})
in #"Removed Columns"

Pivoting multiple columns using PowerQuery in Excel

I'm trying to pivot multiple columns of the following table:
The result I would like to get is the following:
I'm using PowerQuery in Excel, but I couldn't manage to pivot multiple columns (i.e., I can pivot the column "Number", for example). Anyone has any insight about the correct usage of PowerQuery?
Here is an answer to first version of your question
let
src = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
lettersABC=List.Distinct(src[Attribute1]),
count=List.Count(lettersABC),
lettersNUM=List.Transform({1..count}, each "Letter"&Number.ToText(_)),
numbersNUM=List.Transform({1..count}, each "Number"&Number.ToText(_)),
group = Table.Group(src, {"ID"}, {{"attr", each Record.FromList(lettersABC&[Attribute2], lettersNUM&[Attribute1])}}),
exp = Table.ExpandRecordColumn(group, "attr", lettersNUM&lettersABC, lettersNUM&numbersNUM)
in
exp
For example, if the country header is in cell A1 then this formula in D2:
= "tax rate" & CountIf( $A$2:$A2, $A2 )
then copy the formula cell D2 and paste it in the cells below it should give you something like:
country tax rate Income thresholds count
UK 20% 35k tax rate1
UK 30% 50k tax rate2
.....
Now you can pivot by that extra count column with PivotTable or PowerQuery. You can use the same formula for the Income th1, Income th2, etc columns.
Here's a solution using the PQ ribbon, but note the last step (Group By) is not dynamic e.g. you would have to change it if you wanted 4+4 columns per country.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"country", type text}, {"tax rate", type number}, {"Income thresholds", type text}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1),
#"Grouped Rows" = Table.Group(#"Added Index", {"country"}, {{"Min Index", each List.Min([Index]), type number}, {"All Rows", each _, type table}}),
#"Expanded All Rows" = Table.ExpandTableColumn(#"Grouped Rows", "All Rows", {"Income thresholds", "Index", "tax rate"}, {"Income thresholds", "Index", "tax rate"}),
#"Added Custom" = Table.AddColumn(#"Expanded All Rows", "Column Index", each [Index] - [Min Index] + 1),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Min Index", "Index"}),
#"Duplicated Column" = Table.DuplicateColumn(#"Removed Columns", "Column Index", "Column Index - Copy"),
#"Added Prefix" = Table.TransformColumns(#"Duplicated Column", {{"Column Index", each "tax rate" & Text.From(_, "en-AU"), type text}}),
#"Pivoted Column" = Table.Pivot(#"Added Prefix", List.Distinct(#"Added Prefix"[#"Column Index"]), "Column Index", "tax rate", List.Max),
#"Added Prefix1" = Table.TransformColumns(#"Pivoted Column", {{"Column Index - Copy", each "Income thresholds" & Text.From(_, "en-AU"), type text}}),
#"Pivoted Column1" = Table.Pivot(#"Added Prefix1", List.Distinct(#"Added Prefix1"[#"Column Index - Copy"]), "Column Index - Copy", "Income thresholds", List.Max),
#"Grouped Rows1" = Table.Group(#"Pivoted Column1", {"country"}, {{"tax rate1", each List.Max([tax rate1]), type number}, {"tax rate2", each List.Max([tax rate2]), type number}, {"tax rate3", each List.Max([tax rate3]), type number}, {"Income th1", each List.Max([Income thresholds1]), type text}, {"Income th2", each List.Max([Income thresholds2]), type text}, {"Income th3", each List.Max([Income thresholds3]), type text}})
in
#"Grouped Rows1"

Resources