PowerBI: Power Query: Dealing with changing column names due to pivots - powerbi

For a report I am making. I have a date column. I extract the months from that column and then pivot the months.
So for example I might have a table like:
Part#
Month
Qty
1
1
10
1
2
10
1
3
10
1
4
10
1
5
10
1
6
10
Which when I pivot it becomes:
Part#
1
2
3
4
5
6
1
10
10
10
10
10
10
I then rename the columns along with doing a few other tasks like creating a column of maximums.
However, since the data I pull is only for 6-months worth. These columns names will change.
In the future it may be:
Part#
4
5
6
7
8
9
1
10
10
10
10
10
10
So a line like:
Table.ReplaceValue(#"Pivoted Column",null,0,Replacer.ReplaceValue,{"1", "2", "3", "4", "5", "6"})
is going to create an error when the columns are 4,5,6,7,8,9. Is there a way to handle this issue?

You'll need to manually code a step to rename the columns after your pivot.
This M code pulls a table like the one in your example from the current workbook in Excel, then pivots as you describe, then renames the columns to Part#, 1st, 2nd, 3rd, 4th, 5th, and 6th. Yes, I said it renames to Part#, even though it doesn't really change that column name. Be sure to include Part# in the list coded in the step even though the Part# name isn't really changing, because you need to account for all column names extracted by Table.ColumnNames. Replace 1st, 2nd, 3rd, 4th, 5th, and 6th with your desired column names.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(Source, {{"Month", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(Source, {{"Month", type text}}, "en-US")[Month]), "Month", "Qty"),
#"Renamed Columns" = Table.RenameColumns(#"Pivoted Column", List.Zip({Table.ColumnNames(#"Pivoted Column"),{"Part#", "1st", "2nd", "3rd", "4th", "5th", "6th"}}))
in
#"Renamed Columns"
List.Zip interweaves two lists together. Here, it interweaves Part# from the original column names (those in the "Pivoted Column" step's table), then Part# from the list coded into #"Renamed Columns, then the next original column name (1 from your first example or 4 from your second example), then 1st from the column list coded into #"Renamed Columns, then the next original column name (2 from your first example or 5 from your second example), then 2nd from the column list coded into #"Renamed Columns, and so forth. This sets up the list needed for Table.RenameColumns.

You can use TableColumNames to get a list of column names, then you can transform that list. So for your example, you could use something like:
= Table.ReplaceValue(#"Pivoted Column",null,0,Replacer.ReplaceValue,List.Skip(Table.ColumnNames(#"Pivoted Column"),1))

Related

Sum product costs with same ID in Power Query

I have multiple rows with same ID but different products/prices. I would like to get this in Power Query (PowerBI) due to the automation.
Excel formula looks like this:
=SUMPRODUCT(IF($A$2:$A$7=A2;$B$2:$B$7))
And the table is:
A (ID)
B (price)
1
10
1
20
1
5
2
3
2
6
2
1
My goal is to get this:
C (Formula-price)
35
35
35
10
10
10
This step represent Column P & Q (Claims List) in this sheet: https://docs.google.com/spreadsheets/d/1J_nl2_Dgam7JDdyzX-urrO2AEXuCzhQkB1nogTLn2eA/edit#gid=0
In powerquery, right click and group on ID. Add a sum of one of the number columns and then below that, choose All rows as the operation.
After grouping use arrows atop the new column to expand the other columns
Sample, without the expansion
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", Int64.Type}, {"Column3", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Column1"}, {{"Count", each List.Sum([Column2]), type nullable number}, {"data", each _, type table }})
in #"Grouped Rows"
So I am guessing a little bit but I think you would like to add the sum of B(price) grouped by A(id) to every row in your table. And you would like to use Powerquery for that.
First step would be to import the table into powerquery, then I duplicate the query and group it by ID. The third step is to merge these table by ID
Step 1
I took the following example data
Goto Data/From Table/Range and you should get
Step2 Right click on the query above and select Duplicate
I named the result sumTbl , grouped it by ID and with price as the column to sum
PS In the above step you can change to Advanced and add a second aggreagtion level and then expand. No need to merge!
The result looks like
Step 3 Now you merge both tables. I merged them as a new one
The result is
Now you only need to expand the column sumTbl
The result will be

How to loop through values in a column in DAX

I have a table that looks like this:
Document PartNum Cost
A 1 5
A 1 5
A 2 3
A 2 3
B 1 1
B 1 1
B 3 4
B 3 4
I am trying to get the SUM of the cost for each part (counted once) on each document. So my new column would look like this:
Document PartNum Cost NewColumn
A 1 5 8
A 1 5 8
A 2 3 8
A 2 3 8
B 1 1 5
B 1 1 5
B 3 4 5
B 3 4 5
In R I would use a for loop, max and an append function of some kind. I am struggling to find a solution using DAX in PowerBI. Thank you in advance!
I have a solution using MQuery & DAX.
#"Changed Type1" = Table.TransformColumnTypes(#"Renamed Columns",{{"PartNum", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type1", "DocPart", each [Document]&[PartNum]),
#"Removed Duplicates" = Table.Distinct(#"Added Custom", {"DocPart"})
Step 1: Make PartNumber type text
Step 2: Create new custom column by concatenation of Document & PartNumber.
Step 3: Remove duplicates from New Custom Column.
Step 4: Now close N apply.
Step 5: create a new Measure using dax:
TotalCost = CALCULATE(SUM(uni[Cost]),ALL(uni[DocPart],uni[PartNumber],uni[Cost]))
Step 6: Drag required columns.
Note: Please refer screenshot for output data before applying code

