How to independently sort multiple columns of this SEQUENCE output without effecting the positions of the columns and of the blanks?

Rnkhch

Well-known Member
Joined
Apr 28, 2018
Messages
578
Office Version
  1. 365
Platform
  1. Windows
Hello,

This question is related to my previous question below 😀:

I took Stephen's amazing solution and spiced it up to make my LAMBDA more feature-rich, and it works really well (below) :cool: :
Excel Formula:
=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,1,
   b,TOROW(counts),
   c,break,
   g,IF(ISOMITTED(step),1,step),
   m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))),
   d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1),
   i,d+(IF(ISOMITTED(start),0,start-1)),
   f,IF(sort,SORT(i,,sort,1),i),
   IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f))
)

So now in addition to just "counts" and "break", the "start" and "step" can also be specified along with a "sort" option which works with the standard SORT with "1" and "-1" as arguments. Also now the function takes a vertical input as well, such as {3;2;5}, and the result is vertical spill in a single column. And this all works really well, and the output is obviously linear.

But then I thought to spice up this formula even more :cool: and add a "stack" feature as well (where "stack" can be turned on/off) in order to output the multiple counts as multiple columns (or rows in the case of vertical input). This, of course, requires that the "d" variable be taken out of TOROW. But I was not able to get the sorting to work 🧠. I tried both 1) to play with SORT parameters and/or 2) to play with the SEQUENCE components of "d" to get the sorting to work for stacked output, but so far I've been unsuccessful 🧐. Here is the incomplete formula for the stacked version (I haven't coded the actual stacking mechanism yet):

Excel Formula:
=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,,
   b,TOROW(counts),
   c,break,
   g,IF(ISOMITTED(step),1,step),
   m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))),
   d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),
   i,d+(IF(ISOMITTED(start),0,start-1)),
   f,IFERROR(IF(sort,SORT(i,,sort,1),i),""),
   IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f))
)

I thought that the most reasonable sort for stack output would be to sort all columns independently, so the question is what's the best way to do this kind of sorting? I have also included some examples in the XL2BB below.

Thanks for any input 🤗

post.xlsx
ABCDEFGHIJKLMNOPQRST
1
2sort: omitted420-2-4753108131197
3sort: 1-4-2023457789101113
4sort: -1131110987754320-2-4
5
6sort:omittedsort:1(intended output)sort:-1(intended output)
7471013-4387471013
825811-2510925811
90390711039
10-27213-27
11-44-4
12
13
14sort: omittedsort: 1sort: -1sort:omitted
154-413420-2-4
162-211753
170010108
18-229131197
19-438
20747sort:1(intended output)
21557-4-2024
22375357
231074810
24883791113
251392
2611100sort:-1(intended output)
27911-2420-2-4
28713-4753
29108
30131197
31
32
33sort: omitted-5-3.75-1.98-0.211.56-2.5-0.731.04-1.250.522.294.065.837.601.77
34sort: 1-5-3.75-2.5-1.98-1.25-0.73-0.2100.521.041.561.772.294.065.837.6
35sort: -17.65.834.062.291.771.561.040.520-0.21-0.73-1.25-1.98-2.5-3.75-5
36
37sort:omittedsort:1(intended output)sort:-1(intended output)
38-5-3.75-2.5-1.250-5-3.75-2.5-1.250-51.561.047.61.77
39-1.98-0.730.521.77-1.98-0.730.521.77-0.21-0.735.830
40-0.211.042.29-0.211.042.29-1.98-2.54.06
411.564.061.564.06-3.752.29
425.835.830.52
437.67.6-1.25
44
45
46sort: omittedsort: 1sort: -1sort:omitted
47-5-57.6-5
48-3.75-3.755.83-3.75-1.98-0.211.56
49-1.98-2.54.06-2.5-0.731.04
50-0.21-1.982.29-1.250.522.294.065.837.6
511.56-1.251.7701.77
52-2.5-0.731.56
53-0.73-0.211.04sort:1(intended output)
541.0400.52-5
55-1.250.520-3.75-1.98-0.211.56
560.521.04-0.21-2.5-0.731.04
572.291.56-0.73-1.250.522.294.065.837.6
584.061.77-1.2501.77
595.832.29-1.98
607.64.06-2.5sort:-1(intended output)
6105.83-3.75-5
621.777.6-51.56-0.21-1.98-3.75
631.04-0.73-2.5
647.65.834.062.290.52-1.25
651.770
66
Sheet1
Cell Formulas
RangeFormula
C2:P2C2=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C3:P3C3=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C4:P4C4=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,-1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C7:F11,M7:P11C7=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)), i,d+(IF(ISOMITTED(start),0,start-1)), f,IFERROR(IF(sort,SORT(i,,sort,1),i),""), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C15:C28C15=LET(counts,{5;3;2;4},break,3,start,4,step,-2,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
D15:D28D15=LET(counts,{5;3;2;4},break,3,start,4,step,-2,sort,1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
E15:E28E15=LET(counts,{5;3;2;4},break,3,start,4,step,-2,sort,-1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
G15:K18G15=LET(counts,{5;3;2;4},break,3,start,4,step,-2,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)), i,d+(IF(ISOMITTED(start),0,start-1)), f,IFERROR(IF(sort,SORT(i,,sort,1),i),""), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C33:R33C33=LET(counts,{1,4,3,6,2},break,1.25,start,-5,step,1.77,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C34:R34C34=LET(counts,{1,4,3,6,2},break,1.25,start,-5,step,1.77,sort,1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C35:R35C35=LET(counts,{1,4,3,6,2},break,1.25,start,-5,step,1.77,sort,-1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C38:G43C38=LET(counts,{1,4,3,6,2},break,1.25,start,-5,step,1.77,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)), i,d+(IF(ISOMITTED(start),0,start-1)), f,IFERROR(IF(sort,SORT(i,,sort,1),i),""), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
C47:C62C47=LET(counts,{1;4;3;6;2},break,1.25,start,-5,step,1.77,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
D47:D62D47=LET(counts,{1;4;3;6;2},break,1.25,start,-5,step,1.77,sort,1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
E47:E62E47=LET(counts,{1;4;3;6;2},break,1.25,start,-5,step,1.77,sort,-1, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,TOROW(IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),2,1), i,d+(IF(ISOMITTED(start),0,start-1)), f,IF(sort,SORT(i,,sort,1),i), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
G47:L51G47=LET(counts,{1;4;3;6;2},break,1.25,start,-5,step,1.77,sort,, b,TOROW(counts), c,break, g,IF(ISOMITTED(step),1,step), m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))), d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)), i,d+(IF(ISOMITTED(start),0,start-1)), f,IFERROR(IF(sort,SORT(i,,sort,1),i),""), IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f)) )
Dynamic array formulas.
 

