Power Query/Power BI: divide each row by total of another column - powerbi

I'm pretty new using queries and I still need to get on the topic properly.. :)
I'm editing a query in Power BI, and I created a new column that shouls show the division of each cell within a column by the total of another column, as %.
I wrote the following: = Table.AddColumn(#"Renamed Columns", "CONTACTED (CVR)", each [CONTACTED]/[LEADS]), but it divide each cell of the column Contacted by each cell of the column Leads.
Is there any way to do it?
Thanks in advance.
Cheers,
AS

In Power Query:
= Table.AddColumn(#"Renamed Columns", "CONTACTED (CVR)", each [CONTACTED]/List.Sum(#"Renamed Columns"[LEADS]))

This should do the trick, or get you going in the right direction.
You're looking for the Table.Group function aka Transform->Group By in the GUI. Detailed info here: https://msdn.microsoft.com/en-us/library/mt260774.aspx .
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Country", type text}, {"Leads", Int64.Type}, {"Contacted", Int64.Type}, {"User", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Country"}, {{"Leads_Total", each List.Sum([Leads]), type number}, {"Contacted_Total", each List.Sum([Contacted]), type number}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Percent", each [Contacted_Total]/[Leads_Total]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Leads_Total", "Contacted_Total"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Country", "Country2"}}),
#"Result" = Table.Join( Source , "Country" , #"Renamed Columns" , "Country2" , JoinKind.LeftOuter ),
#"Removed Columns1" = Table.RemoveColumns(Result,{"Country2"})
in
#"Removed Columns1"
Hope it helps.

I think this is what you are asking; you need to make your question a MWE next time.
Drag the value (my value is called "Place") into the toolbar on the right hand side twice.
Right click the second value and select "Quick calc"
Make sure the "Summerize Value By" is Sum.
then select percent of grand total under "Show Value As".
that should do it.

Considering your condition per each country how many contacted out of leads,
that'll do:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Types = Table.TransformColumnTypes(Source,{{"Country", type text}, {"Leads", Int64.Type}, {"Contacted", Int64.Type}, {"User", type text}}),
AddColumn = Table.AddColumn(Types, "Contacted (CVR)", (x) => x[Contacted]/List.Sum(Table.SelectRows(Types, (y)=> x[Country] = y[Country])[Leads]), Percentage.Type)
in
AddColumn

Related

Countifs alternative in PowerQuery for MS PowerBI

I have a bit complicated PowerQuery query which has many steps. Within these steps I have a date, team and conditions as below (not actual data)
So the challenge is that I want to count the Pass number for each team for each day and then create another count for Pass and Fail and then it will be used in so many calculations which I can handle later.
I have tried many options, like for example grouping, but it was so confusing because as I mentioned before, the query has so many columns and calculations now. I could successfully solve the issue by creating DAX measure, but the issue here that I need to calculate the average outcome which is not possible to because I couldn't also average the measure of the outcome. So I have no other option but to make the countif though PowerQuery.
Appreciate your help and ideas.
Raw data as text is here in google sheets
I am assuming that your dates showing the year 0203 is a typo and should be 2023
Not sure exactly what you want for output, but you should be able to adapt the below.
The solution seems to be a simple grouping with a count of the number of passes and/or fails.
The below code generates a separate column for passes and fails per team and date.
It is not sorted in the original order, but that could be added if necessary.
#"Grouped Rows" = Table.Group(#"Previous Step", {"Date", "Team"}, {
{"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
{"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
})
Using your data table from the Google sheet (after correcting the year):
let
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Team", type text}, {"PASS/FAIL", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Date", "Team"}, {
{"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
{"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
})
in
#"Grouped Rows"
Note If you require that all teams show on all dates even if they didn't play, one merely creates a new table containing all dates and teams; and then Joins that to the original table, as in the code below:
let
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Team", type text}, {"PASS/FAIL", type text}}),
//If you need to show all teams on all dates, even if they didn't play on a date
//we merely create a blank table (dates and teams), and execute an outer join.
//then remove the original date/team columns before the grouping.
#"Date List" = List.Distinct(#"Changed Type"[Date]),
#"All Teams" = List.Distinct(#"Changed Type"[Team]),
Blank = Table.FromColumns(
{List.Combine(List.Transform(#"Date List", each List.Repeat({_}, List.Count(#"All Teams")))),
List.Repeat(#"All Teams", List.Count(#"Date List"))},
type table[dates=date, teams=text]),
join = Table.Join(Blank,{"dates","teams"}, #"Changed Type",{"Date","Team"}, JoinKind.LeftOuter),
#"Removed Columns" = Table.RemoveColumns(join,{"Date", "Team"}),
#"Grouped Rows" = Table.Group(#"Removed Columns", {"dates", "teams"}, {
{"Pass", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Pass")), Int64.Type},
{"Fail", (t)=>List.Count(List.Select(t[#"PASS/FAIL"], each _ = "Fail")), Int64.Type}
}),
#"Sorted Rows" = Table.Sort(#"Grouped Rows",{{"dates", Order.Ascending}, {"teams", Order.Ascending}})
in
#"Sorted Rows"
If you need the zeroes in your final output, you'll need to do a cross join to bring in combinations not present in the original.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMtQ31DcyMDJW0lFyDAISAYnFxUqxOigSrn44JFxcgYRbYmYOuoSfD7KEkb4RilEkSeA0Cr8E3LlIEmDnEpYw1jfWNzAywDSKIgmcduCUQI0PJAnU+CDGKNSwotwOiFGxAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Team = _t, #"PASS/FAIL" = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type text}, {"Team", type text}, {"PASS/FAIL", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Date", "Team"}, {{"Count", each Table.RowCount(_), Int64.Type}}),
Custom1 = List.Distinct( #"Grouped Rows"[Date]),
#"Converted to Table" = Table.FromList(Custom1, Splitter.SplitByNothing(), {"Date"}, null, ExtraValues.Error),
#"Added Custom" = Table.AddColumn(#"Converted to Table", "Team", each List.Distinct( #"Grouped Rows"[Team])),
#"Expanded Team" = Table.ExpandListColumn(#"Added Custom", "Team"),
#"Merged Queries" = Table.NestedJoin(#"Expanded Team", {"Date", "Team"}, #"Grouped Rows", {"Date", "Team"}, "Expanded Team", JoinKind.LeftOuter),
#"Expanded Expanded Team" = Table.ExpandTableColumn(#"Merged Queries", "Expanded Team", {"Count"}, {"Count"}),
#"Replaced Value" = Table.ReplaceValue(#"Expanded Expanded Team",null,0,Replacer.ReplaceValue,{"Count"})
in
#"Replaced Value"
Stepping through the code:
Group by date and team and create a count:
Get a distinct list of dates
Convert to table
Add column for a cross join with all teams (to get zero values later)
Expand
Merge back to the grouped step to pull in the previous grouped values.
Replace nulls with 0
You can amend this for your other question by simply filtering for pass before you do the grouping.
Just add column, custom column
= 1
then click select Pass/Fail column, transform .. pivot .. and choose the new column as values column
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom", each 1),
#"Pivoted Column" = Table.Pivot(#"Added Custom", List.Distinct(#"Added Custom"[PassFail]), "PassFail", "Custom", List.Sum)
in #"Pivoted Column"

Working with parent child relationships in PowerBi

I am working with data that is structured in a parent-child relationship. Every level already has the rolled-up value (sum of the children). Therefore, I want Power Bi to display the value that is shown at every level (or sum on the same level) and not aggregate between parent and child. Also, the sums of the children don't always equal the parents, because some details are missing at the lower level. I do still need the parent-child relationship in PowerBi for drill through purposes. Attached is an example of how the data is structured. The table on the left is how I receive it. I have a dynamic number of levels, so ideally the solution wouldn't have a hard-coded number of levels. Any thoughts?
There's no way around having a fixed number of levels in PowerBI, but you can easily write a measure that takes the MAX rather than the SUM of the values.
You can apply these below steps to your table in Advanced Editor to get your desired output. Please replace the previous_step_name name (my frst step) accordingly to make this code functional.
let
//Your previous steps,
#"Added Index" = Table.AddIndexColumn(#"previous_step_name", "Index", 1, 1, Int64.Type),
tab_before_split = Table.ReorderColumns(#"Added Index",{"Index", "Item", "Value"}),
tab_split = Table.ExpandListColumn(Table.TransformColumns(#"tab_before_split", {{"Item", Splitter.SplitTextByDelimiter("/", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Item"),
tab_group_by = Table.Group(#"tab_split",{"Index"}, {{"Count", each Table.RowCount(_), Int64.Type}}),
tab_new = Table.Join(tab_before_split,"Index", tab_group_by,"Index"),
#"Split Column by Delimiter" = Table.SplitColumn(tab_new, "Item", Splitter.SplitTextByDelimiter("/", QuoteStyle.Csv), {"Item.1", "Item.2", "Item.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Item.1", type text}, {"Item.2", type text}, {"Item.3", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type1", "Level", each [Count] - 1),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Count"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Removed Columns",{{"Level", Int64.Type}})
in
#"Changed Type2"
Sample input-
Sample output-

best way to add multiple columns in power bi

Hi need to add 1000+ calculated columns in power bi which provide the count per entry, for example.*means calculated columns
ID
RankCode
Count_RankCode*
RankAdvance
Count_RanAdvance*
1000
AAA
2
XYZ
2
1001
AAA
2
XYA
1
1002
AAB
1
XYZ
2
found the right way to count in power BI DAX:
COUNTROWS(FILTER('24Jun_1973',[rankCode]=earlier([rankCode])))
Requirement:
add 1000 columns that count rows in probably in one code using DAX
or create the 1000 count cloumn in power query M language (need it to be fast since raw date is 60gb).
As suggested by #smpa01, I was able to complete this task using the tabular editor. Just used the DAX script in tabular editor, put my all my measures in there since I was able to create all expressio in excels as it is just repeating then voila, 1000 measures added.
example:
Measure '24Jun_1973'[measure]=calculate(COUNTROWS(FILTER('28Jun_1973',[rankcode]='28Jun_1973'[rankcode])))
Measure '24Jun_1973'[measure2]=calculate(COUNTROWS(FILTER('28Jun_1973',[rankAdvance]='28Jun_1973'[rankAdvance])))
I have no idea why you would want another 1000 columns.
If you really want to though, in powerquery, you could unpivot, group and count, append the results to original data, then re-pivot. I don't know how fast it would be. I suspect not very.
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"RankCode", type text}, {"RankAdvance", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID"}, "Attribute", "Value"),
// group and count
#"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"Attribute", "Value"}, {{"Count", each Table.RowCount(_), type number}}),
#"Duplicated Column" = Table.DuplicateColumn(#"Grouped Rows", "Attribute", "Attribute - Copy"),
#"Change column name" = Table.TransformColumns(#"Duplicated Column",{{"Attribute - Copy", each "count_" & _, type text}}),
// append back to original table, then repivot
#"Merged Queries" = Table.NestedJoin(#"Unpivoted Other Columns",{"Attribute", "Value"},#"Change column name",{"Attribute", "Value"},"Table2",JoinKind.LeftOuter),
#"Expanded Table1" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"Count", "Attribute - Copy"}, {"Count", "Attribute - Copy"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Table1",{"Attribute", "Value"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Count", "Value"}, {"Attribute - Copy", "Attribute"}}),
combined = #"Unpivoted Other Columns" & #"Renamed Columns",
#"Pivoted Column" = Table.Pivot(combined, List.Distinct(combined[Attribute]), "Attribute", "Value")
in #"Pivoted Column"

Calculated column with the sum of values from many columns in a row

I need to sum all values in each row and display them in a calculated column. As I deal with lots of columns in lots of tables, adding something like
CalculatedColumn = 'public table_name'[column1] + 'public table_name'[column2] + ... + 'public table_name'[column528]
is really inefficient. Is there a shorter way of doing this?
Yes, there is. You should "Unpivot other columns" and then "Group By" using the Query Editor.
Suppose this dataset:
item;col1;col2;col3;col4;col5
apple;1;2;3;4;5
orange;1;2;3;5;8
banana;1;2;4;6;8
Load it up, and open the query editor.
Choose "Unpivot Other Columns":
You should now see this:
On the "Transform" tab in the ribbon, choose the leftmost "Group By" option. And fill out the dialog like so:
You should now have the wanted end result:
You could also skip the Group By step and let your visualization handle that.
PS. Should you need a few non-summed columns too I recommend either creating a duplicate dataset with the same source and either linking it to the original table with a relationship, or merging it so you get a final table with all wanted columns.
Footnote, this is the Power Query that is generated for you:
let
Source = Csv.Document(File.Contents("D:\Experiments\PowerBi\denormalized.csv"),[Delimiter=";", Columns=6, Encoding=1252, QuoteStyle=QuoteStyle.None]),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"item", type text}, {"col1", Int64.Type}, {"col2", Int64.Type}, {"col3", Int64.Type}, {"col4", Int64.Type}, {"col5", Int64.Type}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"item"}, "Attribute", "Value"),
#"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"item"}, {{"SumCol", each List.Sum([Value]), type number}})
in
#"Grouped Rows"

Expand Table Rows for Each Delimited Value in One Column's Cells

I'm an Excel VBA programmer who's recently discovered Power Query and Power BI.
Often, I will receive requests to change something like:
Into a sort of un-pivoted version that looks like:
This can absolutely be done in VBA, but watching several Power Query videos (and now ordered three books!) It seems it would be much more efficient to do it in Power Query.
I get the over-all idea (create a table from the delimited list, for one) but don't know the language of the actual steps. And I really want to learn these new tools.
Can I buy a vowel? Phone a friend?
Import the table into Power Query using From Table
Click on the second column and choose "Split Column | By Delimiter" from the ribbon. Choose Comma as the delimiter and click OK.
Right click on the first column and choose "Unpivot Other Columns".
Click on the Attribute column and click on "Remove Columns" from the ribbon.
If you go to the Advanced Editor, you can see the code used to generate this:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type","Column2",Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv),{"Column2.1", "Column2.2", "Column2.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Column2.1", type text}, {"Column2.2", type text}, {"Column2.3", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Column1"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"})
in
#"Removed Columns"