Power Query Transform a Column based on Another Column

前端 未结 6 1971
谎友^
谎友^ 2020-12-16 05:10

I keep thinking this should be easy but the answer is evading me. In Excel Power Query, I would like to transform the value in each row of a column based on another column\

相关标签:
6条回答
  • 2020-12-16 05:27

    Here is how I ended up doing this:

    Table1:
    Column A | Column B
    -------------------
    X        | 1
    Y        | 2
    
    = Table.FromRecords(Table.TransformRows(Table1,
        (r) => Record.TransformFields(r,
            {"A", each if r[Column B]="1" then "Z" else _})))
    

    Result:

    Column A | Column B
    -------------------
    Z        | 1
    Y        | 2
    

    This way you can transform multiple columns at once by using a nested list in the Record.TransformFields function.

    0 讨论(0)
  • 2020-12-16 05:27

    Another alternative is this:

    = Table.ReplaceValue(Table1, each [Column A], each if [Column B]=1 then "Z" else [Column A] , Replacer.ReplaceText, {"Column A"})

    The code is a bit more readable, but can only be applied to one column at a time.

    Most of it can be generated by using the UI, like shown here: http://www.thebiccountant.com/2017/07/23/transforming-a-column-with-values-from-another-column-in-powerbi-and-powerquery-in-excel/

    0 讨论(0)
  • 2020-12-16 05:41

    Sorry I was not so good editing the formula, this now works:

    = Table.ReplaceValue(   #"Removed Columns", 
                       each [Contract Start Date],
                        each if [Contract Start Date] < #date(2019,01,01) then #date(2019,01,01) else
                              [Contract Start Date]
                        ,Replacer.ReplaceValue,
                        {"Contract Start Date"})
    
    0 讨论(0)
  • 2020-12-16 05:45

    To build on LoganTheSnowEater's answer, here is one method to retain the table column types using the second argument in Table.FromRecords as specified in the M Reference:

    Table1:
    Column A | Column B
    -------------------
        X    |    1
        Y    |    2
    

    Edit: Updated to use much better method to extract table type from a table using Value.Type - also, embellished to modify multiple columns at once for completeness. Credit to this great convo for Value.Type: https://social.technet.microsoft.com/Forums/en-US/636e9b44-6820-4ff2-ab60-5dd6a5307bd2/type-conversion-mysteries

    =Table.FromRecords(
        Table.TransformRows(
            Table1,
            (r) => 
            Record.TransformFields(
                r,
                {
                    {"Column A", each if r[Column B]="1" then "Z" else _},
                    {"Column B", each if r[Column A]="Y" then "99" else _}
                }
            )
        ),
        Value.Type(Table1)
    )
    
    0 讨论(0)
  • 2020-12-16 05:45

    You can't transform the existing column with such a step. Use a new column, do the transform, then delete the existing column. What's the big deal? In Excel you would not expect a formula to change the value of a different column, either. In Power Query, the result of a formula is also stored in a column, and that cannot be the column that provides one of the formula input values.

    0 讨论(0)
  • 2020-12-16 05:48

    Kudos to LoganTheSnowEater... I love your answer. You mentioned that it could be expanded upon for multiple actions and I wanted to post an example of how I successfully used it to do so:

    #"Patch Records" = Table.FromRecords(Table.TransformRows(#"Sorted Rows",
    (r) => Record.TransformFields( r, {
        {"Min Commit", each 
            if r[service_id] = "21430" then 81 else
            if r[service_id] = "24000" then 230 else
            if r[service_id] = "24008" then 18 else
            if r[service_id] = "24009" then 46.9 else
            _},
        {"Installed", each 
            if r[service_id] = "21430" then 90 else
            if r[service_id] = "24000" then 230 else
            if r[service_id] = "24008" then 18 else
            if r[service_id] = "24009" then 52 else
            _},
        {"Requested", each 
            if r[service_id] = "21430" then 90 else
            if r[service_id] = "24000" then 230 else
            if r[service_id] = "24008" then 18 else
            if r[service_id] = "24009" then 52 else
            _}})))
    

    My only surprise was that I had to reset all of the data types after I was done, but that makes sense in retrospect.

    p.s. I didn't have enough reputation points to post this as a comment to the solution

    0 讨论(0)
提交回复
热议问题