One of the features I’ve loved right from the start in Power Query is the ability to UnPivot data right from the UI (I’m not alone – Ken Puls has written a good blog post summing up this functionality and is equally impressed). However earlier this year when I was trying to implement Life in Power Query, I found that I needed to do the opposite: I needed to pivot data. I was able to do this with some pretty complex M, but since then the nice people on the Power query team have added a new Table.Pivot() function to allow this to be done easily. Unfortunately pivoting is not something that can be done using the UI alone (at least not at the time of writing), but it’s pretty straightforward to write your own M expression to use this new function.
Let’s take the following table as a starting point:
You can see, in the Measure column, we have values Sales Units and Sales Value that tell us what the numbers in each row in the Value column represent. For most purposes, it’s better to pivot this data so that we have two columns, one for Sales Units and one for Sales Value. You can do this pivot operation in a single step using Table.Pivot(). Here’s an example script that loads the data from the table above and pivots it:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Pivot = Table.Pivot(Source, {"Sales Units", "Sales Value"}, "Measure", "Value")
in
Pivot
Here’s the output:
It’s worth pointing out that if you don’t include each distinct value from your chosen column in the second parameter, those rows will be lost after the pivot takes place. So
= Table.Pivot(Source, {"Sales Units"}, "Measure", "Value")
Returns just:
Listing out all the column names in that second parameter is a bit of a pain, so we can get a list with all the distinct values in that column and improve our expression as follows:
= Table.Pivot(Source, List.Distinct(Table.Column(Source, "Measure")), "Measure", "Value")
This returns the same result as our first query – it uses Table.Column() to get a list of all the values in the Measure column, then List.Distinct() to return only the distinct values from that list.
Finally, there is an optional fifth parameter that can be used to aggregate data. The following source table has two rows for Sales Value for March:
If I use my original expression the pivot will work but I’ll get an error value in the cell for Sales Value for March:
Specifying a function to aggregate the data in these scenarios, where two cells need to be pivoted to one, solves the problem:
= Table.Pivot(Source, {"Sales Units", "Sales Value"}, "Measure", "Value", List.Sum)
In this case I’m passing the function List.Sum() to get the value 10+15=25 in the cell for Sales Value for March.