Power BI Grouping

Location
Won
Lost
Home
3
4
Home
2
3
Home
5
4
Home
4
6
Away
3
4
Away
2
3
Away
5
4
Away
4
6
This is an example table that I have in Power BI. I am trying to create a new table, that groups by Location, sums up the values of won and lost, and adds a third column that has the ratio of sum(won)/sum(lost) called Ratio. So all in all, you have three columns: Location (either home or away), Wins (sum of wins), Lost (sum of lost), ratio (the result of dividing wins and lost, the previous two columns)
How can I write the formula I need in Power BI?
There is a function for that called SUMMARIZE, see docs
May be like:
SUMMARIZE(your_table
, your_table[Location]
, "Total Won", SUM(your_table[Won])
, "Total Lost", SUM(your_table[Lost])
, "Ratio", SUM(your_table[Won]/your_table[Lost])
)
You can also create this using Power Query.
Your existing table is produce by a query named myTable
In Power BI Desktop, select `Queries => Transform"
In the PQ UI, select Home=>Advanced Editor and paste the code below into the window that opens.
You may need to change the name in the second line from myTable to whatever that query is really named
I use the Table.Group function to do the appropriate calculations on each grouped sub-table
M Code
let
Source = myTable,
//Group by Location, then add the columns
#"Grouped Rows" = Table.Group(myTable, {"Location"}, {
{"Wins", each List.Sum([Won]), type nullable number},
{"Losses", each List.Sum([Lost]), type nullable number},
{"Ratio", each List.Sum([Won])/List.Sum([Lost]), type number}
})
in
#"Grouped Rows"
Results from your data above

Return Slicer's Value (trade simulator)

I work with a single table (called sTradeSim) that I have created in PowerQuery. It has 3 columns (Fund1, Fund2, Fund3), each having values from -10 to 10, with an increment of 1.
I also have three separate slicers, each created using an option "Greater than or equal to". Each slicer is having a field assigned to it - Slicer 1 = Fund1, Slicer 2 = Fund2, Slicer 3 = Fund3. Below is a screenshot of Slicer 1.
Right next to these three slicers is a table with three rows. For each row, I would like to retrieve the value of the respective slicers. So the desired result would look like:
Row No 1 = -10.00 (the value of Slicer 1),
Row No 2 = -2.00 (the value of Slicer 2),
Row No 3 = 3.00 (the value of Slicer 3).
Unfortunately, DAX formula that I have developed is always returning 3.00 (the value of the third slicer).
I have tried to find a solution on the forum and combine my SWITCH formula with ALL, ALLEXCEPT, SELECTEDVALUE etc., but it seems like I'm missing something very basic.
mHV_Trades =
SWITCH(
MAX(FundTable[FundsRanked]),
1, MIN(sTradeSim[Fund1]),
2, MIN(sTradeSim[Fund2]),
3, MIN(sTradeSim[Fund3])
)
What you are trying to do doesn't work, because essentially when you place 1 filter on any column on the table, it will filter all the rows that have that value. So, when you apply a filter fund1 = -10 it will also filter the values for fund 2 and fund 3.
You have 2 options:
Create independent tables each with values from -10 to 10
Create a table with all the combinations of -10 to 10 values for every fund.
For your example with 3 funds this works quite nicely (the table has about 10k records), all the combinations of -10 to 10 (21) to the power of 3, the problem with this solution is that depending on the number of funds you have you will run out of space quite quickly.

Pivoting/reshaping a dataframe to have dates as columns

Here is my dataframe:
ID AMT DATE
0 1496846 54.76 2015-02-11
1 1496846 195.00 2015-01-09
2 1571558 11350.00 2015-04-30
3 1498812 135.00 2014-07-11
4 1498812 157.00 2014-08-04
5 1498812 110.00 2014-09-23
6 1498812 1428.00 2015-01-28
7 1558450 4355.00 2015-01-26
8 1858606 321.52 2015-03-27
9 1849431 1046.81 2015-03-19
I would like to make this a dataframe consisting of time series data for each ID. That is, each column name is a date (sorted), and it is indexed by ID, and the values are the AMT values corresponding to each date. I can get so far as doing something like
df.set_index("DATE").T
but from here I'm stuck.
I also tried
df.pivot(index='ID', columns='DATE', values='AMT')
but this gave me an error on having duplicate entries (the IDs).
I envision it as transposing DATE, and then grouping by unique ID and melting AMT underneath.
you want to use pivot_table where there is an aggfunc parameter that handles duplicate indices.
df.pivot_table('AMT', 'DATE', 'ID', aggfunc='sum')
You'll want to choose how to handle the dups. I put 'sum' in there. It defaults to 'mean'