DAX Linear Interpolation

joeshu26

Board Regular
Joined
Oct 30, 2013
Messages
136
Hello,

One table is a "lookup" table that contains probabilities and scores. The other is a "fact" table with scores and a column for probabilities. I am looking for a DAX measure that will return the correct probability by linearly interpolating the score in the "fact" table to the "lookup" table...


ProbabilityScore
.01
14.58
.0212.12
.0310.75
.049.83
.059.16
.068.65
.078.23
.087.88
.097.59
.107.34
.117.12
.106.93

<tbody>
</tbody>

IdentifierIDGroupSizeScore
1A100009.5
2A84007.25
3A60008.499
4A30009.2124
5B450012.43
6B220011.689
7C48007.231
8C33008.82
9C860010.3
10C50009.9930
11D110010.6510
12D180013.4

<tbody>
</tbody>
 

Excel Facts

Format cells as date
Select range and press Ctrl+Shift+3 to format cells as date. (Shift 3 is the # sign which sort of looks like a small calendar).
I currently have this measure to get the weighted average score, so I can see size weighted score by group and would like the same thing with the interpolated probability

Wght Score:=DIVIDE(SUMX(factScore,factScore[Size]*factScore[Score]),SUM(factScore[Size]))
 
Upvote 0
I would create a series of intermediate measures to calculate the Scores above/below the Score of interest, the corresponding probabilities, the interpolation % and finally the interpolated probability.

I'm assuming [Wght Score] is the Score we want the interpolated probability for, and the lookup table is called 'Probability' and is hidden so it can't be filtered.


  1. Get the max Score that is <= [Wght Score]
    Code:
    [B]Score Lower[/B] :=
    CALCULATE (
        MAX ( 'Probability'[Score] ),
        FILTER (
            'Probability',
            'Probability'[Score] <= [Wght Score]
        )
    )
  2. Get the min Score that is >= [Wght Score]
    Code:
    [B]Score Upper[/B] :=
    CALCULATE (
        MIN ( 'Probability'[Score] ),
        FILTER (
            'Probability',
            'Probability'[Score] >= [Wght Score]
        )
    )
  3. Get the Probability corresponding to Score Lower
    Code:
    [B]Probability Lower [/B]:=
    CALCULATE (
        MIN ( 'Probability'[Probability] ),
        FILTER (
            'Probability',
            'Probability'[Score] = [Score Lower]
        )
    )
  4. Get the Probability corresponding to Score Upper
    Code:
    [B]Probability Upper [/B]:=
    CALCULATE (
        MAX ( 'Probability'[Probability] ),
        FILTER (
            'Probability',
            'Probability'[Score] = [Score Upper]
        )
    )
  5. Calculate the interpolation fraction
    Code:
    [B]Interpolation Fraction[/B] :=
    DIVIDE (
        [Wght Score] - [Score Lower],
        [Score Upper] - [Score Lower]
    )
  6. Finally calculate the interpolated Probability
    Code:
    [B]Probability Interpolated[/B] :=
    [Probability Lower]
        + [Interpolation Fraction]
        * ( [Probability Upper] - [Probability Lower] )
 
Upvote 0
Hi Guys,

I am looking to optimize the above queries to run quicker and reduce query/cpu duration. Anybody have some optimizations to the above queries to reduce query/dpu duration?
Thanks!
 
Upvote 0
Here is a better method than my original version, which should run more quickly (I've tested it myself with DAX Studio) :)

1. Add a column to your Probability table as shown below. I have called it "Probability Delta per Score Delta". This column is the 'slope' from the current row to the next row, defined as (Change in Probability)/(Change in Score).

For example the value in the first row is (0.02-0.01)/(12.12-14.58) = -0.004065.

I would suggest doing this in Power Query, but can also be done with a calculated column in the PowerPivot table. Having these values pre-computed saves on calculation in the PowerPivot measure.


ProbabilityScoreProbability Delta per Score Delta
0.0114.58-0.004065
0.0212.12-0.007299
0.0310.75-0.010870
0.049.83-0.014925
0.059.16-0.019608
0.068.65-0.023810
0.078.23-0.028571
0.087.88-0.034483
0.097.59-0.040000
0.17.34-0.045455
0.117.12-0.052632
0.126.93

<tbody>
</tbody>

2. Define a new Probability Interpolated measure as follows:
Code:
[B]Probability Interpolated :=[/B]
CALCULATE (
    VALUES ( 'Probability'[Probability] ) + VALUES ( 'Probability'[Probability Delta per Score Delta] ) * ( [Wght Score] - VALUES ( 'Probability'[Score] ) ),
    FIRSTNONBLANK( VALUES('Probability'[Score]), IF('Probability'[Score] >= [Wght Score],1) )
)
The 2nd argument of CALCULATE uses FIRSTNONBLANK to find the smallest 'Probability'[Score] that is >= [Wght Score]. This defines the row of the 'Probability' table we want to use.
The 1st argument of CALCULATE evaluates the linear interpolation using this row of 'Probability'.
 
Last edited:
Upvote 0
Ozeroth, thank you for this DAX wizardry!! I would love to download DAX studio if IT would only let me download it :(

I decided to create the Calculated Column 'Probability'[Probability Delta per Score Delta] in a SQL query, though Power Query what be an effective alternative.

This took performance of query time from +30 seconds to under 4 seconds!!!
 
Upvote 0
You're welcome :) That's great - wasn't sure how much faster it would be when applied to your real data.
 
Upvote 0
Would it be possible to move the " FIRSTNONBLANK( VALUES('Probability'[Score]), IF('Probability'[Score] >= [Wght Score],1) ) " filter argument to the storage engine?

For example, replacing the FIRSTNONBLANK with a combination of FILTER with MIN(X) of 'Probability'[Score] >= [Wght Score] ?
 
Upvote 0
Hmm interesting - I don't know enough about the ins & outs of storage vs formula engine to tell you for sure, but here are some possibilities. The 3rd one actually uses MIN.
Would be interested in relative performance in your full model - not sure if you have DAX Studio yet?

1. Keep FIRSTNONBLANK but use FILTER
Code:
=
CALCULATE (
    VALUES ( 'Probability'[Probability] )
        + VALUES ( 'Probability'[Probability Delta per Score Delta] )
            * ( [Wght Score] - VALUES ( 'Probability'[Score] ) ),
    FIRSTNONBLANK (
        FILTER ( VALUES ( 'Probability'[Score] ), 'Probability'[Score] >= [Wght Score] ),
        1
    )
)

2. Change FIRSTNONBLANK to TOPN and again use FILTER
Code:
=
CALCULATE (
    VALUES ( 'Probability'[Probability] )
        + VALUES ( 'Probability'[Probability Delta per Score Delta] )
            * ( [Wght Score] - VALUES ( 'Probability'[Score] ) ),
            TOPN(1, FILTER(VALUES('Probability'[Score]), 'Probability'[Score] >= [Wght Score]),'Probability'[Score],1)


)

3. Use FILTER and MIN function to determine min value
(Note that MIN returns a scalar so can't be directly used as a filter argument for CALCULATE like TOPN/FIRSTNONBLANK can. There could be a better way of doing this with MIN though, not sure.)
Code:
=
CALCULATE (
    VALUES ( 'Probability'[Probability] )
        + VALUES ( 'Probability'[Probability Delta per Score Delta] )
            * ( [Wght Score] - VALUES ( 'Probability'[Score] ) ),
    FILTER (
        VALUES ( 'Probability'[Score] ),
        'Probability'[Score]
            = CALCULATE (
                MIN ( 'Probability'[Score] ),
                FILTER ( VALUES ( 'Probability'[Score] ), 'Probability'[Score] >= [Wght Score] )
            )
    )
)
 
Last edited:
Upvote 0

Forum statistics

Threads
1,214,614
Messages
6,120,519
Members
448,968
Latest member
Ajax40

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top