Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
wsspglobal
Helper I
Helper I

Apply same calculation to a subset of data in the same column

Hi I have a scenario where I have my data in the same column (unpivoted), but the data are labeled as different items, in consecutive years. I want to calculate the growth rate of each year by item all at once. Is it possible?

 

I created a dummy table as an example:

Dummy table.JPG

I want to create a 5th column that calculates the % change from one year to the next for GDP and Population seperately. Note that I unpivoted the original data. I'm still a Power BI beginner, so I am not sure if after unpivoting the data, I cannot call the 'Item' and/or 'Amount' column in a measure or a new column. 

 

My end goal is to present visual charts the % change with slicers of geography, year, and item.

 

Please help! Thank you!

 

1 ACCEPTED SOLUTION

Thanks for that.

I created 2 columns.

One gets the previous year's value for the same Item and Geography

 

Previous Val = VAR _Item = Table1[Item]
              VAR _Year = Table1[Year]
              VAR _Geog = Table1[Geography]
RETURN
    CALCULATE(SUM(Table1[Amount]), 
        FILTER(Table1,
            Table1[Item] = _Item && 
            Table1[Geography] = _Geog &&
            Table1[Year] = _Year - 1))

The next shows the value as a percentage (Format this as a percentage)

 

%age = if (NOT ISBLANK(Table1[Previous Val]), (Table1[Amount] - Table1[Previous Val]) / Table1[Previous Val], 0)

View solution in original post

5 REPLIES 5
Cmcmahan
Resident Rockstar
Resident Rockstar

Thanks for posting your data in a copy/pastable format! That makes it much easier for us to play with your data

 

So the first thing I would tell a PowerBI beginner is to consider A) whether Power BI is the right tool for the job and B) whether you want to create this % change value as a new column of data.

 

To the first point, Power BI is not Excel.  It's great for displaying and slicing data, but not so good at adding data to tables that depend on previous rows.   Now, I understand that you're likely trying to learn PowerBI here, so I won't let the fact that PowerBI doesn't work well with this particular example stop me from proceeding.

 

To the second point, PowerBI has a few options for using DAX to calculate values.  It has measures and calculated columns.  Calculated columns are added to the original data tables and are only updated when the data is refreshed. You also have to store the result, so if your tables are large, you can easily double their size in memory. They're useful for when you want to add static values for your data, or want to be able to filter the entire report by the result.  These are what most new people gravitate towards because they're familiar.

Measures are more unique to DAX.  They're a way to essentially ask "What is the value of [Measure] right now?"  The important bit is the 'right now' part.  They can recalculate on the fly, with different data, based on slicer selections and position in a table/graph. There are limitations, like you can't add a measure to a slicer, but depending on how you want to display your data, are more versatile.  They're incredibly powerful, and are the tool that I would suggest for this problem.  

 

 

On to your solution.   The first thing to do is to create a new measure. I used this DAX code:

% Change = 
VAR prevAmt = CALCULATE(SUM(Countries[Amount]), FILTER(ALLEXCEPT(Countries,Countries[Geography],Countries[Item]), Countries[Year]=SELECTEDVALUE(Countries[Year])-1))
RETURN
DIVIDE( SUM(Countries[Amount])-prevAmt, prevAmt, "-" )

This may look overwhelming at first, but let's break it down.  

  • The VAR section declares a variable (that I've called prevAmt)  that I re-use twice in the actual calculation below. The RETURN statement just tells DAX that you're going back to the actual measure in question.
  • The bottom section is pretty straightforward math.  Take the SUM of the currently selected Amounts, subtract the previous amount, divide that by the previous amount.
    • We have to use SUM here because measures only work on aggregations.  Without you specifying, the measure doesn't know which value for [Amount] to use.  When you only expect have one value, SUM is an easy way to get a numerical result.
    • Also, if there's a divide by zero error, this returns a "-" instead of "infinity".  You'll get this result when there is no previous year's data, or the [Amount] from a previous year is 0.
  • Back to the VAR section.  First the CALCULATE statement.  This is how you calculate a result while changing the context.  In this case, we're SUMming the amount, but changing the context to the previous year. 
  • After the comma is a FILTER statement.  This defines the context filters we want to use when calculating the sum.  Now, this FILTER is a bit more complex than I would have liked, but is the best way for your example.
  • The ALLEXCEPT is a play on the syntax for ALL.  When you say ALL(Table), it returns the entire table, ignoring any filters in place, including those from visual or report level filters!  ALLEXCEPT returns all of the table in question, except it keeps the filters on columns specified.
    • In this case, we wanted to get back all the data from Countries, but keep any applied filters on [Geography] and [Item].  This way we're not comparing the previous year's GDP and Population data from Europe, Chile, & Paris against the current year's GDP data for just Chile.
    • Note that we didn't keep the filters applied to [Year] in the ALLEXCEPT, more on that next
  • Now that we've defined the table we want to use for this calculation (from the ALLEXCEPT clause), we need to pick which year of data we want to use as a comparison.  In this case, we want data from where the year is one less than the current year.  Ergo, we want data where the [Year] is equal to the current year minus one.  We use SELECTEDVALUE to return one value for year.
    • SELECTEDVALUE returns one value, but only when there's one value available.  In the context of the whole measure, there should only be one year's worth of data used to compare against the previous year's.  Otherwise how could you calculate the percent change?
    • Note that you can define a default value for SELECTEDVALUE if you wish, and that it defaults to blank.

And that's it!  You've created a measure, and now you can add it to your visualization. 

 

Here's my .pbix file using your data.  I've created a few table style visuals that display the original data and the % change measure differently.  I think the matrix is the best way to display data like this, but you may have a different purpose.  We get back to one of my original questions: How do you want to display this data in the end? What is your vision?

 

Hopefully that helped you understand Power BI a little bit better. If you have further questions, or actually really do need the percent change as a calculated column, feel free to follow up here!

HotChilli
Super User
Super User

Can you re-post the data (not a picture) and someone will help you out?

Hope this helps.

GeographyYearItemAmount
Europe2011GDP      5.93
Europe2012GDP      5.63
Europe2013GDP      4.01
Europe2014GDP      8.86
Paris2011GDP      3.29
Paris2012GDP      2.46
Paris2013GDP      2.34
Paris2014GDP      6.97
Chile2011GDP      6.98
Chile2012GDP      6.89
Chile2013GDP      7.53
Chile2014GDP      6.22
Europe2011Population      6.05
Europe2012Population      9.64
Europe2013Population      2.85
Europe2014Population      3.55
Paris2011Population      7.70
Paris2012Population      7.75
Paris2013Population      3.80
Paris2014Population      6.55
Chile2011Population      1.19
Chile2012Population      0.30
Chile2013Population      6.54
Chile2014Population      8.15

Thanks for that.

I created 2 columns.

One gets the previous year's value for the same Item and Geography

 

Previous Val = VAR _Item = Table1[Item]
              VAR _Year = Table1[Year]
              VAR _Geog = Table1[Geography]
RETURN
    CALCULATE(SUM(Table1[Amount]), 
        FILTER(Table1,
            Table1[Item] = _Item && 
            Table1[Geography] = _Geog &&
            Table1[Year] = _Year - 1))

The next shows the value as a percentage (Format this as a percentage)

 

%age = if (NOT ISBLANK(Table1[Previous Val]), (Table1[Amount] - Table1[Previous Val]) / Table1[Previous Val], 0)

That is absolutely what I needed. Thank you very much! This is super helpful.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.