Excel Facts

Does the VLOOKUP table have to be sorted?
No! when you are using an exact match, the VLOOKUP table can be in any order. Best-selling items at the top is actually the best.
Try using SORTBY with TOCOL (and WRAPCOLS) to sort by column number, then by ISNA, then by value:

Excel Formula:
=LET(counts,{5,3,2,4},break,3,start,4,step,-2,sort,1,
   b,TOROW(counts),
   c,break,
   g,IF(ISOMITTED(step),1,step),
   m,SEQUENCE(MAX(b),,,ABS(IF(g,g,1))),
   d,IFS(m<=(b*ABS(IF(g,g,1))),IF(g<=0,SEQUENCE(MAX(b),,,g),m)+SEQUENCE(,COUNT(b),0,c)),
   i,d+(IF(ISOMITTED(start),0,start-1)),
   f,IFNA(IF(sort,WRAPCOLS(SORTBY(TOCOL(i),TOCOL(IF({1},SEQUENCE(,COLUMNS(i)),i)),1,TOCOL(ISNA(i)),1,TOCOL(i),sort),ROWS(i)),i),""),
   IF(COLUMNS(counts)>=ROWS(counts),f,TRANSPOSE(f))
)

Note: the only variable I changed from your original example was f.

Also, if you wanted to sort by row number instead, modify f as follows:

Excel Formula:
=LET(
   ...
   f,IFNA(IF(sort,WRAPROWS(SORTBY(TOCOL(i),TOCOL(IF({1},SEQUENCE(ROWS(i)),i)),1,TOCOL(ISNA(i)),1,TOCOL(i),sort),COLUMNS(i)),i),""),
   ...
)
 
Upvote 0
Solution
Another way to sort individual columns ....

