I have a query function :
let ID = () =>
let
Source = Json.Document(Web.Contents("www.example.com")),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
#"Converted to Table"
in ID
that outputs a table.
What I'm trying to do is add a column from that table I'm outputting to my main query table.
My problem :
I don't know how to add a column without having to define a function that will apply to each row (as in "Add a Custom Column), and insted just add a premade column.
The solution I came up with :
Add an index column to my main query table and then using the "Costum Column" functionnality to call the Nth row of my ID column as such :
let
Source = ID(),
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each ID()[Column1]{[Index]})
in
#"Added Custom"
My question :
Isn't there just an existing function that will allow me to do this :
Table.AddPremadeColumn(#"Added Index", "Custom", ID()[Column1])
You can convert the table to columns (i.e. a list of lists), concatenate {ID[Column1]} and convert the result back to a table:
= Table.FromColumns(Table.ToColumns(#"Added Index")&{ID[Column1]})
Related
In a power bi table, I have two columns named: name and value. The name has 3 types: "diameter", "radius", "length". Right now the names are laid out in rows but i would like to have them in separate columns of their own aligned with the item. So I would like to add a column, say diameter, and append the value of the value column to this new column if the value, in the same row, in the name column is "diameter". How would i dothat? Right now I have something like this which is obviously not working:
= Table.AddColumn(#"Filtered Rows5", "Diameter", each if [name] = "Diamter" then [#"[value].Cell.Data.Element: Text"] else "" )
Basically, I would like to transform the table from
to
In powerquery
Add column .. custom column... name diameter
= if [Name] = "diameter" then [Value] else null
Add column .. custom column... name radius
= if [Name] = "radius" then [Value] else null
Add column .. custom column... name length
= if [Name] = "length" then [Value] else null
sample code:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "diameter", each if [Name] = "radius" then [Value] else null),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "radius", each if [Name]="radius" then [Value] else null),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "length", each if [Name]="length" then [Value] else null)
in #"Added Custom2"
Alternate method
Right click and duplicate the Name Column
Add column index column
Click select the new column
Transform .. pivot column and choose Value as the values column
Resort on the index column and remove it
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
#"Duplicated Column" = Table.DuplicateColumn(#"Added Index", "Name", "Name - Copy"),
#"Pivoted Column" = Table.Pivot(#"Duplicated Column", List.Distinct(#"Duplicated Column"[#"Name - Copy"]), "Name - Copy", "Value", List.Sum),
#"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Index", Order.Ascending}}),
#"Removed Columns" = Table.RemoveColumns(#"Sorted Rows",{"Index"})
in #"Removed Columns"
benefit: works for any number of unique rows that convert to columns
I am looking to add a conditional column in power query by looking up data from another table.
As an example, my lookup data is as follows:
My data is as follows:
Now I want to check if the number in my data is between Begin & End of my Master data & if the condition is satisfied, then I want to add a column by coping the corresponding "Digits" Cell to my Data. The result should look like this:
Can someone point me on how to do this?
Any help is greatly appreciated.
Thanks in Advance
Load your your top table into powerquery with the query name LookupQuery and file ... close and load. It should have the column names you show
Then load the middle source table into powerquery and Add column ... custom column... with formula
= Table.SelectRows(LookupQuery,(x) => [Data] >= x[Begin] and [Data] <=x[End] )[Digits]{0}
full code:
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Data", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each Table.SelectRows(LookupQuery,(x) => [Data] >= x[Begin] and [Data] <=x[End] )[Digits]{0})
in #"Added Custom"
another way is to do a match based on length of the digits. This would work better for large data sets Load your middle source data into powerquery and
add column ... custom column ... with formula
= Text.Length(Text.From([Data]))
merge your data with with lookup query and replace the formula in the formula bar with :
= Table.NestedJoin(#"Added Custom", {"Custom"}, Table.AddColumn(LookupQuery, "Custom", each Text.Length(Text.From([Begin]))), {"Custom"}, "LookupQuery", JoinKind.LeftOuter)
expand the Digits column
full code for the 2nd method:
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Data", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each Text.Length(Text.From([Data]))),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Custom"}, Table.AddColumn(LookupQuery, "Custom", each Text.Length(Text.From([Begin]))), {"Custom"}, "LookupQuery", JoinKind.LeftOuter),
#"Expanded LookupQuery" = Table.ExpandTableColumn(#"Merged Queries", "LookupQuery", {"Digits"}, {"Digits"})
in #"Expanded LookupQuery"
im using a certain config of tables to generate a cascading dropdown list that looks as such:
I wanna merge these tables to look as such using excels powerquery:
Since each dropdown list is a different table, you have to create a list of all the tables.
Creating a list of tables for PQ to operate on can be tricky.
In my example, they were named Table19 - Table26 so I used the List.Generate function to do that. But there are other ways to generate such a list, including just hard-coding it.
Then it's just a matter of reading in all the tables, unpivoting and expanding.
See the comments in the code for better understanding.
M Code
let
//create a list of the relevant table names
// and create a column of the names
//many ways to do this
//Since mine are table19-26, I do it like this:
tableNames = List.Generate(
()=>[Table Name = "Table" & "19", IDX=20],
each [IDX] < 28,
each [Table Name = "Table" & Text.From([IDX]), IDX = [IDX]+1],
each [Table Name]
),
#"Converted to Table" = Table.FromList(tableNames, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
//Add custom column containing the actual table referred to in column1
//then delete the table names column
#"Added Custom" = Table.AddColumn(#"Converted to Table", "Tables", each Excel.CurrentWorkbook(){[Name=[Column1]]}[Content]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Column1"}),
//add custom column to unpivot each of the tables
//then remove the original tables column and expand the unpivoted column
#"Added Custom1" = Table.AddColumn(#"Removed Columns", "unPivot", each
Table.UnpivotOtherColumns([Tables],{},"Type","Subtype")),
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom1",{"Tables"}),
#"Expanded unPivot" = Table.ExpandTableColumn(#"Removed Columns1", "unPivot", {"Type", "Subtype"}, {"Type", "Subtype"})
in
#"Expanded unPivot"
I'm importing a bunch of columns to do some analysis on in Excel power query. Some of the analysis columns need to be inserted after a certain column, but every option for adding a column only lets me append the column to the very end. I want to insert the new columns after the one named "Total" for readability.
Bellow a function than outputs the list of re-arranged column names.
ReorderList:
(tableName as table, toBeMovedColumnName as any, optional afterColumnName as text) as list=>
//tableName - the name of the table we want to reorder.
//toBeMovedColumnName - the name of the column you want to change the position. Can be a list of column names.
//columnName - the name of the column you want the toBeMovedColumnName to be positioned after. If omited toBeMovedColumnName will be placed as the first column.
let
columnNames = Table.ColumnNames(tableName),
positionOf = if afterColumnName is null or afterColumnName = "" then 0 else List.PositionOf(columnNames, afterColumnName) + 1,
toBeMovedList = if Value.Is(toBeMovedColumnName, type list) = true then toBeMovedColumnName else {toBeMovedColumnName},
intermediaryList = List.Combine({List.FirstN(columnNames,positionOf),toBeMovedList}),
intermediaryList2 = List.RemoveItems(columnNames,intermediaryList),
reorderList = List.Combine({intermediaryList,intermediaryList2})
in
reorderList
Usage like this:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom1", each 4),
#"Reordered Columns" = Table.ReorderColumns(#"Added Custom", ReorderList(#"Added Custom","Custom1","Total"))
in
#"Reordered Columns"
Sample below.
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
// get baseline column names. Use this before inserting new analysis columns
Names = Table.ColumnNames(Source),
TotalSpot = List.PositionOf(Names,"Total"),
// add any code or steps here ; this is random sample. don't use
#"Added Custom" = Table.AddColumn(Source, "Custom1", each 4),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom2", each 5),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom3", each 6),
// insert this after all your new columns are added
// it moves all new columns to the right of the Total column
// replace #"Added Custom2" in step below with previous step name
#"Reordered Columns" = Table.ReorderColumns(#"Added Custom2",List.Combine ({List.FirstN(Names,TotalSpot+1),List.RemoveItems(Table.ColumnNames(#"Added Custom2"),Names),List.RemoveFirstN (Names,TotalSpot+1)}))
in #"Reordered Columns"
Maybe this is a very simple question, but I'm trying to figure out how to do this, as I have hundreds of columns and the idea of doing it by hand, splitting them into separate queries and then append them doesn't seem to be very practical.
I've been working on a query and it returns me values in the following format:
Date | Time | Value | Time | Value...
A | B | C | D | E...
But I need to transform it to look like:
Date | Time | Value
A | B | C
A | D | E
Thanks for the help!
Using no custom code:
Load data into powerquery using Data ... From Table/Range...
Right-click Date column, choose unpivot other columns
Add column... index column... use default column name Index
Add column...Custom Column... with formula =Number.Mod([Index],2) and default name Custom
This converts the index column into alternating 0/1s
(Assuming your 2nd column is named Value.1) Add column...Custom Column... with formula =#"Added Custom"{[Index]+1}[Value.1] and default name Custom.1
That will place the value from the row below the current one into current row
Remove alternating row by clicking arrow next to Custom column and removing [x] next the the 1
Click-Select the Attribute, Index and Custom columns, right-click Remove Columns
Load and Close
Assuming your data is loaded as range Table1 you could use this code, pasted into Home...Advanced...
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Date"}, "Attribute", "Value.1"),
#"Added Index" = Table.AddIndexColumn(#"Unpivoted Other Columns", "Index", 0, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each Number.Mod([Index],2)),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each #"Added Custom"{[Index]+1}[Value.1]),
#"Filtered Rows" = Table.SelectRows(#"Added Custom1", each ([Custom] = 0)),
#"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"Attribute", "Index", "Custom"})
in #"Removed Columns"
If you are willing to use some custom code, this creates two tables, one table with odd columns and one with even columns, unpivots each of them, adds an index to both, then merges them back on that index. Works for any number of columns, might be faster than above for larger data sets.
Assuming your data is loaded as range Table1 you could use this code, pasted into Home...Advanced...
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
OddUnpivot= Table.AddIndexColumn(Table.UnpivotOtherColumns(Table.RemoveColumns(Source,List.RemoveFirstN(List.Alternate(Table.ColumnNames(Source),1,1,1),1)), {"date"}, "Attribute", "Value"), "Index", 0, 1),
EvenUnpivot= Table.AddIndexColumn(Table.UnpivotOtherColumns(Table.RemoveColumns(Source,List.Alternate(Table.ColumnNames(Source),1,1)), {"date"}, "Attribute", "Value"), "Index", 0, 1),
#"Merged Queries" = Table.NestedJoin(OddUnpivot,{"Index"},EvenUnpivot,{"Index"},"Table2",JoinKind.LeftOuter),
#"Expanded Table" = Table.ExpandTableColumn(#"Merged Queries", "Table2", {"Value"}, {"Value.1"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Table",{"Attribute", "Index"})
in #"Removed Columns"
LATER UPDATE:
More generically, I've decided I like this method better
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
// 1 base columns, then groups of 2 columns, stack them
Combo = List.Transform(List.Split(List.Skip(Table.ColumnNames(Source),1),2), each List.FirstN(Table.ColumnNames(Source),1) & _),
#"Added Custom" =List.Accumulate(
Combo,
#table({"Column1"}, {}),
(state,current)=> state & Table.Skip(Table.DemoteHeaders(Table.SelectColumns(Source, current)),1)
)
in #"Added Custom"