我一直认为这应该很容易,但答案却在逃避我。在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栏需要多个额外步骤。
答案 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"})