I have a simple CSV data set such as this.
ID,MainCategory,SubCategory,Type,Value
1,E,E1,Demo,5
2,N,N3,Install,2
3,E,E1,Demo,4
4,E,E2,Install,7
5,D,D1,Install,3
6,S,S2,PM,4
7,N,N2,Install,7
8,N,N2,Demo,1
9,E,E2,Demo,2
10,D,D2,Install,6
11,D,D3,PM,4
12,S,S1,PM,8
13,N,N1,Install,5
14,S,S3,Install,8
15,S,S1,Demo,9
16,E,E3,Demo,5
17,N,N2,Install,3
18,E,E2,PM,6
19,D,D2,PM,6
20,N,N3,Demo,6
21,S,S2,Demo,7
22,E,E3,Install,2
23,S,S1,Install,4
24,S,S2,PM,8
25,D,D1,Install,5
In my Power BI Desktop, I'd like to load this into a table, and conditionally format the Value column based on whether the value in each row is greater than or less than the average for the currently selected data set.
For instance, the average of Value considering the entire table is 5.08, so if there are no filters applied (as in, all my slicers are set to select nothing), I'd like all rows whose Value is 6 or more to be background colored in one color, and the others in another color. For this, I created two measures like so:
AvgOfVal = DIVIDE( SUM(G2G[Value]), COUNTA(G2G[ID]) )
BGColor = IF(SUM(G2G[Value]) > [AvgOfVal], "Light Pink", "Light Blue")
Then I tried to apply the BGColor measure for conditionally formatting the background, but this doesn't work as expected, and instead produces the result below.
I realize that this is due to the fact that the measure is calculated per row, so when conditional formatting is applied, as seen in the AvgOfVal column in the table, it calculates average per row instead of for the entire data set. How can I calculate a measure that takes into account the entire data set (considering slicers), and do the conditional formatting as I need.
Please keep in mind that if a user were to select a slicer filter (say, MainCategory = D), then I want the conditional formatting to reflect this. So in this case, given that AvgOfVal = 4.80 for MainCategory = D entries, I'd like all rows whose Value >= 5 to be in one color, and others in another color.
I realize that this is due to the fact that the measure is calculated per row
Yes. The key is understanding how that happens. When the measure is calculated a "context transition" happens and the current row is added to the filter context.
So what you want is a calculation that removes the row filter that was added in the context transition. So you need ALLSELECTED(), which does precisely that. eg
AvgOvVAl = CALCULATE( AVERAGE('data'[Value]), ALLSELECTED() )
Removing the "innermost" filter which in this case is the filter on the row, but leaving all other filters, ie filters added on the report, page, visual, or filters coming from interactions with other visuals like slicers.
I have a table with two choices 'FLOW_CONTEXT' and 'TEST_NAME'.
I want to let the user select one of these values using a slicer. I then want to have a calculated formula point to either the 'FLOW_CONTEXT' or the 'TEST_NAME' column in another table. There is a 1:1 relationship between the 'FLOW_CONTEXT' and the 'TEST_NAME' columns in the table.
Here is the column formula I have, which always defaults to false, even though the SELECTEDVALUE part of the IF statement does work (checked via a card):
COLUMN_POINTER = IF(
SELECTEDVALUE(TEST_NAME_FIELD[TEST_NAME_FIELD]) = "FLOW_CONTEXT",
CCD_BINNING_TEST_RESULTS_LAST_RANK[FLOW_CONTEXT],
CCD_BINNING_TEST_RESULTS_LAST_RANK[TEST_NAME]
)
I have tried doing this with a measure but measures only see non-categorical columns. Thx much.
Columns are only calculated at refresh time - they do not respond to slicers filters in this way. You cannot re-calculate a column based on a selected value in a table visual.
You need to transform your use-case into a measure-friendly approach.
I am new to power BI and stuck with an issue. I have my model as follows:
Date Dimension
Measurement Fact
The date column in Date Dimension is link to measuredate in Measurement Fact
Below is a sample data:
NB: In edit query, I have changed the type of measuredate to Date only.
I have tried the measure below but it doesn't work the way I want. It will sum all the values of the day but what I want is the last value of the day:
day_fuel_consumption =
CALCULATE (
SUM ( measurement[measurementvalue] ),
FILTER (
measurement,
measurement[metername] = "C-FUEL"
&& measurement[measuredate] = MAX ( measurement[measuredate] )
)
)
My Goal is to get 29242, i.e the last value of the day. Remember that measuredate is a Date field and not Datetime (I changed to Date field so that my Year and Month filter can work correctly). I have changed the type in edit query.
Changing your measure to use a variable could be the solution:
DFC =
var maxDate = MAX(measurement[measuredate])
return
CALCULATE(
SUM(measurement[measurementvalue]),
measurement[measuredate] = maxDate
)
However, you should keep the datetime format for measureDate. If you don't want to see the time stamp just change the format I power bi. Otherwise power bi will see two values with max date and sum them, instead of taking the last one.
Well, if you want to avoid creating a measure, you could drag the fields you are filtering over to the visual filters pane. Click your visual, and scroll a tiny bit and you will see the section I am referring to. From there, just drag the field you are trying to filter In this case, your value. Then select "Top N". It will allow you to select a top (number) or bottom (number) based on another field. Strange enough, it does allow you to do top value by top value. It doesn't make sense when you say it out loud, but it works all the same.
This will show you the top values for whatever value field you are trying to use. As an added bonus, you can show how little or how many you want, on the fly.
As far as DAX goes, I'm afraid I am a little DAX illiterate compared to some other folks that may be able to help you.
I had to create two separate measures as shown below for this to work as I wanted:
max_measurement_id_cf = CALCULATE(MAX(measurement[measurementid]), FILTER(measurement, measurement[metername] = "C-FUEL"))
DFC =
var max_id_cf = [max_measurement_id_cf]
return
CALCULATE(SUM(measurement[measurementvalue]), measurement[measurementid] = max_id_cf)
I'm trying to obtain the MAX of a particular column in a Power BI Report and place this as a new Measure within each ROW of the same dataset. Please see the example below.
Is this possible in DAX and via DirectQuery/LiveConnection? The report is pointing to a tabular model but due to outside factors the measure must be created in the report.
Thanks
You can accomplish this a few ways. Essentially, you need override the filter context so that the MAX function isn't just running over whatever slice you're showing in the visual. Using CALCULATE or the iterator function MAXX, set the wrap the table in the ALL() function to override the context and calculate max over all rows.
= CALCULATE(MAX([Calendar`Year]), ALL('Smithfield_Fiscal_Calendar'))
or
= MAXX(ALL('Smithfield_Fiscal_Calendar'), [Calendar`Year])
To get the breakout by date, you'll need to include a Date table in your model. PowerBI makes this possible with a few different DAX options. As an example, go to your Model tab, click 'New Table' and put in the following expression:
MyCalendar = CALENDAR(DATE(2019,1,1), DATE (2019,1,10))
This is a little trivial -- you'd want to use a useful range of dates but this one matches your example above. Next, add a column to [MyCalendar]
CalendarMonthYear = month([date]) & "-" & year([date])
Go to your budget table and add a similar field
BudgetMonthYear = month([date]) & "-" & year([date])
Go into your Model view and create a relationship between CalendarMonthYear and BudgetMonthYear. This will associate every date in the date table with the particular budget row from your budget table.
Hope it helps.
I am using Power BI to bring together data from several systems and display a dash board with data from all of the systems.
The dashboard has a couple of filters which are then used to display the data relating to one object across all systems.
When the dashboard is first loaded and none of the filter have been selected, the data cards display information from all rows in the table.
Is there a way to make a data card only display one row of data?
or
Be blank if there are more than one row of data?
There's no direct way to look at the number of rows in the visual, count them, and do something different if there's more than 1.
That said, there are a few things you can do.
HASONEFILTER
If you have a specific column in your table that, when selected, filters your results to a single row, then you can check if there's a filter on that column using HASONEFILTER. (If you have multiple alternative columns,any of which filter to a single row, that's ok too.)
You could then create a measure for each column that tests HASONEFILTER. If true, return the MAX of the column. (The reason for MAX is because measures always have to aggregate, but the MAX of a 1-row column will be the same as the value in that column.) If false, return either BLANK() or an empty string, depending on your preference.
E.g.
ColumnAMeasure = IF(HASONEFILTER(Sheet1[Slicer Column]),MAX(Sheet1[COLUMN A]), "")
ColumnBMeasure = IF(HASONEFILTER(Sheet1[Slicer Column]),MAX(Sheet1[COLUMN B]), "")
where Sheet1 is the name of the table and "Slicer Column" is the name of the column being used as a slicer
HASONEVALUE
If you have multiple columns that could be used as filters in combination (meaning that having a filter applied on "Slicer Column" doesn't guarantee only 1 row in the table), then rather than testing HASONEFILTER, you can test HASONEVALUE.
ColumnAMeasure = IF(HASONEVALUE(Sheet1[COLUMN A]),MAX(Sheet1[COLUMN A]), "")
ColumnBMeasure = IF(HASONEVALUE(Sheet1[Column B]),MAX(Sheet1[COLUMN B]), "")
Notice that HASONEVALUE tests the current column you're trying to display, rather than a slicer column like HASONEFILTER.
One side-effect of HASONEVALUE is that, if you're filtered to 3 rows, but all 3 rows have the same value for column A, then column A will display that value. (Whereas with HASONEFILTER, column A would stay blank until you're filtered to one thing.)
Low Tech
Both answers above depend on a measure existing for every column you want to display, so that you can test whether to display a blank row or not. That could become a pain if you have dozens of columns.
A lower-tech alternative is to add in an additional row with blanks for each column and then sort your table so that that row always appears first. (And shorten your visual so only the top row is visible.) Technically the other rows would be underneath and there'd be a scrollbar, but at least the initial display would be blank rather than showing a random row.
Hopefully something here has helped. Other people might have better solutions too. More information:
HASONEFILTER documentation: https://msdn.microsoft.com/en-us/library/gg492135.aspx
HASONEVALUE documentation: https://msdn.microsoft.com/en-us/library/gg492190.aspx