Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes! Register now.

Reply
Anonymous
Not applicable

Grouping values to total 100%

Hello PBI community. I have a project where I am trying to 'automate' a process. This involves me grouping numbers together that best/closest add up to 100%. I have one column that is 'Names', and another column that's 'Percent'. The groups can have 2-5 names, 2 names being the highest priority. I'd like the number of names in a group to be dynamic, but not a requirement. So, looking at the sample data below, pairing Name 989 and 1266 would give us 100.39%, then pairing the next 2 that would give us closest to 100%, if the group of 2 falls outside of 92%, group 3 together, if the groups of 3 fall outside of 92%, group 4 together and so on. I'd like for the results to be in a table format as below (not actual results, just example of table format). Please let me know if there are any questions, I greatly appreciate the help! 

 

I was able to do this in Excel. I tried groups in PBI but was not able to sum, and the DAX began to break as my code grew :D. 

 

NamesPercent
98964.20237809
135362.37515013
91159.79395868
53258.7573865
53158.66292337
134249.36307951
33148.59470334
502248.41214269
270648.23443334
30747.9356834
77747.47543057
40847.25912803
101646.04299651
40545.88115542
50545.53459044
116345.38728081
730145.36938506
90945.0906798
120644.64911122
282244.04510418
7544.03519097
293843.97736008
45743.20766274
2342.5981864
93542.36788374
53342.25756666
505640.77774442
91240.37328849
83940.29594043
45039.426135
96139.3512491
30939.29275763
328839.25165603
38639.20502042
120437.68868604
42837.62603878
386837.16898871
41537.12989431
54337.10032518
54236.8671631
17036.65121307
126636.19325006

 

Example Table Format:

GroupsTotal Percent
989, 1353100.56
911, 532102.35
531, 1342, 331102.56
4 REPLIES 4
lbendlin
Super User
Super User

There is a better pairing (1353,428) with 100.0011889 %.  So I would propose an approach that finds the best pairing, removes it from the list and then repeats the process until the threshold is hit (8% delta, from 92% to 108%). Then try the same with triples etc.

Anonymous
Not applicable

How would you approach the best pairing then removing from the list?

Here is the first iteration:

 

Table:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("NZNLjgQxCEPvUutWBJjvWVpz/2sMKehaPhHHMa7v96ms5/O4HiFBJNXz9/k+DMPFchDGRowXF3NTqxOFsvR8qUEuzRMWSLeFPNBdSoBYXb2zWgcOijJ+Md5hzWOlQYCOBIkMVhZW8fEmQT5YoIrfdMtdGqdgngsjFmqYgmxcKOVQsWJJmscx8avrh1SqfL0p2aV2MpnN2v94W2pQK9K5jtkxGBktnCMRIF7shbT2/6ZJNZSKPGrCZJnX6XHtuFnmPsnJQtucMSnPdNhCGLfcPE/6jotxKgJONLNqMVQoeikxluU1LJ18cvqwTnAgPDKxk4YdFQvz/n5BvH7pdNahuvl0rkMRkEyd1SVqqFRvmhRrjJqiTq+4izfnnYf1w6SD2BXXwG5Ud83n+NVfbOzmu85u4lLqItH66nj14jie3V+neZtKLpU+n5E/icXsWZmxjWBbKv33KIZ2v5YSoZ3sv/H2HX7So8sxoxw0sDsmfIs71twHc7UA3Zb8/QM=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Names = _t, Percent = _t]),
    #"Added Custom1" = Table.AddColumn(Source, "Paired", each null,type text),
    #"Added Custom" = Table.AddColumn(#"Added Custom1", "Sum", each null,type number),
    #"Changed Type" = Table.TransformColumnTypes(#"Added Custom",{{"Percent", type number}}),
    Pass = List.Accumulate({0..20},#"Changed Type",(state,current)=> TwoStep(state))
in
    Pass 

 

(the "20"  should ideally be replaced by half the size of the list)

 

TwoStep:

 

(tbl)=>
let 
    t=Table.Buffer(tbl),
    #"Invoked Custom Function" = Table.AddColumn(t, "Twos", each Twos(Table.SelectRows(t,each [Paired]=null))),
    #"Replaced Value" = Table.ReplaceValue(#"Invoked Custom Function",each [Paired],each 
//if [Twos]{0}[Names]=[Twos]{0}[Pair] then [Paired] else 
if [Names]=[Twos]{0}[Names] then [Twos]{0}[Pair] else
if [Names]=[Twos]{0}[Pair] then [Twos]{0}[Names] else
 [Paired],Replacer.ReplaceValue,{"Paired"}),
    #"Replaced Value1" = Table.ReplaceValue(#"Replaced Value",each [Sum],each if [Names]=[Twos]{0}[Names] or [Names]=[Twos]{0}[Pair] then [Twos]{0}[Percent]+[Twos]{0}[Percent.1] else [Sum],Replacer.ReplaceValue,{"Sum"}),
    #"Removed Other Columns" = Table.SelectColumns(#"Replaced Value1",{"Names", "Percent", "Paired", "Sum"})
in
    #"Removed Other Columns"

 

Twos:

 

(tbl)=>
let
    #"Added Custom1" = Table.AddColumn(tbl, "Match", (k)=> Table.SelectRows(tbl,each [Names]<>k[Names])),
    #"Expanded Match" = Table.ExpandTableColumn(#"Added Custom1", "Match", {"Names", "Percent"}, {"Pair", "Percent.1"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Match", "Diff", each Number.Abs(100-[Percent]-[Percent.1]),type number),
    #"Sorted Rows" = Table.Sort(#"Added Custom",{{"Diff", Order.Ascending}}),
    #"Kept First Rows" = Table.FirstN(#"Sorted Rows",1)
in
    #"Kept First Rows"

 

 

As you can see from the result some of the mappings are below the threshold. Those would then be candidates for the next step - testing the triples.

 

lbendlin_0-1680726251002.png

 

I also have to check why the "above 100"  matches are so underrepresented.

Looking at the rest of the data - there is no chance for any of the remaining values to group in triplets without exceeding the 8% threshold.

 

lbendlin_1-1680727105796.png

 

So you would have to play with different matching strategies. For example match the high end (108%) first, or change the threshold, or whatever other criteria is meaningful for your situation.

Helpful resources

Announcements
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

September Power BI Update Carousel

Power BI Monthly Update - September 2025

Check out the September 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Solution Authors
Top Kudoed Authors