I am tryning to calculate Mean Absolute Error (MAE) in powerbi (using "new measure" option).
MAE_1 =
DIVIDE (
ABS ( AVERAGE ( 'STATION'[GHI W/sqm] ) - AVERAGE ( 'Forecast_1d'[GHI W/sqm] ) ),
CALCULATE ( COUNTROWS ( 'Forecast_1d' ), 'Forecast_1d'[GHI W/sqm] )
)
My data has the following struture (the station data has negative value, while my forecast has 0 values):
Date
Hour
STATION[GHI W/sqm]
Forecast_1d[GHI W/sqm]
01/01/2023
0:00
-5.26
0
01/01/2023
1:00
-5.24
0
01/01/2023
2:00
-5.27
0
...
01/01/2023
13:00
800
789
01/01/2023
14:00
799
789
...
01/01/2023
22:00
-5.26
0
However, when I check my results I obtain:
Date
Hour
STATION[GHI W/sqm]
Forecast_1d[GHI W/sqm]
MAE_1
01/01/2023
0:00
-5.26
0
01/01/2023
1:00
-5.24
0
01/01/2023
2:00
-5.27
0
...
01/01/2023
13:00
800
789
11
01/01/2023
14:00
799
789
10
...
01/01/2023
22:00
-5.26
0
So I am seeing the MAE it has been calculated on positive values in the STATION[GHI W/sqm] column, but I do not know why I am not calculating the negative values.
P.D: I have to calculate the average inside the MAE, because the steps of both data are deferents (The station has a step of 5 min while the forecast has a step of 30min). I used a Fact table to relate both tables.
You have a very strange construct in your DIVIDE divisor.
When you specify a formula like this:
Foo =
CALCULATE (
[Measure] ,
'Table'[Column]
)
And your 'Table'[Column] contains zeroes, you will remove these rows from your calculation altogether, as they will be interpreted by the engine as FALSE.
So for all your rows where Forecast_1d[GHI W/sqm] = 0, DIVIDE will get a blank divisor and will return a blank value. For the rows in your example data where STATION[GHI W/sqm] is negative, you also have Forecast_1d[GHI W/sqm] = 0 which causes your calculation to blank out for these rows.
Related
I'm quite new to Power Bi and DAX in general and I have some problems calculating how much of each month was of the whole year.
Example:
Year 2021:
Month Value Percentage
Jan. 100 10
Feb. 50 5
Mar. 250 25
Apr. 30 3
Etc...
Total 1000 100
I have calculated the percentage column in dax as:
=
[Value] /
CALCULATE(
[Value],
ALLEXCEPT(Calendar, Calendar[Year])
)
This gives me the correct result for the chosen year, the problem I have is when trying to compare it to last year's result.
I've tried to add
"SAMEPERIODLASTYEAR(Calendar[Key_Calendar])" and "PARALLELLPERIOD(CALENDAR[Key_Calendar],-12,Month)"
but neither of them gives me the result I am looking for.
I'd appreciate any help that I can get on the issue.
First you need to create such a model:
If you want to create a simple calendar table, create new table and paste this code:
Calendar =
VAR BaseTable = CALENDAR(DATE(2020,01,01), DATE(2021,12,31))
RETURN
ADDCOLUMNS(
BaseTable,
"Year", YEAR([Date]),
"Month", MONTH([Date]),
"MonthName", FORMAT([Date],"mmm"),
"Quarter", QUARTER([Date]),
"Period", FORMAT([Date],"yyyy-mm")
)
Your resulting Date table:
Then create a fact table with some data:
Date Value
01/01/2021 100
01/02/2021 50
01/03/2021 250
01/04/2021 30
01/05/2021 25
01/06/2021 50
01/07/2021 65
01/08/2021 75
01/09/2021 70
01/10/2021 35
01/11/2021 40
01/12/2021 20
01/01/2020 10
01/02/2020 25
01/03/2020 65
01/04/2020 85
01/05/2020 35
01/06/2020 25
01/07/2020 35
01/08/2020 10
01/09/2020 30
01/10/2020 50
01/11/2020 30
01/12/2020 20
Then we can create 2 new measures!
Percentage =
DIVIDE(SUM(FactTable[Value]),CALCULATE(SUM(FactTable[Value]),ALL(FactTable)))
Percentage_LastYear =
CALCULATE(
[Percentage],
SAMEPERIODLASTYEAR('Calendar'[Date])
)
Then create a table visual and put it like you see in the below screenshot:
And you are Good to go! I hope It solves your problem!
Assuming that your Calendar dimension has a date column called Date, the following would get the value for the prior year:
Value PY =
CALCULATE ( [Value], SAMEPERIODLASTYEAR ( 'Calendar'[Date] ) )
First, as I am a French guy, I want to apologise in advance for my poor English!
Despite my searches since few days, I cannot find the correct measure to solve my problem.
I think I am close to the solution, but I really need help to achieve this job!
Here is my need:
I have a dataset with a date table and a "Position" (i.e. "stock") table, which is my fact table, with date column.
Classic relationship between these 2 tables. Many Dates in "Position" table / 1 date un "Dates" table.
My "Dates" table has a one date per day (Column "AsOf")
My "Deals" table looks like this:
Id
DealId
AsOfDate
Notional
10000
1
9/1/2022
2000000
10001
1
9/1/2022
3000000
10002
1
9/1/2022
1818147
10010
4
5/31/2022
2000000
10011
4
5/31/2022
997500
10012
4
5/31/2022
1500000
10013
4
5/31/2022
1127820
10014
5
7/27/2022
140000
10015
5
7/27/2022
210000
10016
5
7/27/2022
500000
10017
5
7/27/2022
750000
10018
5
7/27/2022
625000
10019
1
8/31/2022
2000000
10020
1
8/31/2022
3000000
10021
1
8/31/2022
1801257
10022
1
8/31/2022
96976
10023
1
8/31/2022
1193365
10024
1
8/31/2022
67883
Based on a selected date (slicer with all dates from "Dates" table), I would like to calculate the sum of Last Notional for each "Deal" (column "DealId").
So, I must identify, for each Deal, the last "Asof Date" before or equal to the selected date and sum all matching rows.
Examples:
If selected date is 9/1/2022, I will see all rows, except rows asof date = 8/31/2022 for deal 1 (as the last date for this deal is 9/1/2022).
So, I expect to see:
DealId Sum of Notional
1 6 818 147
4 5 625 320
5 2 225 000
Grand Total 14 668 467
If I select 8/31/2022, total for Deal 1 changes (as we now take rows of 8/31 instead of 1/9):
DealId Sum of Notional
1 8 159 481
4 5 625 320
5 2 225 000
Grand Total 16 009 800
If I select 7/29, only deals 4 and 5 are active on this date, so the results should be:
DealId Sum of Notional
4 5 625 320
5 2 225 000
Grand Total 7 850 320
I think I found a solution for the rows, but my total is wrong (only notionals of the selected date are totalized).
I also think my measure is incorrect if I try to display the notional amounts aggregated by Rating (other column in my table) instead of deal.
Here is my measure:
Last Notional =
VAR SelectedAsOf =
SELECTEDVALUE ( Dates[AsOf] )
VAR LastAsofPerDeal =
CALCULATE (
MAX ( Deals[AsOf Date] ),
FILTER ( ALLEXCEPT ( Deals, Deals[DealId] ), Deals[AsOf Date] <= SelectedAsOf )
)
RETURN
CALCULATE (
SUM ( Deals[Notional] ),
FILTER (
ALLEXCEPT ( Deals, Deals[DealId]),
LastAsofPerDeal = Deals[AsOf Date]
)
)
I hope it is clear for you, and you will be able to find a solution for this.
Thanks in advance.
Antoine
Make sure you have no relationship between your calendar table and deals table like so.
Create a slicer with your dates table and create a table visual with deal id. Then add a measure to the table as follows:
Sum of Notional =
VAR slicer = SELECTEDVALUE(Dates[Date])
VAR tbl = FILTER(Deals,Deals[AsOfDate] <= slicer)
VAR maxBalanceDate = CALCULATE(MAX(Deals[AsOfDate]),tbl)
RETURN
CALCULATE(
SUM(Deals[Notional]),
Deals[AsOfDate] = maxBalanceDate
)
I have a dataset containing the duration (in minutes) of occupancy events over a period of 1 hour in my rooms:
# room date duration
--- ---- ------------------- --------
0 A1 2022-01-01 08:00:00 30
1 A1 2022-01-01 10:00:00 5
2 A1 2022-01-01 16:00:00 30
3 A1 2022-01-02 10:00:00 60
4 A1 2022-01-02 16:00:00 60
...
My date column is linked to a date table in which I have:
# datetime year month monthName day dayOfWeek dayName hour
--- ------------------- ---- ----- --------- --- --------- -------- ----
...
k 2022-01-01 08:00:00 2022 1 January 1 5 Saturday 8
k+1 2022-01-01 09:00:00 2022 1 January 1 5 Saturday 9
...
n 2022-03-01 22:00:00 2022 3 March 1 1 Tuesday 22
I am trying to retrieve the following percentage: duration/timeperiod through a measure. The idea behind using a measure is :
Being able to use a time slicer and see my percentage being updated
Using, for example, a bar chart with my date hierarchy, and being able to see a percentage in my different level of hierarchy (datetime -> year -> month -> dayOfWeek -> hour)
Attempt
My idea was to create a first measure that would return the number of minutes between the first and the last date currently chosen. Here is what I came up with:
Diff minutes = DATEDIFF(
FIRSTDATE( 'date'[date] ),
LASTDATE( 'date'[date] ),
MINUTE
)
The idea was then to create a second measure that would divide the SUM of the durations by the Diff minutes' measure:
My rate = DIVIDE(
SUM( 'table'[duration] ),
[Diff minutes]
)
I currently face a few issues:
The slicer is set to (2022-01-02 --> 2022-01-03) and if I check in a matrix, I have datetime between 2022-01-02 0:00:00 and 2022-01-03 23:00:00, but my measure returns 1440 which is the number of minutes in a day but not in my selected time period
The percentage is also wrong unfortunately. Let's take the example that I highlighted in the capture. There are 2 values for the 10h slot, 5min and 60min. But the percentage shows 4.51% instead of 54.2%. It actually is the result of 65/1440, 1440 being the total of minutes for my whole time period, not my 10h slot.
Examples
1- Let's say I have a slicer over a period of 2 days (2022-01-01 --> 2022-01-02) and my dataset is the one provided before:
I would have a total duration of 185 minutes (30+5+30+60+60)
My time period would be 2 days = 48h = 2880 minutes
The displayed ratio would be: 6.4% (185/2880)
2- With the same slicer, a matrix with hours and percentage would give me:
hour rate
---- -----
0 0.0%
1 0.0%
...
8 25.0% <--- 30 minutes on the 1st of January and 0 minutes on the 2nd
9 0.0% <--- (5+0)/120
10 54.2% <--- (5+60)/120
...
16 75.0% <--- (30+60)/120
Constraints
The example I provided only has 1 room. In practice, there are n rooms and I would like my measure to return the percentage as the mean of all my rooms.
Would it be possible ? Have I chosen the right method ?
The DateDiff function you have created should work, I have tested it on a report and when I select some dates, it gives me the difference between the first and last selected dates.
Make sure your slicer is interacting with the measure.
In the meantime, I think I found a simpler and easier way to do it.
First, I added a new column to my date table, that seems dubious but is actually helpful:
minutes = 60
This allows me to get rid of the DATEDIFF function. My rate measure now looks like this:
My rate = DIVIDE(
SUM( table[duration] ),
[Number of minutes],
0
)
Here, I use the measure Number of minutes which is simply a SUM of the values in the minutes column. In order to provide accurate results when I have multiple rooms selected, I multiplied the number of minutes by the number of rooms:
Number of minutes = COUNTROWS( rooms ) * SUM( 'date'[minutes] )
This now works perfectly with my date hierarchy!
I have a table given below. I want to create an indicator which will be based on the column total using DAX. E.g Company A with YoY 13% would have an indicator value 1 as it is more than equal to YoY column total of 8%. I want the similar indicator for all the companies. It should automatically change based on filter/slicer values in Power BI
Company Pax 2019 YoY(%)
A 87 13%
B 45 9%
C 57 9%
D 82 2%
E 53 4%
F 57 8%
G 84 12%
Grand Total 465 8%
I tried it using all table but it changes as the filter changes the value.
Company Pax 2019 YoY(%) Indicator(if grand total YoY> individual YoY, 1, 0)
A 87 13% 1
B 45 9% 1
C 57 9% 1
D 82 2% 0
E 53 4% 0
F 57 8% 0
G 84 12% 1
Grand Total 465 8%
Below DAX Expression should work for you:
Column =
VAR Tot_Average =
AVERAGE ( 'Example'[Pax] )
VAR Check =
CALCULATE (
Tot_Average,
ALL ( 'Example'[Pax] )
)
RETURN
IF ( 'Example'[Pax] > Check, 1, 0 )
I am trying to create a "Percent Retention" for policies during a given time period ( By month, YTD and year over year) . So all of the policies at a given time period compared to those active at the end of the period.
Policies can be:
N=New
RN=ReNew
C=Cancel
RI=ReInstate
NR=NonRenew
Transaction data kinda looks like this, the StatusNum is something I can derive to show inforce status.
PolicyID PolicyNum StatusDate Status StatusNum Net
1 123 1/1/2018 N 1 1
2 123 3/31/2018 C 0 -1
3 123 4/1/2018 RI 1 +1
4 123 6/1/2018 RN 1 0
5 222 2/1/2018 N 1 1
6 222 7/1/2018 RN 1 0
7 333 1/1/2018 N 1 1
8 333 6/1/2018 NR 0 -1
9 444 1/1/2018 N 1 1
10 444 5/30/2018 C 0 -1
My best guess on how to do this is to take the sum of the last StatusNum values at a PIT (partitioned by Policy Number) divided by the first StatusNum value at the beginning PIT. So if I filter by dates 1/1/2018 to 8/1/2018
123 will be in force (+1,+1)
222 will not be in force yet(so not counted for anything) (+0,+0)
333 was in force at the beginning, but it non renewed (+1,-1)
444 was in force at the beginning, but it cancelled (+1,-1)
So 3 of the policies were active at 1/1/2018 and 2 cancelled, 1 doesn't matter so the retention would be 33.3%
Can anyone offer feedback if this is the best way to do this and how to accomplish this?
Thank you in advance for your assistance.
Update
This is kinda what I am looking for, but it is too slow:
'AsOfPolicies =
var A= SELECTCOLUMNS(SUMMARIZECOLUMNS(Transactions[PolicyNumber], filter( Transactions,Transactions[DateKey]=min(Transactions[DateKey])&&Transactions[IsInForce]=-1) ),"aPolicyNumber", [PolicyNumber])
var B=SELECTCOLUMNS(SUMMARIZECOLUMNS(Transactions[PolicyNumber], filter( Transactions,Transactions[DateKey]<=MAX(Transactions[DateKey]) ),"MaxDate",MAX(Transactions[DateKey]) ),"bPolicyNumber",[PolicyNumber],"MaxDate",[MaxDate]) var C = SELECTCOLUMNS(filter(CROSSJOIN(A,B),[aPolicyNumber]=[bPolicyNumber]),"cPolicyNumber",[aPolicyNumber],"MaxDateKey",[MaxDate])
Var D = SELECTCOLUMNS(filter(CROSSJOIN(C,Transactions),[cPolicyNumber]=[PolicyNumber] && [MaxDateKey]=[DateKey]),"PolicyNumber",[PolicyNumber],"PD_ID",[PD_ID],"IsInForce",[IsInForce])
Return D'
Update
Also the filter does not appear to be working
I think you can do something like this:
Retention =
VAR StartDates =
SUMMARIZE (
ALLSELECTED ( PolicyLog ),
PolicyLog[PolicyNum],
"Start", MIN ( PolicyLog[StatusDate] )
)
VAR Included =
SELECTCOLUMNS (
FILTER ( StartDates, [Start] <= MIN ( Dates[Date] ) ),
"Policies", PolicyLog[PolicyNum]
)
VAR Filtered = FILTER ( PolicyLog, PolicyLog[PolicyNum] IN Included )
RETURN
DIVIDE (
SUMX ( Filtered, PolicyLog[Net] ),
COUNTROWS ( SUMMARIZE ( Filtered, PolicyLog[PolicyNum] ) )
)
First, you create a table, StartDates, that gives the earliest dates for each policy limited to the time frame you have selected. It would look something like this:
StartData =
PolicyNum Start
123 1/1/2018
222 2/1/2018
333 1/1/2018
444 1/1/2018
From there, we just want a list of which policies we want to include in the calculation. So we pick the ones that have a Start on the minimum selected date in the date slicer. We just want a list of the resulting policy numbers, so we just select that column.
Included =
Policies
123
333
444
From there we filter the whole PolicyLog table to just include these ones (Filtered).
Finally, we can add up the Net column for each of these selected policies and divide by the distinct count of them to get our retention percentage.
Edit: In response to your comment, I think you want to be a bit more selective with the StartDate variable. Instead of MIN( PolicyLog[StatusDate] ), try something more like this:
CALCULATE( MIN(PolicyLog[StatusDate]), PolicyLog[Status] IN {"N", "RN", "RI"} )