Power BI DAX Avg of AVG - powerbi

I want the results to show, for example:
AVG GROUP 1 takes the avg of the brand then avg's the group. So,
avg BRAND J = 8.4
avg BRAND K = 4.8
avg BRAND L = 4.9
AVG GROUP 1 would then = 6.03 NOT 6.6
This would then continue for all groups.
Thanks
DataTable
GROUP BRAND PERCENT CHANGE
GROUP 1 BRAND J 4.8%
GROUP 1 BRAND J 12.0%
GROUP 1 BRAND K 4.8%
GROUP 1 BRAND L 4.9%
GROUP 2 BRAND M 8.0%
GROUP 3 BRAND A 4.0%
GROUP 4 BRAND B 8.0%
GROUP 4 BRAND B 15.0%
GROUP 4 BRAND C 8.0%
GROUP 4 BRAND N 7.0%
GROUP 5 BRAND D 5.0%
GROUP 5 BRAND E 4.0%
GROUP 5 BRAND E 6.0%
GROUP 5 BRAND E 6.0%

Create a measure:
Group Average =
AVERAGEX (
SUMMARIZE (
Data,
Data[Group],
Data[Brand],
"Brand Average", AVERAGE ( Data[Percent Change] )
),
[Brand Average]
)
where "Data" is your table name.
Result:
More detailed result:
How it works:
First, we summarize your data by Group and Brand, and calculate average per each. Then, we use AVERAGEX to iterate the summarized table, and calculate the average of the averages.
Edit:
To filter out groups with 1 brand, modify the measure:
Group Average =
AVERAGEX(
SUMMARIZE (
Data,
Data[Group],
Data[Brand],
"Brand Average", AVERAGE ( Data[Percent Change] ),
"Brand Count", CALCULATE(COUNT(Data[BRAND]), ALLEXCEPT(Data, Data[GROUP])),
IF([Brand Count] > 1, [Brand Average])
)
You will get:

Related

Calculating the cumulative values in Power BI

I have two tables:
user table (contains: user registration data. columns: user_id, create_date)
customer order table (contains: history of orders. columns: user_id, order_date, order_id)
*user and customer aren't the same. when a user registers his first order, he becomes a customer.
For each month of each year, I want the accumulative count of distinct users and the accumulative count of the distinct customers because at last, I want to calculate the ratio of the accumulative count of the distinct customers to the accumulative count of the distinct users for each month.
I don't know how can I calculate the accumulative values and the Ratio that I said, using DAX.
Note that if a customer registers more than one order in a month, I want to count him just once for that month and if he registers a new order in the next months, also I count him in each new month.
Maybe these pictures help you to understand my question better.
-I don't count_of_users and count_of_customers columns in my tables. I should calculate them.
the user table:
user_id
create_date
1
2017-12-03
2
2018-01-01
3
2018-01-01
4
2018-02-04
5
2018-03-10
6
2018-04-07
7
2018-04-08
8
2018-09-12
9
2018-10-02
10
2018-10-02
11
2018-10-09
12
2018-10-11
13
2018-10-12
14
2018-10-12
15
2018-10-20
the customer order table:
user_id
order_date
order_id
1
2018-03-28
120
1
2018-03-28
514
1
2018-03-30
426
2
2018-02-11
125
2
2018-03-01
547
3
2018-02-10
588
3
2018-04-03
111
4
2018-02-10
697
5
2018-04-02
403
5
2018-04-05
321
6
2018-04-09
909
11
2018-10-25
8401
You need a few building blocks for this. Here is the data model I used:
<edit>
I see user_id in the different tables are not the same, in that case you can omit the relationship between the tables and the two relationships from the Calendar table will both be active - with no need to change the relationship semantics in the count_of_customer measure. </edit>
The calendar table is important because we can't rely on one single date column to aggregate data from different tables, so we create a common calendar table with this sample DAX code:
Calendar =
ADDCOLUMNS (
CALENDARAUTO () ,
"Year" , YEAR ( [Date] ) ,
"Month" , FORMAT ( [Date] , "MMM" ) ,
"Month-Year" , FORMAT ( [Date] , "MMM")&"-"&YEAR ( [Date] ) ,
"YearMonthNo" , YEAR ( [Date] ) * 12 + MONTH ( [Date] ) - 1
)
Make sure to sort the Month-Year column by the YearMonthNo column so your tables look nice:
Set your relationships as shown with the active relationship from Calendar to user - if not the measures will not work unless you alter the relationships accordingly in the code! In my data model the inactive relationship is between Calendar and customer order.
Next up are the measures we will use for this. First off we count the users, a simple row count:
count_of_users = COUNTROWS ( user )
Then we count distinct user ids in the order table to count customers, here we need to use the inactive relationship between Calendar and customer order and to do this we have to invoke CALCULATE:
count_of_customers =
CALCULATE (
DISTINCTCOUNT ( 'customer order'[user_id] ) ,
USERELATIONSHIP (
'Calendar'[Date] ,
'customer order'[order_date]
)
)
We can use this measure to count users cumulatively:
cumulative_users =
VAR _maxVisibleDate = MAX ( 'Calendar'[Date] )
RETURN
CALCULATE (
[count_of_users] ,
ALL ( 'Calendar' ) ,
'Calendar'[Date] <= _maxVisibleDate
)
And this measure to count cumulative customers per month:
cumulative_customers =
VAR _maxVisibleDate = MAX ( 'Calendar'[Date] )
RETURN
CALCULATE (
SUMX (
VALUES ( 'Calendar'[YearMonthNo] ) ,
[count_of_customers]
),
ALL ( 'Calendar' ) ,
'Calendar'[Date] <= _maxVisibleDate
)
Lastly we want the ratio of these last cumulative measures:
cumulative_customers/users =
DIVIDE (
[cumulative_customers] ,
[cumulative_users]
)
And here is your result:

What is the purpose of using VALUES or ALL in the first parameter of an iterator function?

I know that only CALCULATE can modify the filter context. However following are 2 example using VALUES and ALL.
Example 1:
Revenue =
SUMX(
Sales,
Sales[Order Quantity] * Sales[Unit Price]
)
Revenue Avg Order =
AVERAGEX(
VALUES('Sales Order'[Sales Order]),
[Revenue]
)
What is the purpose of VALUES in AVERAGEX function? Is this to add an additional filter context?
Example 2:
Product Quantity Rank =
RANKX(
ALL('Product'[Product]),
[Quantity]
)
What is the purpose of using ALL in an iterator function?
Suppose we have a table like this:
ID
Sales Order
Order Quantity
UnitID
Unit Price
1
101
10
4
39.99
2
101
15
3
24.99
3
102
5
2
15.99
4
103
5
1
14.99
5
103
10
3
24.99
Since the Sales Order column has duplicates,
Revenue Avg Order = AVERAGEX ( VALUES ( Sales[Sales Order] ), [Revenue] )
gives a different result than
Revenue Avg ID = AVERAGEX ( Sales, [Revenue] )
since the first averages over the three Sales Order values whereas the second averages over the five ID rows.
Using DISTINCT instead of VALUES would work too.
Using ALL is instead of VALUES gives the same total but ignores the local filter context from the table visual:
Revenue Avg All = AVERAGEX ( ALL ( Sales[Sales Order] ), [Revenue] )
In this context, ALL is acting as a table function that returns all of the distinct values of the column specified ignoring filter context.

PowerBi/Dax Summarize table and get average rating

I'm trying to create a new measure to find the average of the rating from my table, either the whole table or a particular 'id' as selected by a slicer. The issue is, in the original data if a user appears in more than one user group then they have a table row included for each of their groups (eg. harry appears 3 times). I want to show the average of the rating in a visual but can't work out how to calculate it without the duplicated values.
For the below table, I would like to show the average rating for id 1 in the visual as 4.5 ((5+4)/2) instead of 4.75 ((5+5+5+4)/4).
Table
id
user group
user id
rating
1
group 1
harry
5
1
group 2
harry
5
1
group 3
harry
5
2
group 1
betty
2
2
group 2
phil
3
1
group 1
ted
4
Since the specification is to remove duplicate values, but also to consider existing slicers, a possible solution is
Avg Rating =
CALCULATE(
AVERAGEX( SUMMARIZE( T, T[id], T[rating] ), T[rating] ),
ALLSELECTED( T[user id], T[user group], T[rating] ),
VALUES( T[id] )
)

PowerBI Rankx Returning only 1

I have a table called Commissions summary that are for sales reps
This table generates a summary row for each sales rep for each month. I want to rank the sales rep only by each month, however my formula is only returning 1's.
The table can be simplified down to this
Sales reps Target Attainment
John, deer 53%
Jane, Joe 160%
Adam, Smith 30%
My goal is to show my table like this
Sales reps Target Attainment Rank
John, deer 53% 2
Jane, Joe 160% 1
Adam, Smith 30% 3
This is the Rankx formula I am using
Ranks =
RANKX (
ALL ( 'Commission Summary' ),
CALCULATE (
SUM ( 'Commission Summary'[Target Attainment] ),
'Commission Summary'[Date] = 10 / 01 / 2019
),
,
DESC
)
As I mentioned earlier, I am only filtering my date to October.
Please help :(
the problem occurs into calculate's filter 'Commission Summary'[Date] = 10 / 01 / 2019. The engine is dividing each number first 10/01 = 10 and 10/2019 = 0.00495 that date doesn't exist in your data returning blank for all values giving as a result a ranking with 1 in all ocurrences (because all are the same blank value).
To avoid this problem use 'Commission Summary'[Date] = DATE(2019,10,1) as filter context. That will return a ranking properly sorted, but you'll have ranked all sales reps including sales reps who had no activity that date (they will be in the bottom of the ranking)
If you want to go a step further i recommend using the following steps:
create a measure first:
Comission Summary Filtered = CALCULATE (
SUM ( 'Commission Summary'[Target Attainment] ),
'Commission Summary'[Date] = DATE(2019,10,1)
Then filter by that measure with the following code:
Rank =
IF (
[Comision Summary Filtered] > 0,
RANKX ( ALL ( 'Commission Summary' ), [Comision Summary Filtered],, DESC, DENSE )
)
With that you'll have a cleaner result. :)

Count NA's at a customer level using measures in Power BI

I have a table with the customer name and its product code. I want to count the number of products having its name as "NA" on a customer level using only measures as I don't have access to create new columns.
Customer Name Product Code
---------------------------
Customer 1 NA
Customer 1 NA
Customer 1 999
Customer 2 888
Customer 2 777
Customer 3 NA
Customer 3 666
Customer 3 NA
Customer 4 5
Output should be something like this:
Customer Name Product Code
---------------------------
Customer 1 2
Customer 2 0
Customer 3 2
Customer 4 0
In this case, it sounds like you want to leverage the calculate function which is used modify calculation context.
The example below, the count of your Product Code, is being modified so that it only is done on rows in which the product code is NA.
NA count:= CALCULATE ( COUNT ( table[ Product Code ] ) , table[ Product Code ] = "NA" )
Calculate is a powerful function, since you can use it to both restrict or expand how the calculation works based on what filter conditions you provide.
You can do it in various ways, here are a couple:
The first like Marcus suggested:
NA Count :=
CALCULATE (
COUNT ( 'Table'[Product Code] ),
KEEPFILTERS ( FILTER ( 'Table', 'Table'[Product Code] = "NA" ) )
)
Or, Using SUMMARIZECOLUMNS, which will create a table:
NA COUNT :=
SUMMARIZECOLUMNS (
'Table'[Customer Name],
"NA Count", CALCULATE (
COUNT ( 'Table'[Product Code] ),
KEEPFILTERS ( FILTER ( 'Table', 'Table'[Product Code] = "NA" ) )
)
)
But since you cant create calculated columns, I am assuming you wont be able to create a new table either :) Good luck and have fun!