Home > OS >  Dense Ranks filtered Data OR Groups in Powerquery, Using A custom function
Dense Ranks filtered Data OR Groups in Powerquery, Using A custom function

Time:09-15

I have been trying the easiest method to dense rank the following data for data having groups or category. I have ask similiar question for ranking a data, but this one is for data with grouping.

I wish to rank the scores column as shown below, such that the highest number take 1st position=1st. The second largest number takes the second position etc. Where there are ties, give them same ranking order. say score=200 of ID=3002, ID=3010 occurring twice is placed 1st for the class SS3. So in this case the scorers will have the same ranking => Dense Ranking. same thing goes for all the classes.

The Class represent group of formations. Each individual, would be graded per each class. All methods have google, seems cumbersome and somehow takes more of powerquery memory space. However, thanks to someone in this platform, that gave a good and quick way of solving it. He supplied the following custom function to handle this case as discussed in this trend:How To Effectively Dense Rank Groups in a Table Using Powerquery i discovered that in his function, some column values are hardcoded.So if i got several column values,i will need to manually add them.How do handle this problem effectively?

Scores ID Class Arabic Maths Rank
130 1002 SS1 30 100
180 2003 SS2 100 80
140 1006 SS1 90 50
130 1007 SS1 80 50
200 3002 SS3 100 100
200 3010 SS3 100 100
70 3010 SS3 50 20

Expected results

Scores ID Class Arabic Maths Rank
130 1002 SS1 30 100 2nd
180 2003 SS2 100 80 1st
140 1006 SS1 90 50 1st
130 1007 SS1 80 50 2nd
200 3002 SS3 100 100 1st
200 3010 SS3 100 100 1st
70 3010 SS3 50 20 3rd

CodePudding user response:

How about this which ranks the Scores column after grouping on Class, working for any number of columns

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type), //optional
#"Grouped Rows" = Table.Group(#"Added Index", {"Class"}, {{"data", each  rank(_,"Scores","Rank"), type table }}),
ColumnsToExpand = List.Difference(List.Distinct(List.Combine(List.Transform(Table.Column(#"Grouped Rows", "data"), each if _ is table then Table.ColumnNames(_) else {}))),{"Class"}),
DynamicExpanded = Table.ExpandTableColumn(#"Grouped Rows", "data",ColumnsToExpand ,ColumnsToExpand ),
#"Sorted Rows" = Table.Sort(DynamicExpanded,{{"Index", Order.Ascending}}),  // optional
#"Removed Columns" = Table.RemoveColumns(#"Sorted Rows",{"Index"})  // optional
in  #"Removed Columns"

using this function, named rank

(Source as table, RankColumnName as text, optional OutputName as nullable text) =>
let #"Added Index" = Table.AddIndexColumn(Source, "RankIndex", 0, 1, Int64.Type),
#"Grouped Rows" = Table.Group(#"Added Index", RankColumnName, {{"data", each _, type table}}),
#"Sorted Rows" = Table.Sort(#"Grouped Rows",{{RankColumnName, Order.Descending}}),
#"Added Index1" = Table.AddIndexColumn(#"Sorted Rows", if OutputName=null or OutputName="" then"Rank" else OutputName, 1, 1, Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Added Index1",RankColumnName),
#"Expanded data" = Table.ExpandTableColumn(#"Removed Columns", "data", Table.ColumnNames(#"Added Index"), Table.ColumnNames(#"Added Index")), 
#"Sorted Rows2" = Table.Buffer(Table.Sort(#"Expanded data",{{"RankIndex", Order.Ascending}})), // optional
#"Removed Columns1" = Table.RemoveColumns(#"Sorted Rows2",{"RankIndex"})
in #"Removed Columns1" 
  • Related