I wish to clean up a table I have been working on removing complex formulas and opting to sort my data using PQE.
Below is a made up example of the data I am working with.
I wish to have the output column alternate between material and sub values akin to headers and sub headers in a book.
M Code so far:
let
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Material ", type text}, {"Sub ", type text}, {"CAS", type text}}),
#"Trimmed Text" = Table.TransformColumns(#"Changed Type",{{"Material ", Text.Trim, type text}, {"Sub ", Text.Trim, type text}}),
#"Cleaned Text" = Table.TransformColumns(#"Trimmed Text",{{"Sub ", Text.Clean, type text}}),
#"Replaced Value" = Table.ReplaceValue(#"Cleaned Text","-","",Replacer.ReplaceText,{"Sub "}),
#"Merged Columns" = Table.CombineColumns(#"Replaced Value",{"Material ", "Sub "},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"Merged"),
#"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Merged Columns", {{"Merged", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Merged"),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Merged", type text}})
in
#"Changed Type1"
The problem with this code is that it doesn't properly list the materials when combined and I also don't know how to get the CAS numbers to be correctly sorted.
If anyone has any thoughts how to achieve the desired output it would be appreciated.
You can get your output from your input using the same technique I showed you in your last, similar question.
create two lists of the columns; then List.Zip to combine them.
The trick is that for List 1, (eg output column 1), you may need to add the contents of the Material column at the top of the Sub column list (or replace the - if that's all there is; and, if that is the case, add a - at the start of the CAS list; so things will line up at the end.
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table13"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Material", type text}, {"Sub", type text}, {"CAS", type text}}),
//combine the columns
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each
let
L1 = if [Sub] = "-" then {[Material]}
else List.Combine({{[Material]},Text.Split([Sub],"#(lf)")}),
L2 = if [Sub] = "-" then {[CAS]}
else List.Combine({{"-"},Text.Split([CAS],"#(lf)")})
in
List.Zip({L1,L2})),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom",{"Material", "Sub", "CAS"}),
//split the combined columns
#"Expanded Custom" = Table.ExpandListColumn(#"Removed Columns1", "Custom"),
#"Extracted Values" = Table.TransformColumns(#"Expanded Custom",
{"Custom", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values",
"Custom", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Material", "CAS"})
in
#"Split Column by Delimiter"
Related
What I want to achieve:
As the title says, is there any way to convert my table structure? I've tried using Power Query but it didn't work. Any kind of help is greatly appreciated. Thanks!
So, I was trying to pivot type and type value, but it seems impossible if I maintain the current table structure since it would cause duplicates when I wanted to aggregate on type.
Should I remake the table structure or there is any way to get around this problem?
Thanks in advance!
In Power Query, the following is adaptable to any number of type/value column pairs.
Unpivot all except the ID column
Add a custom column to define if the unpivoted value is a Type or a Type Value
Add an Index column and then do an integer/divide by 2 so things will sort in the desired order
Pivot with no aggregation, using a custom function as the "built-in" function will error with multiple items.
Custom function to Pivot with No aggregation
Rename as noted in comments
//credit: Cam Wallace https://www.dingbatdata.com/2018/03/08/non-aggregate-pivot-with-multiple-rows-in-powerquery/
//Rename: fnPivotAll
(Source as table,
ColToPivot as text,
ColForValues as text)=>
let
PivotColNames = List.Buffer(List.Distinct(Table.Column(Source,ColToPivot))),
#"Pivoted Column" = Table.Pivot(Source, PivotColNames, ColToPivot, ColForValues, each _),
TableFromRecordOfLists = (rec as record, fieldnames as list) =>
let
PartialRecord = Record.SelectFields(rec,fieldnames),
RecordToList = Record.ToList(PartialRecord),
Table = Table.FromColumns(RecordToList,fieldnames)
in
Table,
#"Added Custom" = Table.AddColumn(#"Pivoted Column", "Values", each TableFromRecordOfLists(_,PivotColNames)),
#"Removed Other Columns" = Table.RemoveColumns(#"Added Custom",PivotColNames),
#"Expanded Values" = Table.ExpandTableColumn(#"Removed Other Columns", "Values", PivotColNames)
in
#"Expanded Values"
Regular Query
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"ID", type text}, {"Type 1", type text}, {"Type 1 Value", Int64.Type}, {"Type 2", type text}, {"Type 2 Value", Int64.Type}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "Custom",
each if Text.EndsWith([Attribute],"Value") then "Value" else "Type"),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Attribute"}),
#"Added Index" = Table.AddIndexColumn(#"Removed Columns", "Index", 0, 1, Int64.Type),
#"Inserted Integer-Division" = Table.AddColumn(#"Added Index", "Integer-Division", each Number.IntegerDivide([Index], 2), Int64.Type),
#"Removed Columns1" = Table.RemoveColumns(#"Inserted Integer-Division",{"Index"}),
Pivot = fnPivotAll(#"Removed Columns1","Custom","Value"),
#"Removed Columns2" = Table.RemoveColumns(Pivot,{"Integer-Division"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns2",{{"Type", type text}, {"Value", Int64.Type}})
in
#"Changed Type1"
More generically to stack vertically in powerquery while keeping certain columns
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
base_columns=1, groupsof=2, //stack them
Combo = List.Transform(List.Split(List.Skip(Table.ColumnNames(Source),base_columns),groupsof), each List.FirstN(Table.ColumnNames(Source),base_columns) & _),
#"Added Custom" =List.Accumulate(Combo, #table({"Column1"}, {}),(state,current)=> state & Table.Skip(Table.DemoteHeaders(Table.SelectColumns(Source, current)),1)),
#"Rename"=Table.RenameColumns(#"Added Custom",List.Zip({Table.ColumnNames(#"Added Custom"),List.FirstN(Table.ColumnNames(Source),base_columns+groupsof)}))
in #"Rename"
What seems to be fastest method of those I've tested
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
leading=1, groupsof=2,
#"Added Custom" = Table.AddColumn(Source, "Custom", each List.Split( List.RemoveFirstN(Record.ToList( _),leading), groupsof) ),
#"Added Custom0" = Table.AddColumn(#"Added Custom", "Custom0", each Text.Combine(List.FirstN(Record.ToList(_),leading),"|")),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom0",{"Custom0", "Custom"}),
#"Expanded Custom" = Table.ExpandListColumn( #"Removed Other Columns", "Custom"),
#"Extracted Values" = Table.TransformColumns(#"Expanded Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), "|"), type text}),
#"Merged Columns" = Table.CombineColumns(#"Extracted Values",{"Custom0", "Custom"},Combiner.CombineTextByDelimiter("|", QuoteStyle.None),"Custom"),
#"Split Column by Delimiter" = Table.SplitColumn(#"Merged Columns", "Custom", Splitter.SplitTextByDelimiter("|", QuoteStyle.Csv), List.FirstN(Table.ColumnNames(Source),leading+groupsof))
in #"Split Column by Delimiter"
There is probably a better way, but if you first concat the 4 columns with specific unique delimiter to split on later in a custom column, you have a work-around in PQ:
let
Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"Type1", type text}, {"Type1 Val", Int64.Type}, {"Type2", type text}, {"Type2 Val", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom1", each [Type1]&"|"&Number.ToText([Type1 Val])&"$"&[Type2]&"|"&Number.ToText([Type2 Val])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Type1", "Type1 Val", "Type2", "Type2 Val"}),
#"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Removed Columns", {{"Custom1", Splitter.SplitTextByDelimiter("$", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Custom1"),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Custom1", type text}}),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "Custom1", Splitter.SplitTextByEachDelimiter({"|"}, QuoteStyle.Csv, false), {"Custom1.1", "Custom1.2"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Custom1.1", type text}, {"Custom1.2", Int64.Type}})
in
#"Changed Type2"
Just in case you tagged 'Excel-Formula' and you have access to ms365:
Formula in H1:
=REDUCE({"ID","Type","Val"},ROW(A2:A5),LAMBDA(X,Y,VSTACK(X,INDEX(A:E,Y,{1,2,3}),INDEX(A:E,Y,{1,4,5}))))
Or formula:
=SORT(VSTACK(A2:C5,HSTACK(A2:A5,D2:E5)))
I have data that looks like this:
Wire
Point1
Point2
Point3
Point4
Point5
Point6
A
WP1
WP1
WP2
WP2
B
WP3
WP4
WP3
WP4
C
WP5
WP5
WP6
WP7
WP6
WP7
(note the varying lengths of each row, and the duplicates)
I would like to have the end result be:
Wire
Point1
Point2
Point3
A
WP1
WP2
B
WP3
WP4
C
WP5
WP6
WP7
Duplicates removed, and blank spaces removed.
This would be VERY similar to the =UNIQUE() function, but that is not available in power query.
It's a lot easier to work with columns, so I'd recommend unpivoting the Point columns, removing duplicates, and then putting it into the shape you want.
Here's a full query you can past into your Advanced Editor to look at each step more closely:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUQoPMEQijYAkBIHYsTrRSk5gtjGYNIGzYWpMwGqcwWxTJNIMTJqjsGNjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Wire = _t, Point1 = _t, Point2 = _t, Point3 = _t, Point4 = _t, Point5 = _t, Point6 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Wire", type text}, {"Point1", type text}, {"Point2", type text}, {"Point3", type text}, {"Point4", type text}, {"Point5", type text}, {"Point6", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Wire"}, "Attribute", "Value"),
#"Filtered Rows" = Table.SelectRows(#"Unpivoted Other Columns", each ([Value] <> "")),
#"Removed Duplicates" = Table.Distinct(#"Filtered Rows", {"Wire", "Value"}),
#"Grouped Rows" = Table.Group(#"Removed Duplicates", {"Wire"}, {{"Point", each Text.Combine([Value],","), type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Grouped Rows", "Point", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Point1", "Point2", "Point3"})
in
#"Split Column by Delimiter"
Unpivot
Group by Wire
Aggregate into sorted List of Unique Points
Calculate Max number of items in all the Lists to use in the later Column Splitter
Extract the List of points into semicolon separated string
Split into new columns
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source, List.Transform(Table.ColumnNames(Source), each {_, Text.Type})),
//Unpivot
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Wire"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
//Group by Wire
//Aggregate by sorted, unique list of Points for each Wire
#"Grouped Rows" = Table.Group(#"Removed Columns", {"Wire"}, {
{"Point", each List.Sort(List.Distinct([Value]))}}),
//Calculate the Max unique Points for any Wire (for subsequent splitting
maxPoints = List.Max(List.Transform(#"Grouped Rows"[Point], each List.Count(_))),
//Extract the List values into a semicolon separated list
#"Extracted Values" = Table.TransformColumns(#"Grouped Rows",
{"Point", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
//Then split into new columns using the semicolon delimiter
#"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Point",
Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv),maxPoints)
in
#"Split Column by Delimiter"
I have data from multiple suppliers which I wish to compare. The data shown in the image below has been previously transformed via a series of steps using power query. The final step was to pivot the Supplier column (in this example consisting of X,Y,Z) so that these new columns can be compared and the maximum value is returned.
How can I compare the values in columns X, Y and Z to do this? Importantly, X Y and Z arent necessarily the only suppliers. If I Add Say A as a new supplier to the original data, a new column A will be generated and I wish to include this in the comparison so that at column at the end outputs the highest value found for each row. So reading from the top down it would read in this example: 3,3,1,1,5,0.04,10 etc.
Thanks
Link to file https://onedrive.live.com/?authkey=%21AE_6NgN3hnS6MpA&id=8BA0D02D4869CBCA%21763&cid=8BA0D02D4869CBCA
M Code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Material", type text}, {"Residual Solvents", type text}, {"RMQ", type text}, {"COA", type text}, {"Technical Data Sheet", type text}}),
//Replace Time and null with blank
#"Replaced Value" = Table.ReplaceValue(#"Changed Type","00:00:00","",Replacer.ReplaceText,{"Material", "RMQ", "Residual Solvents", "Technical Data Sheet", "COA"}),
#"Replaced Value1" = Table.ReplaceValue(#"Replaced Value",null,"",Replacer.ReplaceValue,{"Material", "RMQ", "Residual Solvents", "Technical Data Sheet", "COA"}),
//Trims all whitespace from user
#"Power Trim" = Table.TransformColumns(#"Replaced Value1",{{"Material", #"PowerTrim", type text}, {"Residual Solvents", #"PowerTrim", type text}, {"RMQ", #"PowerTrim", type text}, {"COA", #"PowerTrim", type text}, {"Technical Data Sheet",#"PowerTrim", type text}}),
//Unpivot to develop a single column of solvent/metals/date data
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Power Trim", {"Material", "Supplier"}, "Attribute", "Value"),
//split into rows by line feed
#"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Unpivoted Other Columns",
{{"Value", Splitter.SplitTextByDelimiter("#(lf)", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Value"),
#"Trimmed Text" = Table.TransformColumns(#"Split Column by Delimiter",{{"Value", Text.Trim, type text}}),
//filter out the blank rows
#"Filtered Rows" = Table.SelectRows(#"Trimmed Text", each ([Value] <> "" and [Value] <> "Not Provided")),
//Add custom column for separating the tables
#"Added Custom" = Table.AddColumn(#"Filtered Rows", "Custom", each try Date.FromText([Value]) otherwise
if [Value] = "Heavy Metals" or [Value] = "Residual Solvents" or [Value] = "Other" then [Value] else null),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Custom", type text}}),
#"Filled Down" = Table.FillDown(#"Changed Type1",{"Custom"}),
//Filter the value and custom columns to remove contaminant type from Value column and remove dates from Custom column
#"Filtered Rows1" = Table.SelectRows(#"Filled Down", each ([Custom] = "Heavy Metals" or [Custom] = "Residual Solvents") and ([Value] <> "Heavy Metals" and [Value] <> "Residual Solvents")),
//split substance from amount
#"Split Column by Delimiter1" = Table.SplitColumn(#"Filtered Rows1", "Value",
Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, true), {"Substance", "Amount"}),
//Filter for Solvents Table
#"Filtered Rows2" = Table.SelectRows(#"Split Column by Delimiter1", each ([Custom] = "Heavy Metals")),
#"Changed Type2" = Table.TransformColumnTypes(#"Filtered Rows2",{{"Amount", type number}}),
//Group by Material and Substance, then extract the Max contaminant and Source
#"Grouped Rows" = Table.Group(#"Changed Type2", {"Substance","Material", "Supplier"}, {
{"Amount", each List.Max([Amount]), type number},
{"Source", (t) => t[Attribute]{List.PositionOf(t[Amount],List.Max(t[Amount]))}, type text}
}),
#"Sorted Rows" = Table.Sort(#"Grouped Rows",{{"Substance", Order.Ascending}}),
//PIVOT to compare suppliers
#"Pivoted Column" = Table.Pivot(#"Sorted Rows", List.Distinct(#"Sorted Rows"[Supplier]), "Supplier", "Amount", List.Sum)
in
#"Pivoted Column"
Add an Index Column starting with zero (0).
Add a Custom Column:
=List.Max(
Record.ToList(
Table.SelectColumns(#"Added Index",
List.RemoveFirstN(
Table.ColumnNames(#"Pivoted Column"),3)){[Index]}))
Then remove the Index column
Algorithm
Generate a list of the relevant column names to sum.
We exclude the first three column names from this list
Note that we refer to the step PRIOR to adding the Index column for the list of column names. If we referred to the actual previous step where we added the Index column, we'd also have to remove the Last column name
Select the relevant columns
{[Index]} will return a record corresponding to the Index number.
Convert the record to a list and use List.Max
I'm trying to format an excel file using Power Query in order to be able to pivot it, but I haven't been able to do it right.
I'm merging many worksheets from different workbooks into one. Every sheet has the data of the specific workbook in the first 3 rows (column 1= Title; and Column 2= Value), and then I have the table well formatted starting in row 5 (with headers and all, but different amount of rows each)
How can I transform the data in the first 3 rows of every sheet into columns, so I can get a Pivotable table?
Here an example of what I get when merging 2 files.
Based on the picture I assume you would like to transform such kind of file
to something like that
I used the following M-Code for that
let
Source = Table.FromColumns({Lines.FromBinary(File.Contents("D:\tmp\Files\file1.txt"), null, null, 1252)}),
#"Kept First Rows" = Table.FirstN(Source,3),
#"Split Column by Delimiter" = Table.SplitColumn(#"Kept First Rows", "Column1", Splitter.SplitTextByDelimiter("#(tab)", QuoteStyle.Csv), {"Col1", "Col2"}),
step = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Col1", type text}, {"Col2", type text}}),
#"Transposed Table" = Table.Transpose(step),
#"Promoted Headers" = Table.PromoteHeaders(#"Transposed Table", [PromoteAllScalars=true]),
Hdr = Table.TransformColumnTypes(#"Promoted Headers",{{"Nummer", type text}, {"Id", type text}}),
Custom1 = Source,
#"Removed Top Rows" = Table.Skip(Custom1,4),
#"Split Column by Delimiter1" = Table.SplitColumn(#"Removed Top Rows", "Column1", Splitter.SplitTextByDelimiter("#(tab)", QuoteStyle.Csv), {"Column1.1", "Column1.2", "Column1.3", "Column1.4"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Column1.1", type text}, {"Column1.2", type text}, {"Column1.3", type text}, {"Column1.4", type text}}),
#"Promoted Headers1" = Table.PromoteHeaders(#"Changed Type1", [PromoteAllScalars=true]),
#"Changed Type2" = Table.TransformColumnTypes(#"Promoted Headers1",{{"F1", Int64.Type}, {"F2", Int64.Type}, {"F3", Int64.Type}, {"F4", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type2", "Nummer", each Hdr[Nummer]),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "ID", each Hdr[Id]),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Export", each Hdr[Export]),
#"Expanded Export" = Table.ExpandListColumn(#"Added Custom2", "Export"),
#"Expanded ID" = Table.ExpandListColumn(#"Expanded Export", "ID"),
#"Expanded Nummer" = Table.ExpandListColumn(#"Expanded ID", "Nummer"),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded Nummer",{{"Export", type date}})
in
#"Changed Type"
Let's say that I have a column that has a comma seperated list of values in each row
Row ID | Symptoms
1 | Vomiting,Diarrhoea
2 | Diarrhoea
3 | Cough
Would it be possible to transform this into the following in Power Query?:
Row ID | Symptoms - Cough | Symptoms - Diarrhoea | Symptom - Vomiting
1 | No | Yes | Yes
2 | No | Yes | No
3 | Yes| No | No
Unfortunately could not a find a specific question and answers that tackles my challenge on Stack Overflow and tried looking up multiple videos on YouTube with limited success.
I suggest:
Split the symptom column by comma
Select the Row ID column and unpivot other columns
Add a custom column consisting of the word "Yes"
Pivot on the Value column (containing the symptoms) and Don't Aggregate
Replace the null with "No"
The code as written should adjust as you add/remove rows or symptoms from your orginal data table.
If you need to prefix all of the symptom columns with Symptoms - , that can be done with a few more lines of code.
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Row ID", Int64.Type}, {"Symptoms", type text}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Symptoms", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv)),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Split Column by Delimiter", {"Row ID"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
#"Trimmed Text" = Table.TransformColumns(#"Removed Columns",{{"Value", Text.Trim, type text}}),
#"Added Custom" = Table.AddColumn(#"Trimmed Text", "Custom", each "Yes"),
#"Pivoted Column" = Table.Pivot(#"Added Custom", List.Distinct(#"Added Custom"[Value]), "Value", "Custom"),
#"Replaced Value" = Table.ReplaceValue(#"Pivoted Column",null,"No",Replacer.ReplaceValue,Table.ColumnNames(#"Pivoted Column"))
in
#"Replaced Value"
EDIT: Provoked by #AlexisOlson comment, I added a few lines of code to both alphabetize the symptom list, and also to prefix each symptom name with the string Symptoms - .
I also added numerous comments to the code, which you will also be able to see in the Applied Steps window.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Row ID", Int64.Type}, {"Symptoms", type text}}),
//Split the different symptoms into separate columns
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Symptoms", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv)),
//Unpivot other than "Row ID" so as to have all the symptoms in a single column
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Split Column by Delimiter", {"Row ID"}, "Attribute", "Value"),
//Remove the Attribute column
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
//Trim the symptoms column to get rid of any leading spaces that might be there
#"Trimmed Text" = Table.TransformColumns(#"Removed Columns",{{"Value", Text.Trim, type text}}),
//Sort symptoms alphabetically
#"Sorted Rows" = Table.Sort(#"Trimmed Text",{{"Value", Order.Ascending}}),
//Create a new column with the "Yes"'s
#"Added Custom" = Table.AddColumn(#"Sorted Rows", "Custom", each "Yes"),
//Pivot on the symptoms column to create new table with each symptom as a column header
#"Pivoted Column" = Table.Pivot(#"Added Custom", List.Distinct(#"Added Custom"[Value]), "Value", "Custom"),
#"Changed Type1" = Table.TransformColumnTypes(#"Pivoted Column",{{"Cough", type text}, {"Diarrhoea", type text}, {"Headache", type text}, {"Myalgia", type text}, {"Vomiting", type text}}),
//Replace the resultant nulls with "No"'s
#"Replaced Value" = Table.ReplaceValue(#"Changed Type1",null,"No",Replacer.ReplaceValue,Table.ColumnNames(#"Changed Type1")),
firstColName = Table.ColumnNames(#"Replaced Value"){0},
//Prefix each column header with "Symptoms - " except first
rename = Table.TransformColumnNames(#"Replaced Value", each if _ <> firstColName then "Symptoms - " & _ else _)
in
rename