Power Query根据另一列转换列

时间:2015-07-21 19:39:21

标签: excel powerquery

我一直认为这应该很容易,但答案却在逃避我。在Excel Power Query中,我想根据另一列的值转换列的每一行中的值。例如,假设我有Table1如下:

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

我想根据B列中的值转换A列中的值,而不必添加新列并替换原始A列。我尝试使用TransformColumns但输入只能是目标列&# 39; s值 - 我无法从TransformColumns函数中访问行/记录中的其他字段值。我会喜欢能够做到这样的事情:

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

会导致:

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

我知道有办法做到这一点,但我试图找到一个步骤/转换量最少的人。例如,我知道我可以使用Table.AddColumn根据查看列B的函数添加 new 列A,但是我必须删除原始列A并将其替换为新列A栏需要多个额外步骤。

6 个答案:

答案 0 :(得分:13)

以下是我最终如何做到这一点:

undefined

结果:

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 _})))

这样,您可以使用Record.TransformFields函数中的嵌套列表一次转换多个列。

答案 1 :(得分:2)

感谢LoganTheSnowEater ......我喜欢你的回答。你提到它可以扩展为多个动作,我想发布一个如何成功使用它的例子:

#"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
        _}})))

我唯一的惊喜是我在完成后必须重置所有数据类型,但回想起来这是有道理的。

P.S。我没有足够的声誉点来发布这个作为对解决方案的评论

答案 2 :(得分:1)

另一种选择是:

= Table.ReplaceValue(表1,每个[A列],每个如果[B列] = 1然后“Z”否则[A列],Replacer.ReplaceText,{“A列”})

代码更具可读性,但一次只能应用于一列。

大多数都可以使用UI生成,如下所示:http://www.thebiccountant.com/2017/07/23/transforming-a-column-with-values-from-another-column-in-powerbi-and-powerquery-in-excel/

答案 3 :(得分:1)

要以LoganTheSnowEater的答案为基础,这是一种通过利用Table.Schema来构造表类型以用作Table.FromRecords中的第二个参数(如M Reference中指定的表)来保留表列类型的方法: / p>

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

= Table.FromRecords(
    Table.TransformRows(
        Table1,
        (r) => Record.TransformFields(r,
            {"Column A", each if r[Column B]="1" then "Z" else _}
        )
    ),
    Expression.Evaluate(
        let s = Table.Schema(Table1) in 
        "type table ["&
        Text.Combine(
            List.Transform(List.Zip({s[Name],s[TypeName]}),each "#"""&_{0}&""" = "&_{1}),
            ", ")
        &"]",
        #shared
    )
)

Table.Schema生成具有列名和列TypeName的表,这些表用于构造用于定义表类型的文本,在这种情况下为

type table [#"Column A" = Text.Type, #"Column B" = Int64.Type]

当然,可以手动键入表类型,如果转换更改了列中值的类型,则需要这样做。

答案 4 :(得分:0)

您无法使用此步骤转换现有列。使用新列,执行转换,然后删除现有列。有什么大不了的?在Excel中,您不希望公式更改其他列的值。在Power Query中,公式的结果也存储在列中,而不能是提供公式输入值之一的列。

答案 5 :(得分:0)

对不起,我对公式的编辑不太好,现在可以使用:

= 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"})