Forum Discussion

TaylorLile's avatar
TaylorLile
Frequent Visitor
6 years ago
Solved

Unpivot Two Groupings of Columns to Rows

Hello,

 

I am struggling with taking two groups of columns and converting them into only two columns. I have a decent understanding of unpivoting columns, but I'm not sure how to handle this when I have to do it another time because then I end up with an obserd number of rows. 

 

Here is what I'm trying to do in simple terms:

 

I have the following:

 

IDDiabetesHypertensionDepressionDiabetes LabHypertension LabDepression Lab
1TRUETRUEFALSE450
2TRUEFALSEFALSE514
3FALSETRUEFALSE531

 

I'm trying to convert this to look like below:

 

IDConditionDiagnosisLab Value
1DiabetesTRUE4
1HypertensionTRUE5
1DepressionFALSE0
2DiabetesTRUE5
2HypertensionFALSE1
2DepressionFALSE4
3DiabetesFALSE5
3HypertensionTRUE3
3DepressionFALSE1

 

First, I unpivoted the Diabetes, Hypertension and Depression columns to create those Condition and Diagnosis columns (Which is exactly what I need). However, I'm still left with the lab values and am unsure on how to unpivot. If I unpivot just those three lab columns I end up with the wrong results. 

 

Let me know if you have any advice!! Thanks!

  • FrankAT's avatar
    FrankAT
    6 years ago

    Hi,

    here is the used M-Code:

    // Table
    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCgkKdVXSgVFujj7BINoEiE2B2ACIDZVidaLRFcBoU7ACiAYjsEKYDJoGkEJjqGJjpdhYAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Diabetes = _t, Hypertension = _t, Depression = _t, #"Diabetes Lab" = _t, #"Hypertension Lab" = _t, #"Depression Lab" = _t, ID = _t]),
        #"Reordered Columns" = Table.ReorderColumns(Source,{"ID", "Diabetes", "Hypertension", "Depression", "Diabetes Lab", "Hypertension Lab", "Depression Lab"}),
        #"Changed Type" = Table.TransformColumnTypes(#"Reordered Columns",{{"Diabetes", type logical}, {"Hypertension", type logical}, {"Depression", type logical}, {"Diabetes Lab", Int64.Type}, {"Hypertension Lab", Int64.Type}, {"Depression Lab", Int64.Type}}),
        #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID"}, "Attribute", "Value"),
        #"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Columns", "Attribute", Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, false), {"Attribute.1", "Attribute.2"})
    in
        #"Split Column by Delimiter"
    
    // Lab Value (Reference of Table)
    let
        Source = Table,
        #"Filtered Rows" = Table.SelectRows(Source, each ([Attribute.2] = "Lab")),
        #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"Attribute.2"})
    in
        #"Removed Columns"
    
    // Diagnosis (Reference of Table)
    let
        Source = Table,
        #"Filtered Rows" = Table.SelectRows(Source, each ([Attribute.2] = null)),
        #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"Attribute.2"})
    in
        #"Removed Columns"
    
    // Merged Lab Value & Diagnosis
    let
        Source = Table.NestedJoin(#"Lab Value (Reference of Table)", {"ID", "Attribute.1"}, #"Diagnosis (Reference of Table)", {"ID", "Attribute.1"}, "Diagnosis", JoinKind.LeftOuter),
        #"Expanded Diagnosis" = Table.ExpandTableColumn(Source, "Diagnosis", {"Value"}, {"Value.1"}),
        #"Renamed Columns" = Table.RenameColumns(#"Expanded Diagnosis",{{"Attribute.1", "Condition"}, {"Value.1", "Diagnosis"}, {"Value", "Lab Value"}}),
        #"Reordered Columns" = Table.ReorderColumns(#"Renamed Columns",{"ID", "Condition", "Diagnosis", "Lab Value"}),
        #"Changed Type" = Table.TransformColumnTypes(#"Reordered Columns",{{"ID", Int64.Type}, {"Condition", type text}, {"Diagnosis", type logical}, {"Lab Value", Int64.Type}})
    in
        #"Changed Type"

     

    Figures:

     

     

    Regards FrankAT

9 Replies

  • Hi,

    This M code works

    let
        Source = Excel.CurrentWorkbook(){[Name="Data"]}[Content],
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"Diabetes", type logical}, {"Hypertension", type logical}, {"Depression", type logical}, {"Diabetes Lab", Int64.Type}, {"Hypertension Lab", Int64.Type}, {"Depression Lab", Int64.Type}}),
        #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID"}, "Attribute", "Value"),
        #"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Other Columns", "Attribute", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Attribute.1", "Attribute.2"}),
        #"Replaced Value" = Table.ReplaceValue(#"Split Column by Delimiter",null,"Diagnosis",Replacer.ReplaceValue,{"Attribute.2"}),
        #"Pivoted Column" = Table.Pivot(#"Replaced Value", List.Distinct(#"Replaced Value"[Attribute.2]), "Attribute.2", "Value")
    in
        #"Pivoted Column"

    Hope this helps.

    • FrankAT's avatar
      FrankAT
      Icon for Community Champion rankCommunity Champion

      Hi Ashish_Mathur,

      thx, I learned something again about pivoting data. I think your solution is the most efficient.

      Regards Frank AT

      • Ashish_Mathur's avatar
        Ashish_Mathur
        Icon for Super User rankSuper User

        Thank you.  If my reply helped, please mark it as Answer.

  • smpa01's avatar
    smpa01
    Icon for Community Champion rankCommunity Champion

    TaylorLile  please try this

    let
        Source = Web.BrowserContents("https://community.powerbi.com/t5/Desktop/Unpivot-Two-Groupings-of-Columns-to-Rows/m-p/953043#M456617"),
        #"Extracted Table From Html" = Html.Table(Source, {{"Column1", "TABLE:nth-child(9) > * > TR > :nth-child(1)"}, {"Column2", "TABLE:nth-child(9) > * > TR > :nth-child(2)"}, {"Column3", "TABLE:nth-child(9) > * > TR > :nth-child(3)"}, {"Column4", "TABLE:nth-child(9) > * > TR > :nth-child(4)"}, {"Column5", "TABLE:nth-child(9) > * > TR > :nth-child(5)"}, {"Column6", "TABLE:nth-child(9) > * > TR > :nth-child(6)"}, {"Column7", "TABLE:nth-child(9) > * > TR > :nth-child(7)"}}, [RowSelector="TABLE:nth-child(9) > * > TR"]),
        #"Promoted Headers" = Table.PromoteHeaders(#"Extracted Table From Html", [PromoteAllScalars=true]),
        #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ID", Int64.Type}, {"Diabetes", type logical}, {"Hypertension", type logical}, {"Depression", type logical}, {"Diabetes Lab", Int64.Type}, {"Hypertension Lab", Int64.Type}, {"Depression Lab", Int64.Type}}),
        Custom1 = Table.DemoteHeaders(#"Changed Type"),
        #"Transposed Table" = Table.Transpose(Custom1),
        #"Filtered Rows" = Table.SelectRows(#"Transposed Table", each ([Column1] <> "Depression Lab" and [Column1] <> "Diabetes Lab" and [Column1] <> "Hypertension Lab")),
        #"Transposed Table1" = Table.Transpose(#"Filtered Rows"),
        #"Promoted Headers1" = Table.PromoteHeaders(#"Transposed Table1", [PromoteAllScalars=true]),
        #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Promoted Headers1", {"ID"}, "Attribute", "Value"),
        #"Changed Type1" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"ID", Int64.Type}}),
        #"Trimmed Text1" = Table.TransformColumns(#"Changed Type1",{{"Attribute", Text.Trim, type text}}),
        Custom2 = Table.SelectRows(#"Transposed Table", each [Column1] = "Depression Lab" or [Column1] = "Diabetes Lab" or [Column1] = "Hypertension Lab" or [Column1] = "ID"),
        #"Transposed Table2" = Table.Transpose(Custom2),
        #"Promoted Headers2" = Table.PromoteHeaders(#"Transposed Table2", [PromoteAllScalars=true]),
        #"Unpivoted Other Columns1" = Table.UnpivotOtherColumns(#"Promoted Headers2", {"ID"}, "Attribute", "Value"),
        #"Replaced Value" = Table.ReplaceValue(#"Unpivoted Other Columns1","Lab","",Replacer.ReplaceText,{"Attribute"}),
        #"Trimmed Text" = Table.TransformColumns(#"Replaced Value",{{"Attribute", Text.Trim, type text}}),
        #"Changed Type2" = Table.TransformColumnTypes(#"Trimmed Text",{{"ID", Int64.Type}}),
        #"Merged Queries" = Table.NestedJoin(#"Trimmed Text1", {"ID", "Attribute"}, #"Trimmed Text", {"ID", "Attribute"}, "Replaced Value", JoinKind.LeftOuter),
        #"Expanded Replaced Value" = Table.ExpandTableColumn(#"Merged Queries", "Replaced Value", {"Value"}, {"Lab Value"})
    in
        #"Expanded Replaced Value"
    • TaylorLile's avatar
      TaylorLile
      Frequent Visitor

      Thanks amitchandak , but I'm still not sure this solves my issue. If I follow the instruction in the article, don't I run into the same issue I talked about earlier where I have duplicated rows that don't necessarily match each other like below?

       

      IDConditionDiagnosisCondition LabLab Value

      1HypertensionTRUEDiabetes Lab4
      1HypertensionTRUEHypertension Lab5
      1HypertensionTRUEDepression Lab0
      1DiabetesTRUEDiabetes Lab4
      1DiabetesTRUEHypertension Lab5
      1DiabetesTRUEDepression Lab0
      1DepressionFALSEDiabetes Lab4
      1DepressionFALSEHypertension Lab5
      1DepressionFALSEDepression Lab0
      2HypertensionFALSEDiabetes Lab5
      2HypertensionFALSEHypertension Lab1
      2HypertensionFALSEDepression Lab4
      2DiabetesTRUEDiabetes Lab5
      2DiabetesTRUEHypertension Lab1
      2DiabetesTRUEDepression Lab4
      2DepressionFALSEDiabetes Lab5
      2DepressionFALSEHypertension Lab1
      2DepressionFALSEDepression Lab4
      3HypertensionTRUEDiabetes Lab5
      3HypertensionTRUEHypertension Lab3
      3HypertensionTRUEDepression Lab1
      3DiabetesFALSEDiabetes Lab5
      3DiabetesFALSEHypertension Lab3
      3DiabetesFALSEDepression Lab1
      3DepressionFALSEDiabetes Lab5
      3DepressionFALSEHypertension Lab3
      3DepressionFALSEDepression Lab1
      • amitchandak's avatar
        amitchandak
        Icon for Super User rankSuper User

        You can use something like this in DAX. Instead of tablename[columnname], I just used [columnname]

        union(
         selectcolumn(table,"ID",[ID],"Condition","Diabetes","Diagnosis",[Diabetes],"Lab Value",[Diabetes Lab])
         ,selectcolumn(table,"ID",[ID],"Condition","Hypertension","Diagnosis",[Hypertension],"Lab Value",[Hypertension Lab])
         ,selectcolumn(table,"ID",[ID],"Condition","Depression ","Diagnosis",[Depression ],"Lab Value",[Depression  Lab])
         )

         

        But for M code

        ImkeF , can you help?