Stacking pairs of columns in Excel with PowerQuery - excel

I have a table generated in power query that is currently in the following format
A
Key1
Value1
Key2
Value2
A1
B1
C1
D1
E1
I want
A
Key
Value
A1
B1
C1
A1
D1
E1
How can this be achieved in power query?

Answer from Peter works, or to make it more generic:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
base=1, // # leading columns that will repeat
group=2, // followed by groups of 2 columns
Combo = List.Transform(List.Split(List.Skip(Table.ColumnNames(Source),base),group), each List.FirstN(Table.ColumnNames(Source),base) & _),
#"Added Custom" =List.Accumulate(
Combo,
#table({"Column1"}, {}),
(state,current)=> state & Table.Skip(Table.DemoteHeaders(Table.SelectColumns(Source, current)),1)
)
in #"Added Custom"

Reference the original table, remove columns 4 and 5 and rename the remaining columns to A, Key and Value.
Reference the original table again, remove columns 2 and 3 and rename the remaining columns to A, Key and Value.
Append the 2 above queries

Related

Group values in one column and list in row the values of other column [duplicate]

With data such as this:
Column A Column B
1 98
1 12
1 21
1 31
2 37
2 40
3 48
4 34
4 88
4 74
4 99
7 82
7 19
7 29
7 50
7 95
7 85
where all values in Column B are unique, and Column A has multiple duplicates. How can I group the A values in one column, and display concatenated values of B in another, like this:
Column C Column D
1 98,12,21,31
2 37,40
3 48
4 34,88,74,99
7 82,19,29,50,95,85
I've tried with a combination of concatenate and index and match, but it all just turns into a mess.
Any suggestions would be great?
Let me add two additional methods to the answer by #Harun24HR. Both options assume you don't have headers as per your sample data.
Option 1) : Dynamic Array Functions
When one has access to dynamic array functions you may use the following:
In C1:
=UNIQUE(A1:A17)
This UNIQUE function will spill an array of unique values from defined range into column C.
In D1:
=TEXTJOIN(",",TRUE,FILTER(B$1:B$17,A$1:A$17=C1))
Whereas FILTER will extract all values from column B where column A matches it is TEXTJOIN that will concatenate these values into your desired string.
Drag down...
Or, in a single go, exploiting TOCOL():
=LET(x,UNIQUE(TOCOL(A:A,1)),HSTACK(x,MAP(x,LAMBDA(y,TEXTJOIN(",",,FILTER(B:B,A:A=y))))))
Option 2) : PowerQuery
Would you want to experiment with PowerQuery/GetAndTransform then you don't need any formulas nor VBA for that matter. Follow these steps:
Select A1:B17 and from the ribbon choose Data > From Table/Range under "Get & Transform Data"
Choose to import data without headers. A new window will open.
From the ribbon click Transform > Group By. Within that menu choose to group by Column1, choose a new column name, e.g.: "Grouped" and then choose All Rows from the Operation dropdown and click OK.
You'll notice an extra column. Now on the ribbon click Add Column > Custom Column and enter the following formula: Table.Column([Grouped], "Column2"). This should add a third column that holds a list of values.
Remove Grouped from the table. Then click on the icon to the right of the newly added column name, and you'll have two options. Choose Extract Values, then choose a comma as your delimiter.
There might be a translation-error in the M-code below, but this should be it:
let
Source = Excel.CurrentWorkbook(){[Name="Tabel1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", Int64.Type}, {"Column2", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Column1"}, {{"Grouped", each _, type table [Column1=number, Column2=number]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each Table.Column([Grouped], "Column2")),
#"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
#"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"Grouped"})
in
#"Removed Columns"
PowerQuery is available from Excel-2010 if I'm not mistaken so you wouldn't need access to advanced formulas like TEXTJOIN to perform this.
First, you need to extract unique value from Column A to Column C. You can do it by using Advance Filter method or you can use below formula.
=IFERROR(INDEX($A$2:$A$18,MATCH(0,INDEX(COUNTIF($C$1:C1,$A$2:$A$18),0,0),0)),"")
After extracting unique values you have to use TEXTJOIN() formula to aggregate values from Column B to Column D. You have TEXTJOIN() formula in your excel version then you can use it like below
=TEXTJOIN(", ",TRUE,IF($A$2:$A$18=C2,$B$2:$B$18,""))
Otherwise you have to user VBA custom function to write TextJoin() formula. For TEXTJOIN() custom function you can have look to this post. Post Link

Removing Columns based on a list of index numbers -Power Query

I have a table, and I have a list of indexes.
Lets say the table is
Column A
Column B
Column C
Column D
Cell 1
Cell 2
And the list is MyList={1,2}
Based on the list, which is the index of the Columns that needs to be removed, I would like to get a new table that consists of Column 0 and 3 which would be
Column A
Column D
Cell 1
Cell 2
Of course in the actual scenario, the table sizes are dynamic, and the list is generated automatically. I need the M code for removing the columns based on the indexes in a list.
I am actually trying to remove the columns in the table where the values are the same. I have gotten so far to retrieving a list of indexes of the columns that need to be removed, and I would appreciate a help in pointing me in the right direction from here.
To remove columns based on array of column numbers
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
MyList={1,2},
x = Table.RemoveColumns(Source,List.Transform(MyList, each Table.ColumnNames(Source){_}))
in x
To remove columns where contents of rows in that column are identical
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {}, "Attribute", "Value"),
#"Grouped Rows" = Table.Group(#"Unpivoted Columns", {"Attribute"}, {{"Test", each if List.Count(List.Distinct([Value]))=1 then true else false}}),
x = Table.RemoveColumns(Source,Table.SelectRows(#"Grouped Rows", each ([Test] = true))[Attribute])
in x
From what I understand from your question, you are trying to remove columns in the table where the values ​​are the same. I hope it was a correct answer.
https://support.microsoft.com/en-us/office/remove-columns-power-query-5c4b5906-84ea-467b-8a80-4edf2c4140cc#:~:text=To%20remove%20a%20single%20column,can%20be%20contiguous%20or%20discontiguous.

Creating multiple columns for different values in 1 single row [duplicate]

With data such as this:
Column A Column B
1 98
1 12
1 21
1 31
2 37
2 40
3 48
4 34
4 88
4 74
4 99
7 82
7 19
7 29
7 50
7 95
7 85
where all values in Column B are unique, and Column A has multiple duplicates. How can I group the A values in one column, and display concatenated values of B in another, like this:
Column C Column D
1 98,12,21,31
2 37,40
3 48
4 34,88,74,99
7 82,19,29,50,95,85
I've tried with a combination of concatenate and index and match, but it all just turns into a mess.
Any suggestions would be great?
Let me add two additional methods to the answer by #Harun24HR. Both options assume you don't have headers as per your sample data.
Option 1) : Dynamic Array Functions
When one has access to dynamic array functions you may use the following:
In C1:
=UNIQUE(A1:A17)
This UNIQUE function will spill an array of unique values from defined range into column C.
In D1:
=TEXTJOIN(",",TRUE,FILTER(B$1:B$17,A$1:A$17=C1))
Whereas FILTER will extract all values from column B where column A matches it is TEXTJOIN that will concatenate these values into your desired string.
Drag down...
Or, in a single go, exploiting TOCOL():
=LET(x,UNIQUE(TOCOL(A:A,1)),HSTACK(x,MAP(x,LAMBDA(y,TEXTJOIN(",",,FILTER(B:B,A:A=y))))))
Option 2) : PowerQuery
Would you want to experiment with PowerQuery/GetAndTransform then you don't need any formulas nor VBA for that matter. Follow these steps:
Select A1:B17 and from the ribbon choose Data > From Table/Range under "Get & Transform Data"
Choose to import data without headers. A new window will open.
From the ribbon click Transform > Group By. Within that menu choose to group by Column1, choose a new column name, e.g.: "Grouped" and then choose All Rows from the Operation dropdown and click OK.
You'll notice an extra column. Now on the ribbon click Add Column > Custom Column and enter the following formula: Table.Column([Grouped], "Column2"). This should add a third column that holds a list of values.
Remove Grouped from the table. Then click on the icon to the right of the newly added column name, and you'll have two options. Choose Extract Values, then choose a comma as your delimiter.
There might be a translation-error in the M-code below, but this should be it:
let
Source = Excel.CurrentWorkbook(){[Name="Tabel1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", Int64.Type}, {"Column2", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Column1"}, {{"Grouped", each _, type table [Column1=number, Column2=number]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each Table.Column([Grouped], "Column2")),
#"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
#"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"Grouped"})
in
#"Removed Columns"
PowerQuery is available from Excel-2010 if I'm not mistaken so you wouldn't need access to advanced formulas like TEXTJOIN to perform this.
First, you need to extract unique value from Column A to Column C. You can do it by using Advance Filter method or you can use below formula.
=IFERROR(INDEX($A$2:$A$18,MATCH(0,INDEX(COUNTIF($C$1:C1,$A$2:$A$18),0,0),0)),"")
After extracting unique values you have to use TEXTJOIN() formula to aggregate values from Column B to Column D. You have TEXTJOIN() formula in your excel version then you can use it like below
=TEXTJOIN(", ",TRUE,IF($A$2:$A$18=C2,$B$2:$B$18,""))
Otherwise you have to user VBA custom function to write TextJoin() formula. For TEXTJOIN() custom function you can have look to this post. Post Link

Excel: How to gather unique values in one column that are associated with duplicates in another column?

With data such as this:
Column A Column B
1 98
1 12
1 21
1 31
2 37
2 40
3 48
4 34
4 88
4 74
4 99
7 82
7 19
7 29
7 50
7 95
7 85
where all values in Column B are unique, and Column A has multiple duplicates. How can I group the A values in one column, and display concatenated values of B in another, like this:
Column C Column D
1 98,12,21,31
2 37,40
3 48
4 34,88,74,99
7 82,19,29,50,95,85
I've tried with a combination of concatenate and index and match, but it all just turns into a mess.
Any suggestions would be great?
Let me add two additional methods to the answer by #Harun24HR. Both options assume you don't have headers as per your sample data.
Option 1) : Dynamic Array Functions
When one has access to dynamic array functions you may use the following:
In C1:
=UNIQUE(A1:A17)
This UNIQUE function will spill an array of unique values from defined range into column C.
In D1:
=TEXTJOIN(",",TRUE,FILTER(B$1:B$17,A$1:A$17=C1))
Whereas FILTER will extract all values from column B where column A matches it is TEXTJOIN that will concatenate these values into your desired string.
Drag down...
Or, in a single go, exploiting TOCOL():
=LET(x,UNIQUE(TOCOL(A:A,1)),HSTACK(x,MAP(x,LAMBDA(y,TEXTJOIN(",",,FILTER(B:B,A:A=y))))))
Option 2) : PowerQuery
Would you want to experiment with PowerQuery/GetAndTransform then you don't need any formulas nor VBA for that matter. Follow these steps:
Select A1:B17 and from the ribbon choose Data > From Table/Range under "Get & Transform Data"
Choose to import data without headers. A new window will open.
From the ribbon click Transform > Group By. Within that menu choose to group by Column1, choose a new column name, e.g.: "Grouped" and then choose All Rows from the Operation dropdown and click OK.
You'll notice an extra column. Now on the ribbon click Add Column > Custom Column and enter the following formula: Table.Column([Grouped], "Column2"). This should add a third column that holds a list of values.
Remove Grouped from the table. Then click on the icon to the right of the newly added column name, and you'll have two options. Choose Extract Values, then choose a comma as your delimiter.
There might be a translation-error in the M-code below, but this should be it:
let
Source = Excel.CurrentWorkbook(){[Name="Tabel1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", Int64.Type}, {"Column2", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Column1"}, {{"Grouped", each _, type table [Column1=number, Column2=number]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each Table.Column([Grouped], "Column2")),
#"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
#"Removed Columns" = Table.RemoveColumns(#"Extracted Values",{"Grouped"})
in
#"Removed Columns"
PowerQuery is available from Excel-2010 if I'm not mistaken so you wouldn't need access to advanced formulas like TEXTJOIN to perform this.
First, you need to extract unique value from Column A to Column C. You can do it by using Advance Filter method or you can use below formula.
=IFERROR(INDEX($A$2:$A$18,MATCH(0,INDEX(COUNTIF($C$1:C1,$A$2:$A$18),0,0),0)),"")
After extracting unique values you have to use TEXTJOIN() formula to aggregate values from Column B to Column D. You have TEXTJOIN() formula in your excel version then you can use it like below
=TEXTJOIN(", ",TRUE,IF($A$2:$A$18=C2,$B$2:$B$18,""))
Otherwise you have to user VBA custom function to write TextJoin() formula. For TEXTJOIN() custom function you can have look to this post. Post Link

Remove all Rows with more than 2 Numbers in it

I want to remove all the rows that contain more than 2 numerical numbers in the A column.
If the value in the A column contains more than 2 numerical numbers in it, then I want to remove it.
Can some one help me with this?
UPDATE
A b C D
12tech
1pics
google9
panda555
jer9gf666
9tom
I want to remove the 1st, 4th,5th rows in the example, because each of those contain more than 2 numbers.
Assuming row 1 is a header row and your actual data starts in row 2, put this formula in cell B2 and copy down:
=SUM(LEN(A2)-LEN(SUBSTITUTE(A2,{1,2,3,4,5,6,7,8,9,0},"")))>1
Then filter on column B for TRUE, delete those rows, and remove the filter
There is no pure-formula way to delete the rows (you can write a VBA macro using regular expressions, but since you didn't say to use macros I'll avoid them), but here is one procedure to find and delete the rows:
1) let B1 be the following formula:
= MIN(
IFERROR(FIND("0",A1),999999),
IFERROR(FIND("1",A1),999999),
IFERROR(FIND("2",A1),999999),
IFERROR(FIND("3",A1),999999),
IFERROR(FIND("4",A1),999999),
IFERROR(FIND("5",A1),999999),
IFERROR(FIND("6",A1),999999),
IFERROR(FIND("7",A1),999999),
IFERROR(FIND("8",A1),999999),
IFERROR(FIND("9",A1),999999)
)
2) fill down column B
3) let C1 be the formula
= MIN(
IFERROR(FIND("0",A1,B1+1),999999),
IFERROR(FIND("1",A1,B1+1),999999),
IFERROR(FIND("2",A1,B1+1),999999),
IFERROR(FIND("3",A1,B1+1),999999),
IFERROR(FIND("4",A1,B1+1),999999),
IFERROR(FIND("5",A1,B1+1),999999),
IFERROR(FIND("6",A1,B1+1),999999),
IFERROR(FIND("7",A1,B1+1),999999),
IFERROR(FIND("8",A1,B1+1),999999),
IFERROR(FIND("9",A1,B1+1),999999)
)
4) fill down column C
5) let D1 be the formula
=C1<999999
6) fill down column D
7) insert a row above the top data row, and set the new A1 = "name" and D1 = "filter"
8) let F1="filter" and F2=TRUE
9) select table (A2:D...), right click, advanced filter
10) set the Criteria range to be F1:F2 and hit OK

Resources