部分转置 table

Transpose table partially

我有一个 CSV 文件,其中包含有关某些生产批次的信息。当加载到 Excels PowerQuery 编辑器中时,table 看起来像这样:

Batch    Date         RawMaterial1    RawMaterial2    RawMaterial3    Amount1    Amount2    Amount3
123      01.01.2020   Fe              Cr              Ni              70         19         11
234      01.02.2020   Fe              Cr              Ni              72         17          9

为了使这个 table 更具可读性,我正在寻找一种方法来将其部分转置以将其转换为如下格式:

Batch    Date         RawMaterials    Amounts
123      01.01.2020   Fe              70
                      Cr              19
                      Ni              11
234      01.02.2020   Fe              72
                      Cr              17
                      Ni              11

有没有办法单独使用 PowerQueryM 实现这一点?

这似乎有效

取消透视除前两列之外的所有列

复制数据列

将列类型更改为数字以强制在非数字列上出错

将所有错误更改为可识别的内容,例如 999999999999

据此过滤成两个table,并为每个table

添加一个索引

将两个 table 合并在一起

添加新列,使用索引查看批次是否与前一行相同以消除重复项

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Date", "Batch"}, "Attribute", "Value"),
#"Duplicated Column" = Table.DuplicateColumn(#"Unpivoted Other Columns", "Value", "Value - Copy"),
#"Changed Type" = Table.TransformColumnTypes(#"Duplicated Column",{{"Value - Copy", type number}}),
#"Replaced Errors" = Table.ReplaceErrorValues(#"Changed Type", {{"Value - Copy", 999999999999999}}),
#"Filtered Rows" = Table.SelectRows(#"Replaced Errors", each ([#"Value - Copy"] = 999999999999999)),
#"Filtered Rows2" = Table.SelectRows(#"Replaced Errors", each ([#"Value - Copy"] <> 999999999999999)),
Index1 = Table.AddIndexColumn(#"Filtered Rows", "Index", 0, 1),
Index2 = Table.AddIndexColumn(#"Filtered Rows2", "Index", 0, 1),
#"Merged Queries" = Table.NestedJoin(Index2,{"Index"},Index1,{"Index"},"Index3",JoinKind.LeftOuter),
#"Expanded Index3" = Table.ExpandTableColumn(#"Merged Queries", "Index3", {"Value"}, {"Value.1"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Index3",{"Attribute", "Value - Copy"}),
#"Added Custom" = Table.AddColumn(#"Removed Columns", "Batch.1", each if [Index] = 0 then [Batch] else if #"Removed Columns"{[Index]-1}[Batch] = [Batch] then null else [Batch]),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "Date.1", each if [Index] = 0 then [Date] else if #"Removed Columns"{[Index]-1}[Batch] = [Batch] then null else [Date]),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom2",{"Batch", "Date", "Index"}),
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns1",{"Batch.1", "Date.1", "Value.1", "Value"})
in  #"Reordered Columns"

首先非常感谢@horseyride。我从您建议的代码中学到了很多东西。可悲的是,当我尝试将日期列也添加到逆轴区域时,我发现代码中存在一点缺陷。但是由于我从中吸取的教训,我能够制作出一个稍微更通用的版本,它基本上遵循相同的算法。

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}}),
    #"Unpivot Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Batch"}, "Attribut", "Wert"),
    Filter1 = Table.SelectRows(#"Unpivot Columns", each ([Attribut] <> "Amount1" and [Attribut] <> "Amount2" and [Attribut] <> "Amount3")),
    ModFilter1 = Table.AddColumn(Filter1, "Benutzerdefiniert", each if [Attribut] = "Date" then [Attribut] else [Wert], type text),
    Filter2 = Table.SelectRows(#"Unpivot Columns", each ([Attribut] <> "RawMaterial1" and [Attribut] <> "RawMaterial2" and [Attribut] <> "RawMaterial3")),
    #"IndexFilter1" = Table.AddIndexColumn(ModFilter1, "Index", 0, 1),
    #"IndexFilter2" = Table.AddIndexColumn(Filter2, "Index", 0, 1),
    #"Join Filtered Indexes" = Table.NestedJoin(IndexFilter1,{"Index"},IndexFilter2,{"Index"},"IndexFilter2",JoinKind.LeftOuter),
    #"Expand Joined Column" = Table.ExpandTableColumn(#"Join Filtered Indexes", "IndexFilter2", {"Wert"}, {"IndexFilter2.Wert"}),
    #"Remove Columns" = Table.RemoveColumns(#"Expand Joined Column",{"Index", "Attribut", "Wert"}),
    #"Rename Columns" = Table.RenameColumns(#"Remove Columns",{{"Benutzerdefiniert", "Attribut"}, {"IndexFilter2.Wert", "Wert"}})
in
    #"Rename Columns"

我会检查 horseyrides 的答案是否为正确答案,因为他原样解决了我最初的问题。

这可以更简单地完成:

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],,
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Batch", Int64.Type}, {"Date", type date}, {"RawMaterial1", type text}, {"RawMaterial2", type text}, {"RawMaterial3", type text}, {"Amount1", Int64.Type}, {"Amount2", Int64.Type}, {"Amount3", Int64.Type}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Batch", "Date"}, "Attribute", "Value"),
    #"Split Column by Character Transition" = Table.SplitColumn(#"Unpivoted Other Columns", "Attribute", Splitter.SplitTextByCharacterTransition((c) => not List.Contains({"0".."9"}, c), {"0".."9"}), {"Type", "Index"}),
    #"Pivoted Column" = Table.Pivot(#"Split Column by Character Transition", List.Distinct(#"Split Column by Character Transition"[Type]), "Type", "Value")
in
    #"Pivoted Column"
  1. 取消透视除前两列以外的所有列。
  2. 将属性列拆分为文本部分和索引部分(在 GUI 中:转换 > 拆分列 > 按非数字到数字)。
  3. 回到文本部分列(在“数据透视列高级”选项中选择“不聚合”)。