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

Join us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.

Reply
megjarvis
Regular Visitor

Turn repeating row values into column headers?

I have a dataset that tracks the progress of various milestones across multiple projects. The projects are in rows and multiple attributes about each milestone are tracked in columns. I track both the name of the milestone and the percent completion of each milestone in separate columns. So if there are four milestones, I use eight columns to track them.

 

What I start with:

megjarvis_0-1688498653387.png

 

I want to get this data into an unpivoted table with the columns being: Project, Milestone, Name, Percent Complete.

 

What I need:

megjarvis_1-1688498678068.png

 

I can unpivot it and get the Project and Milestone columns, but the final two columns are Attribute (with values alternating between "Name" and "Percent Complete") and Value (with the values alternating between the actual names of the milestones and the actual percent completion numbers). 

 

What I can get to:

megjarvis_0-1688499310804.png

 

I have managed to get to the final product I'm looking for but it requires three extra tables per milestones, which seems ludicrous.  I think there must be a method that I'm just not aware of. Transpose doesn't work, because it will only transpose the entire table, and pivot doesn't work because I lose the text values in the cells. This feels like something that shouldn't be too complicated, though. Can you help?

 

Here's a link to the dummy data: 

https://docs.google.com/spreadsheets/d/1NogjwuUN7kTU0jDex5vmje8fnWURgEUARqK2Zo5Ghj8/edit?usp=sharing

 

Thanks for your help solving this mystery for me!

1 ACCEPTED SOLUTION
ronrsnfld
Super User
Super User

After doing your unpivot, you can

  • Split out the Number for the Milestone column
  • Add an extra column that is shifted by one from the Value column
  • Remove every other row from the table, starting with row 2
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"Project", type text}, {"Milestone 1 - Name", type text}, {"Milestone 1 - Percent Complete", type number}, {"Milestone 2 - Name", type text}, {"Milestone 2 - Percent Complete", type number}, {"Milestone 3 - Name", type text}, {"Milestone 3 - Percent Complete", type number}, {"Milestone 4 - Name", type text}, {"Milestone 4 - Percent Complete", type number}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Project"}, "Attribute", "Value"),
    
    #"Add Milestone" = Table.AddColumn(#"Unpivoted Other Columns", "Milestone", 
        each Number.From(Text.Split([Attribute]," "){1}), type number),
    #"Reordered Columns" = Table.ReorderColumns(#"Add Milestone",{"Project", "Milestone", "Attribute", "Value"}),
    #"Removed Columns" = Table.RemoveColumns(#"Reordered Columns",{"Attribute"}),

//Offset Percentage column
    #"Add Offset Col" = Table.FromColumns(
        Table.ToColumns(#"Removed Columns") &
        {List.RemoveFirstN(#"Removed Columns"[Value]) & {null}},
        type table[Project=text, Milestone=Int64.Type, Name=text, Percent Complete = Percentage.Type]),
        
    #"Removed Alternate Rows" = Table.AlternateRows(#"Add Offset Col",1,1,1)
in
    #"Removed Alternate Rows"

ronrsnfld_0-1688518512748.png

 

 

View solution in original post

3 REPLIES 3
ronrsnfld
Super User
Super User

After doing your unpivot, you can

  • Split out the Number for the Milestone column
  • Add an extra column that is shifted by one from the Value column
  • Remove every other row from the table, starting with row 2
let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{
        {"Project", type text}, {"Milestone 1 - Name", type text}, {"Milestone 1 - Percent Complete", type number}, {"Milestone 2 - Name", type text}, {"Milestone 2 - Percent Complete", type number}, {"Milestone 3 - Name", type text}, {"Milestone 3 - Percent Complete", type number}, {"Milestone 4 - Name", type text}, {"Milestone 4 - Percent Complete", type number}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Project"}, "Attribute", "Value"),
    
    #"Add Milestone" = Table.AddColumn(#"Unpivoted Other Columns", "Milestone", 
        each Number.From(Text.Split([Attribute]," "){1}), type number),
    #"Reordered Columns" = Table.ReorderColumns(#"Add Milestone",{"Project", "Milestone", "Attribute", "Value"}),
    #"Removed Columns" = Table.RemoveColumns(#"Reordered Columns",{"Attribute"}),

//Offset Percentage column
    #"Add Offset Col" = Table.FromColumns(
        Table.ToColumns(#"Removed Columns") &
        {List.RemoveFirstN(#"Removed Columns"[Value]) & {null}},
        type table[Project=text, Milestone=Int64.Type, Name=text, Percent Complete = Percentage.Type]),
        
    #"Removed Alternate Rows" = Table.AlternateRows(#"Add Offset Col",1,1,1)
in
    #"Removed Alternate Rows"

ronrsnfld_0-1688518512748.png

 

 

AH-MAZING! Thank you so much! 

 

I had to add a step to replace null percent complete values with 0s so my unpivot would result in perfect alternating rows, but it works! I love the outside-the-box thinking. I will review this more closely and see if I can replicate the outcome in my other report where I do the same thing.  Thanks again! 

ThxAlot
Super User
Super User

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCijKz0pNLlFwVNJBsGNKDQyMzIsVfDNzUotL8vNSFQyB0kamqvgVGQGlLQwIKDIGShsTMskEKG0GNClWB+FCJyQtTthdiGI3FjVGRKgxJkKNCUQNsuuckXQ4Y3edoQGKuVhUgdxnSkiRMUZUYFGExYUuSDpcsLsQ1W4sijAdiEUR2IGEFJmAAwTowlgA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Project = _t, #"Milestone 1 - Name" = _t, #"Milestone 1 - Percent Complete" = _t, #"Milestone 2 - Name" = _t, #"Milestone 2 - Percent Complete" = _t, #"Milestone 3 - Name" = _t, #"Milestone 3 - Percent Complete" = _t, #"Milestone 4 - Name" = _t, #"Milestone 4 - Percent Complete" = _t]),
    Cols = Table.ToColumns(Source),
    Tables = let col = Cols{0} in List.Transform(List.Split(List.Skip(Cols),2), each Table.FromColumns({col} & _, {"Project","Name","Pct Completed"})),
    Table = Table.Combine(Tables)
in
    Table

ThxAlot_0-1688501793567.png



Expertise = List.Accumulate(


        {Days as from Today},


        {Skills and Knowledge},


        (Current, Everyday) => Current & Day.LearnAndPractise(Everyday)


)



Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

June 2025 community update carousel

Fabric Community Update - June 2025

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