ABCDEF
1counts5324
2start4
3break3
4step-2
5Sort1
6
7Output-4387
8-25109
90711
10213
114
12
Sheet1
Cell Formulas
RangeFormula
B1:E1B1={5,3,2,4}
B7:E11B7=LET(Counts,B1#,start,B2,break,B3,step,B4,sort,B5,c,COUNT(Counts),s,SEQUENCE(MAX(Counts),,0),d,IF(s<Counts,start+s*step+SEQUENCE(,c,0,break)),m,MAKEARRAY(ROWS(d),c,LAMBDA(a,b,INDEX(BYCOL(d,LAMBDA(c,CHOOSE(sort+2,LARGE(c,a),INDEX(c,a),SMALL(c,a)))), 1, b))),IF(ISNUMBER(m),m,""))
Dynamic array formulas.
 
Upvote 0
Awesome, thank you both 🤗

@djclements Amazing formula! And stays super fast and doesn't lose speed even on large inputs

@StephenCrump Also amazing formula, but slow on large inputs (which is probably due to MAKEARRAY/BYCOL). I used SEQUENCE(,150) for counts, and it already took about 30 seconds. But I'll check to see if I can bring some of the components into my formula while avoiding MAKEARRAY/BYCOL

So, I'll mark djclements' post as solution
 
Upvote 0
@djclements Supplemental question :biggrin:

I was playing with just the "f" part of your formula on other random arrays, and I figured that if the "TOCOL(ISNA(i))" portion of SORTBY is sorted with "1", it pushes the errors to the bottom of columns, and if it is sorted by "-1", it pushes the errors to the top of the columns :cool:, which are great options to have 🙏

How could I modify your formula 🧐 such that it would preserve the locations of errors where they occur in the input array columns (or rows)? 🙃
Excel Formula:
WRAPCOLS(SORTBY(TOCOL(i),TOCOL(IF({1},SEQUENCE(,COLUMNS(i)),i)),1,TOCOL(ISNA(i)),1,TOCOL(i),sort),ROWS(i))

post.xlsx
ABCDEFGHIJKLMNOP
1
2input arraysort: 1(intended output)sort: -1(intended output)
3-975-10-10-7-7-10101066
460#N/A4-9-6#N/A-1077#N/A4
5-810#N/A-7-80#N/A-766#N/A-5
60#N/A56-1#N/A-4-50#N/A5-7
7-102-7-50254-125-10
876#N/A-1066#N/A6-80#N/A-10
910-6-4#N/A775#N/A-9-6-4#N/A
10-1-76#N/A10106#N/A-10-7-7#N/A
11
Sheet2
Cell Formulas
RangeFormula
D4:D5,E9:E10,N8,I8,D8,M6,H6,C6,I4:I5D4=#N/A
 
Last edited:
Upvote 0
Not impossible, but a little more complicated, so I'll break it down step by step for the supplemental dataset:

Excel Formula:
=LET(
    i, B3:E10,
    o, 1,
    h, ROWS(i),
    w, COLUMNS(i),
    r, SEQUENCE(h),
    c, SEQUENCE(,w),
    e, ISERROR(i),
    t, NOT(e),
    v, TOCOL(i,2,1),
    b, TOCOL(IFS(t,c),2,1),
    s, SORTBY(
        EXPAND(SORTBY(v,b,1,v,o),h*w),
        VSTACK(b,TOCOL(IFS(e,c),2,1)),1,
        VSTACK(TOCOL(IFS(t,r),2,1),TOCOL(IFS(e,r),2,1)),1
    ),
    WRAPCOLS(s,h)
)

Note: set the optional [pad_with] argument of EXPAND to "" if desired.

Let me know if you have trouble incorporating this method into your original function example. Cheers!
 
Upvote 0
Another possibility:

Excel Formula:
=LET(
    i, B3:E10,
    o, 1,
    v, TOCOL(i),
    b, TOCOL(ISNA(i)),
    r, TOCOL(IF({1},SEQUENCE(ROWS(i)),i)),
    c, TOCOL(IF({1},SEQUENCE(,COLUMNS(i)),i)),
    WRAPCOLS(SORTBY(SORTBY(v,b,1,c,1,v,o),SORTBY(c,b,1,c,1),1,SORTBY(r,b,1,c,1,r,1),1),ROWS(i))
)

I didn't perform a speed test with a larger dataset to see which method is faster; however, this method will continue to work as expected in the event the dataset does NOT contain any #N/A errors, whereas the first method will return #CALC!.
 
Upvote 0
Amazing 😮 🐄 thanks much 🤗

Both are pretty fast with large datasets. I tested the first formula with "IF(SEQUENCE(64,16000)>500000,#N/A,2)" and it took about 2 seconds. The second formula with "IF(SEQUENCE(64,16000)>500000,#N/A,2)" or just "SEQUENCE(64,16000)" took about six seconds.
 
Upvote 0
Hi @djclements

For your post #6 formula, what would be the horizontal sorting version? 🙃

I tried a bunch of edits of your vertical formula, but couldn't get it just right. I'm almost done making the multi-column/row sorting LAMBDA :cool:

Thanks 🤗
 
Upvote 0
@Rnkhch To sort by row instead, simply swap the r & c variables in each of the TOCOL functions and remove the 1's from all of the [scan_by_column] arguments, then change the final output from WRAPCOLS(s,h) to WRAPROWS(s,w):

Excel Formula:
=LET(
    i, B3:E10,
    o, -1,
    h, ROWS(i),
    w, COLUMNS(i),
    r, SEQUENCE(h),
    c, SEQUENCE(,w),
    e, ISERROR(i),
    t, NOT(e),
    v, TOCOL(i,2),
    b, TOCOL(IFS(t,r),2),
    s, SORTBY(
        EXPAND(SORTBY(v,b,1,v,o),h*w),
        VSTACK(b,TOCOL(IFS(e,r),2)),1,
        VSTACK(TOCOL(IFS(t,c),2),TOCOL(IFS(e,c),2)),1
    ),
    WRAPROWS(s,w)
)
 
Upvote 0

Forum statistics

Threads
1,224,802
Messages
6,181,048
Members
453,014
Latest member
Chris258

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top