Power Query Excel 将值显示为列的百分比
Power Query Excel show values as percentage of column
通常,数据透视表用于按特定顺序显示数据。对于这个特定的 "issue" 我需要提供数字和目标。
这在 Pivots 中存在冲突,因为列的百分比也考虑了目标。
不用担心,使用 PowerPivot 应该可以解决这个问题。到目前为止,我已经能够创建具有以下布局的 table:
1 2 3
cat A 5 10 7
cat B 10 8 9
cat C 0 2 1
其中 1、2 和 3 是一个月的前三天(为简单起见,其余部分被省略)。
我可以按如下方式得到各列的总数:
= Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(prevStep, _)))}, {"1","2","3"})
此外,我可以将列的每个值除以一个数字:
= Table.TransformColumns(prevStep, List.Transform({"1","2","3"}, each {_, (this) => this / 42, type number}))
现在我想将 42 替换为之前计算的各列的总数。请注意,“{"1","2","3"}" 将在另一步中自动计算。
有人可以详细说明如何实现吗?预期结果:
1 2 3
cat A 0.33 0.5 0.41
cat B 0.67 0.4 0.53
cat C 0 0.1 0.06
我无法想出一种简单地替换代码中的 42 的方法,但由于我看到这是矩阵数学,所以我将下面的解决方案基于 Gil Raviv's blog on matrix multiplication.
我从表 1 开始:
然后,要做到这一点...
...我使用 Table1 作为新查询的来源,此代码:
let
Source = Table1,
#"Removed Columns" = Table.RemoveColumns(Source,{""}),
MatrixA = Table.TransformColumnTypes(#"Removed Columns",{{"1", type number}, {"2", type number}, {"3", type number}}),
Summed = Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(MatrixA, _)))}, {"1","2","3"}),
MatrixB = Table.TransformColumnTypes(Summed,{{"1", type number}, {"2", type number}, {"3", type number}}),
IndexedMatrixA = Table.AddIndexColumn(MatrixA, "Index", 1, 1),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(IndexedMatrixA, {"Index"}, "Attribute", "Value"),
#"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Attribute", Int64.Type}}),
RenamedColumnsMatrixA = Table.RenameColumns(#"Changed Type",{{"Index", "Row"}, {"Attribute", "Column"}}),
IndexedMatrixB = Table.AddIndexColumn(MatrixB, "Index", 1, 1),
#"Unpivoted Other Columns1" = Table.UnpivotOtherColumns(IndexedMatrixB, {"Index"}, "Attribute", "Value"),
#"Changed Type1" = Table.TransformColumnTypes(#"Unpivoted Other Columns1",{{"Attribute", Int64.Type}}),
RenamedColumnsMatrixB = Table.RenameColumns(#"Changed Type1",{{"Index", "Row"}, {"Attribute", "Column"}}),
#"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,{"Column"},RenamedColumnsMatrixB,{"Column"},"RenamedColumnsMatrixB",JoinKind.LeftOuter),
#"Expanded RenamedColumnsMatrixB" = Table.ExpandTableColumn(#"Merged Queries", "RenamedColumnsMatrixB", {"Row", "Column", "Value"}, {"B.Row", "B.Column", "B.Value"}),
#"Added Custom" = Table.AddColumn(#"Expanded RenamedColumnsMatrixB", "AB", each [Value]/[B.Value]),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Row", "B.Column"}, {{"AB", each List.Sum([AB]), type number}}),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Grouped Rows", {{"B.Column", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Grouped Rows", {{"B.Column", type text}}, "en-US")[B.Column]), "B.Column", "AB"),
#"Added Index" = Table.AddIndexColumn(#"Pivoted Column", "Index", 1, 1),
IndexedSource = Table.AddIndexColumn(Source, "Index", 1, 1),
#"Merged Queries1" = Table.NestedJoin(#"Added Index",{"Index"},IndexedSource,{"Index"},"IndexedSource",JoinKind.LeftOuter),
#"Expanded IndexedSource" = Table.ExpandTableColumn(#"Merged Queries1", "IndexedSource", {""}, {"Column1"}),
#"Removed Columns1" = Table.RemoveColumns(#"Expanded IndexedSource",{"Row", "Index"}),
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns1",{"Column1", "1", "2", "3"})
in
#"Reordered Columns"
你会注意到我有点 "jumped around",使用以前的应用步骤(基本上是查询 table 状态)作为代码中的 "tables"...就像这些应用步骤:
Index MatrixB(IndexedMatrixB = Table.AddIndexColumn(MatrixB,
"Index", 1, 1),
其中 MatrixB
是前一个应用步骤);和
合并查询(#"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,{"Column"},RenamedColumnsMatrixB,"Column"},"RenamedColumnsMatrixB",JoinKind.LeftOuter),
,其中 RenamedColumnsMatrixA
和 RenamedColumnsMatrixB
是先前应用的步骤)。
@Marc Pince;感谢您的建议。经过一番努力后,我能够做出以下菜肴:
首先,我将总和计算行交换如下:
totMinDay = Table.ToRows (Table.FromRows({List.Transform(daysOfMonth , each List.Sum(Table.Column(prevStep, _)))}, daysOfMonth )){0},
其中 daysOfMonth 是从别处获得的那个实际月份的天数。
接下来我计算百分比如下:
perc= Table.TransformColumns(prevStep, List.Transform(daysOfMonth , each {_, (this) => Number.Round(this/ ( totMinDay {Number.FromText( _ ) - 1} ), 3), type number})),
我在这里使用总和的索引基于月中的第几天减去 1(从零开始)这一事实来提供可靠的结果。
感谢所有意见。
在这种情况下,您可以使用以下结构访问列名称:Table.Column(TableName, ColumnName).
在您的示例中,它将是:Table.Column(prevStep, _ ),其中“_”访问每一列。
所以,你的代码应该是这样的:
= Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(prevStep, _)))}, {"1","2","3"})
= Table.TransformColumns(prevStep, List.Transform({"1","2","3"}, each {_, (this) => this / Table.Column(prevStep, _), type number}))
通常,数据透视表用于按特定顺序显示数据。对于这个特定的 "issue" 我需要提供数字和目标。 这在 Pivots 中存在冲突,因为列的百分比也考虑了目标。
不用担心,使用 PowerPivot 应该可以解决这个问题。到目前为止,我已经能够创建具有以下布局的 table:
1 2 3
cat A 5 10 7
cat B 10 8 9
cat C 0 2 1
其中 1、2 和 3 是一个月的前三天(为简单起见,其余部分被省略)。
我可以按如下方式得到各列的总数:
= Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(prevStep, _)))}, {"1","2","3"})
此外,我可以将列的每个值除以一个数字:
= Table.TransformColumns(prevStep, List.Transform({"1","2","3"}, each {_, (this) => this / 42, type number}))
现在我想将 42 替换为之前计算的各列的总数。请注意,“{"1","2","3"}" 将在另一步中自动计算。
有人可以详细说明如何实现吗?预期结果:
1 2 3
cat A 0.33 0.5 0.41
cat B 0.67 0.4 0.53
cat C 0 0.1 0.06
我无法想出一种简单地替换代码中的 42 的方法,但由于我看到这是矩阵数学,所以我将下面的解决方案基于 Gil Raviv's blog on matrix multiplication.
我从表 1 开始:
然后,要做到这一点...
...我使用 Table1 作为新查询的来源,此代码:
let
Source = Table1,
#"Removed Columns" = Table.RemoveColumns(Source,{""}),
MatrixA = Table.TransformColumnTypes(#"Removed Columns",{{"1", type number}, {"2", type number}, {"3", type number}}),
Summed = Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(MatrixA, _)))}, {"1","2","3"}),
MatrixB = Table.TransformColumnTypes(Summed,{{"1", type number}, {"2", type number}, {"3", type number}}),
IndexedMatrixA = Table.AddIndexColumn(MatrixA, "Index", 1, 1),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(IndexedMatrixA, {"Index"}, "Attribute", "Value"),
#"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Attribute", Int64.Type}}),
RenamedColumnsMatrixA = Table.RenameColumns(#"Changed Type",{{"Index", "Row"}, {"Attribute", "Column"}}),
IndexedMatrixB = Table.AddIndexColumn(MatrixB, "Index", 1, 1),
#"Unpivoted Other Columns1" = Table.UnpivotOtherColumns(IndexedMatrixB, {"Index"}, "Attribute", "Value"),
#"Changed Type1" = Table.TransformColumnTypes(#"Unpivoted Other Columns1",{{"Attribute", Int64.Type}}),
RenamedColumnsMatrixB = Table.RenameColumns(#"Changed Type1",{{"Index", "Row"}, {"Attribute", "Column"}}),
#"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,{"Column"},RenamedColumnsMatrixB,{"Column"},"RenamedColumnsMatrixB",JoinKind.LeftOuter),
#"Expanded RenamedColumnsMatrixB" = Table.ExpandTableColumn(#"Merged Queries", "RenamedColumnsMatrixB", {"Row", "Column", "Value"}, {"B.Row", "B.Column", "B.Value"}),
#"Added Custom" = Table.AddColumn(#"Expanded RenamedColumnsMatrixB", "AB", each [Value]/[B.Value]),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Row", "B.Column"}, {{"AB", each List.Sum([AB]), type number}}),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Grouped Rows", {{"B.Column", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Grouped Rows", {{"B.Column", type text}}, "en-US")[B.Column]), "B.Column", "AB"),
#"Added Index" = Table.AddIndexColumn(#"Pivoted Column", "Index", 1, 1),
IndexedSource = Table.AddIndexColumn(Source, "Index", 1, 1),
#"Merged Queries1" = Table.NestedJoin(#"Added Index",{"Index"},IndexedSource,{"Index"},"IndexedSource",JoinKind.LeftOuter),
#"Expanded IndexedSource" = Table.ExpandTableColumn(#"Merged Queries1", "IndexedSource", {""}, {"Column1"}),
#"Removed Columns1" = Table.RemoveColumns(#"Expanded IndexedSource",{"Row", "Index"}),
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns1",{"Column1", "1", "2", "3"})
in
#"Reordered Columns"
你会注意到我有点 "jumped around",使用以前的应用步骤(基本上是查询 table 状态)作为代码中的 "tables"...就像这些应用步骤:
Index MatrixB(
IndexedMatrixB = Table.AddIndexColumn(MatrixB, "Index", 1, 1),
其中MatrixB
是前一个应用步骤);和合并查询(
#"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,{"Column"},RenamedColumnsMatrixB,"Column"},"RenamedColumnsMatrixB",JoinKind.LeftOuter),
,其中RenamedColumnsMatrixA
和RenamedColumnsMatrixB
是先前应用的步骤)。
@Marc Pince;感谢您的建议。经过一番努力后,我能够做出以下菜肴:
首先,我将总和计算行交换如下:
totMinDay = Table.ToRows (Table.FromRows({List.Transform(daysOfMonth , each List.Sum(Table.Column(prevStep, _)))}, daysOfMonth )){0},
其中 daysOfMonth 是从别处获得的那个实际月份的天数。
接下来我计算百分比如下:
perc= Table.TransformColumns(prevStep, List.Transform(daysOfMonth , each {_, (this) => Number.Round(this/ ( totMinDay {Number.FromText( _ ) - 1} ), 3), type number})),
我在这里使用总和的索引基于月中的第几天减去 1(从零开始)这一事实来提供可靠的结果。
感谢所有意见。
在这种情况下,您可以使用以下结构访问列名称:Table.Column(TableName, ColumnName).
在您的示例中,它将是:Table.Column(prevStep, _ ),其中“_”访问每一列。
所以,你的代码应该是这样的:
= Table.FromRows({List.Transform({"1","2","3"}, each List.Sum(Table.Column(prevStep, _)))}, {"1","2","3"})
= Table.TransformColumns(prevStep, List.Transform({"1","2","3"}, each {_, (this) => this / Table.Column(prevStep, _), type number}))