Percent Retention - powerbi

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"} )

Related

Latest values by category based on a selected 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
)

DAX measure for Sum of values on the first and last day of a cycle

I have a table 'fact WorkItems', where changes made to items are saved on the day of the change ([ChangedDate]).
WorkItemId
AreaPath
ChangedDate
State
StoryPoints
IterationPath
1day
14day
Commitment
Delivered
1
A
04/01/2022
New
4
24.1
4
1
A
06/01/2022
Ready
6
24.1
6
1
A
10/01/2022
Active
6
24.1
6
1
A
12/01/2022
Testing
8
24.1
8
8
1
A
18/01/2022
Testing
2
24.1
1
A
19/01/2022
Testing
2
24.1
1
A
28/01/2022
Closed
2
24.1
2
1
A
01/02/2022
Closed
2
24.1
2
2
1
A
03/02/2022
Closed
2
24.1
I also have a table called 'dim Itrations', where cycles' start and end dates are kept.
IterationPath
StartDate
EndDate
24.1
13/01/2022
02/02/2022
24.2
03/02/2022
17/02/2022
24.3
18/02/2022
04/03/2022
I have created a measure [1day] which tells me how many [StoryPoints] had an Item on or before a cycle started
1day =
CALCULATE (
SUM( 'fact WorkItems'[StoryPoints] ),
FILTER (
'dim Iterations',
MAX('fact Workitems'[ChangedDate]) <= 'dim Iterations'[StartDate]
)
)
I have also created a measure [14day] which tells me how many [StoryPoints] had an Item by the end of the cycle once it's in "Closed" [State].
14day =
CALCULATE (
SUM( 'fact WorkItems'[StoryPoints] ),
FILTER ('fact WorkItems',
AND(
'fact Workitems'[State]="Closed",
'fact Workitems'[ChangedDate] <= MIN('dim Iterations'[EndDate])
)
))
My objective is to create two measures: [Commitment] and [Delivered] which will sum all the StoryPoints each team ([AreaPath]) had for each of  the cycles exactly on the the day the cycle started and ended (the latter with status closed). I know how to "tell" Power BI to only look at the rows, where Change date = [StartDate] or [ClosedDate].
The problem is when changes to items are made before the start/end date. I'm trying to "fill in those gaps" in the table by telling Power BI to look at the last record which was changed before or on the Start/End Date and to use those values. What I'm trying to achieve is presented in the table. Any ideas?

How to create a visual showing top 3 employees with highest sales for every date in a bar chart?

I have a table with the Date, Analyst Name, and Quantity of tickets resolved. What I want to create is a visual with a stacked bar chart for every date showing the top 3 analysts with the highest quantities of tickets resolved for each day.
I have tried using the TOP N filter but it filters every analyst except the 3 with the highest number of tickets resolved overall. But I want for each date.
You could use a rank measure.
Considering the following table with sample data:
Date
Analyst Name
Quantity
2021-01-01
A
5
2021-01-01
B
10
2021-01-01
C
15
2021-01-01
D
20
2021-01-02
A
42
2021-01-02
B
32
2021-01-02
C
22
2021-01-02
D
12
2021-01-03
A
15
2021-01-03
B
5
2021-01-03
C
21
2021-01-03
D
30
You can write a measure like this:
Rank =
RANKX (
CALCULATETABLE (
'Table',
-- remove the filter an Analyst Name to only keep grouping by Date
REMOVEFILTERS ( 'Table'[Analyst Name] )
),
-- CALCULATE needed here for context transition
CALCULATE (
SUM ( 'Table'[Quantity] )
)
)
In your report just pull this measure into the filter panel and configure it like this:
The result will then look like this:

DAX query to filter Invoices where at least one line item contains a particular product

I have an invoice table with columns including InvoiceNo and ProductID. I need to be able to filter so that it returns all Invoices that contain a particular Product. When this filter is applied, it needs to only display the invoices with that product, but it should show all products on that invoice.
For example, I have the following table:
InvoiceNo ProductID
111 ProdA
111 ProdB
111 ProdC
222 ProdA
222 ProdB
I only want to display invoices that have ProdC. When filtered, it needs to show
InvoiceNo ProductID
111 ProdA
111 ProdB
111 ProdC
I have tried the following DAX Measure:
CALCULATE(
COUNTROWS(Invoice),
SUMMARIZE(
FILTER(
SUMMARIZE(
Invoice
,Invoice[InvoiceNo]
,Invoice[ProductID]
)
,Invoice[ProductID] = "ProductC"
)
,Invoice[InvoiceNo]
)
)
But when I apply the filter (where measure > 0), it only returns the following
InvoiceNo ProductID
111 ProdC
If I was doing this in SQL, I would use the following query:
select
[InvoiceNo]
,[ProductID]
from
[Invoice]
where
[InvoiceNo] in (SELECT [InvoiceNo] FROM [Invoice] where [ProductID] = 'ProdC')
UPDATED: 19th July
A further complication is that we also have a Qty Column, which can contain the value 0. So an updated table would be
InvoiceNo ProductID Qty
111 ProdA 1
111 ProdB 2
111 ProdC 1
222 ProdA 1
222 ProdB 3
333 ProdA 1
333 ProdB 2
333 ProdC 0
I want to exclude Invoice 333 from my result, because while I am looking for invoices that contain ProdC, I only want them if ProdC qty is > 0.
This measure will do the trick
Active =
SUMX (
Products ;
CALCULATE(
DISTINCTCOUNT ( Products[InvoiceNo] ) ;
ALL ( Products ) ;
Products[ProductID] = "ProdC" ;
Products[Qty] <> 0 ;
Products[InvoiceNo] = EARLIER ( Products[InvoiceNo] )
)
)
First you make sure you perform the calculation on a row level with the iterator SUMX. This makes it possible to relate to the invoice number of that particular line and compare it against a filtered version of the product table based on product C and simply count the results.

DAX formula to calculate account balance

I am trying to use DAX to calculate the balance on claims. I have the following tables in Power BI:
Claims
ClaimID Charge
123 $100.00
456 $250.00
789 $400.00
Payments
PaymentID ClaimID Payment
1 123 $20.00
2 123 $10.00
3 456 $50.00
4 789 $25.00
5 789 $25.00
6 789 $25.00
So I want to add a Measure to my Claims table and it should show the balance. Thus, 123 would have $70 ($100 - $20 - $10), 456 would have $200, and 789 would have $325.
Create the following measure in the Claims table:
Balance =
SUM ( [Charge] )
- CALCULATE (
SUM ( Payments[Payment] ),
FILTER ( Payments, [ClaimID] = MAX ( Payments[ClaimID] ) )
)
If ClaimID is not an aggregable column you can use FIRSTNONBLANK(Payments[ClaimID],0) instead of MAX ( Payments[ClaimID] ).
You will get:
Let me know if this helps.