Forum Discussion
Calculate % change from previous row based on multiple columns
Good day,
I need to show analysis (% change of Total Viewers per Episode) for different packages (Gold, Silver, Bronze). The Title and Station of the Episode doesn't matter. My sample data is below and expected output (% change per Episode) is provided thereafter.
*Note that the number of Titles / which Package they get aired on varies by Episode.
I have been able to obtain a clunky solution by: duplicating the table, filtering on one package, group by Episode number, adding an index, creating a calculated column referencing the previous Episode (by Index), and then calculating the % change per episode. The disadvantage is that I would need to do this for all packages (my real data set has 7 packages), and then create separate visualisations for each table, so no user interactivity. I was hoping there's a more elegant solution?
Sample data:
| Title | Package | Episode number | Station | Viewers |
| Programme | Gold | 101 | A | 30 |
| Highlights | Gold | 101 | A | 25 |
| Programme | Silver | 101 | A | 50 |
| Highlights | Silver | 101 | A | 70 |
| Highlights | Bronze | 101 | A | 40 |
| Programme | Gold | 101 | B | 15 |
| Highlights | Gold | 101 | B | 10 |
| Programme | Silver | 101 | B | 40 |
| Highlights | Silver | 101 | B | 30 |
| Highlights | Bronze | 101 | B | 20 |
| Programme | Gold | 102 | A | 20 |
| Highlights | Gold | 102 | A | 40 |
| Programme | Silver | 102 | A | 60 |
| Highlights | Silver | 102 | A | 55 |
| Highlights | Bronze | 102 | A | 65 |
| Programme | Gold | 101 | B | 10 |
| Highlights | Gold | 101 | B | 20 |
| Programme | Silver | 101 | B | 25 |
| Highlights | Bronze | 101 | B | 15 |
| Programme | Gold | 103 | A | 20 |
| Highlights | Gold | 103 | A | 15 |
| Programme | Silver | 103 | A | 45 |
| Highlights | Bronze | 103 | A | 15 |
Expected output (% change in Viewers per Episode):
Thank you in advance for your time and expertise.
Hi Anonymous ,
First create a Episode table and dont create a relationship between;
Then create a measure as below:
Measure = VAR _previous = CALCULATE ( MAX ( 'Table'[Episode number] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] < MAX ( 'Table'[Episode number] ) ) ) VAR _previoussum = CALCULATE ( SUM ( 'Table'[Viewers] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] = _previous && 'Table'[Package] IN FILTERS ( Slicer[Package] ) ) ) VAR _currentsum = CALCULATE ( SUM ( 'Table'[Viewers] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] = MAX ( 'Table'[Episode number] ) && 'Table'[Package] IN FILTERS ( Slicer[Package] ) ) ) RETURN IF ( _previous = BLANK (), BLANK (), DIVIDE ( _currentsum - _previoussum, _previoussum ) )And you will see:
For the related .pbix file,pls see attached.
Best Regards,
KellyDid I answer your question? Mark my reply as a solution!
- Anonymous4 years ago
Thank you v-kelly-msft
In the meantime, my colleague came up with another solution that allows both the Viewers and % Change to be updated from the same slicer:
WoW % Change =VAR CurrentEpisode = SELECTEDVALUE('Table'[Episode number])VAR PreviousEpisode = CurrentEpisode -1VAR CurrentEpisodeScore = SUM('Table'[Viewers])VAR PreviousEpisodeScore = CALCULATE( SUM('Table'[Viewers]) , 'Table'[Episode number] = PreviousEpisode)VAR Wow = DIVIDE( CurrentEpisodeScore - PreviousEpisodeScore , PreviousEpisodeScore )RETURNWowThis solution also allows additional analysis by Title or Station, if required (see comparison between the two measures below):Thank you again for your input.
Hi Anonymous ,
Good solution,but one thing needs to be reminded,if the previous Episode number not equals the current one minus 1,then the solution will return error,you could check my solution which will avoid such error.
If you feel my solution is also a good one,I hope you could also mark my reply as answered to let more people find it.
Thanks in advance.
Best Regards,
KellyDid I answer your question? Mark my reply as a solution!
5 Replies
- amitchandakSuper User
Anonymous , if you need just based on episode. Better to create a table with distinct Episode and join it with Episode of this table
then
measure =
var _1 = sum(Table[Viewer])
var _2 = calculate(_1, filter(all(Episode), Episode [Episode] = maX(Episode[Episode])-1))
return
divide(_2,_1)
- AnonymousNot applicable
Thank you amitchandak
I'm not sure what I'm doing wrong, I created an Episode table (Distinct), linked to my data, and the measure, but the measure shows 100% regardless of the filter context.
The measure:
% Change =var _1 = sum('Table'[Viewers])var _2 = calculate(_1, filter(all(Episode), Episode[Episode number] = MAX(Episode[Episode number])-1))returndivide(_2,_1)My Data model:
Thank you again for your time.
- v-kelly-msftCommunity Support
Hi Anonymous ,
First create a Episode table and dont create a relationship between;
Then create a measure as below:
Measure = VAR _previous = CALCULATE ( MAX ( 'Table'[Episode number] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] < MAX ( 'Table'[Episode number] ) ) ) VAR _previoussum = CALCULATE ( SUM ( 'Table'[Viewers] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] = _previous && 'Table'[Package] IN FILTERS ( Slicer[Package] ) ) ) VAR _currentsum = CALCULATE ( SUM ( 'Table'[Viewers] ), FILTER ( ALL ( 'Table' ), 'Table'[Episode number] = MAX ( 'Table'[Episode number] ) && 'Table'[Package] IN FILTERS ( Slicer[Package] ) ) ) RETURN IF ( _previous = BLANK (), BLANK (), DIVIDE ( _currentsum - _previoussum, _previoussum ) )And you will see:
For the related .pbix file,pls see attached.
Best Regards,
KellyDid I answer your question? Mark my reply as a solution!