Creating a Dynamic Array from sparse but regular data - excel

My data is regular but sparse. As an example, imagine 3 data points in A4, A14 and A24 ("a","b" and "c" respectively). I want to pull these into a table. I need it to be able to adapt to more data points (so there might be 20, might be 2, but always 10 rows apart starting in A4).
Currently, I'm handling this by using an index column (say B1:B3 with the array formula SEQUENCE(COUNTA(A:A),1,1,1), and then next to that having:
INDIRECT("R"&4+(B1-1)*10&"C1",FALSE)
but I have to drag this formula down, and I want it to update dynamically, the way the index column would.
I wanted to make this into a dynamic array by adapting the formula to:
INDIRECT("R"&4+(B1:B3-1)*10&"C1",FALSE)
or
INDIRECT("R"&4+(SEQUENCE(COUNTA(A:A),1,0,1)*10&"C1",FALSE)
It spills correctly, but both of these return arrays of #VALUE! errors instead of the expected {a,b,c}. Why would this be? Have you got any suggestions for handling this in other ways?

Try this as a cell formula
=INDEX(A:A,SEQUENCE(COUNTA(A:A),1,4,10))

for previous versions of Excel, without Sequence(), this will do
=INDEX(B1:B1000,(ROW(OFFSET($A$1,,,COUNT(B1:B1000)))-1)*10+4)
OR put the Distance (ex:10) in D3 / Start in D2 (ex:4) / Total no of Numbers in D1 (ex: D1 = Count(b1:b1000)) and write the formula:
=INDEX(B1:B1000,(ROW(OFFSET($A$1,,,$D$1))-1)*$D$3+$D$2)
up to you. (enter both as Array Formulas w ctrl+shift+enter)
B1:B1000 will contain up to 100 numbers... so adjust at will and keep small for speed

Related

Determine if values in a column are between 2 numbers in an array

Excel formula that looks up if X is in between 2 values in a matrix and says yes or no (1 or 0). This formula is intended to be copied as the Y-value to the X. X column will be up to 50,000 rows and the matrix will be up to 100rows
This code works:
=IF(OR(AND(A2>=$D$2,A2<=$E$2),AND(A2>=$D$3,A2<=$E$3)),1,0)
but will get very cumbersome if the matrix gets larger, ie up to 50 rows. I also tried:
{=IF(AND(A2>=$D$2:$D$3,A2<=$E$2:$E$3),1,0)}
but returns #VALUE!
You could also make use of SUMPRODUCT() like so in B2 and drag down:
=IF(SUMPRODUCT((A2>=$D$2:$D$3)*(A2<=$E$2:$E$3))>0,1,0)
And here is a way to make it easy on yourself, create a table out of your ranges, and if you add or remove from there the formula will adjust. Like so:
=IF(SUMPRODUCT((A2>=Tabel1[X1])*(A2<=Tabel1[X2]))>0,1,0)
If you can, add an extra column to the "matrix" to store the result (1,0) for each range.
Use vlookup with approximate results

Excel 2003: Averaging every Nth row

I am using Excel 2003 and am trying to average every two rows of data in one column,
starting from A1 and ending in A4, for example,
1
2
1
2
I try to do this average on the B1 column/row as follows (based on this info)
=AVERAGE(IF(MOD(ROW(A1:A4),2)=0,A1:A4))
However, when doing the above, B1 returns a 0, even though I intended to get a 1.
What would be the best way to make this kind of averaging work?
=AVERAGE(IF(MOD(ROW(A1:A4),2)=0,A1:A4))
The above formula is an array formula. To finalize it you need to press ctrl+shift+enter simultaneously; not just enter. This has also been abbreviated as CSE.
When you do this correctly, excel will wrap the formula in braces (e.g. { and }) like this:
{=AVERAGE(IF(MOD(ROW(A1:A4),2)=0,A1:A4))}
You do not type these braces in yourself; they are added automatically when a formula is entered as an array formula.
The solution to the question was as follows:
{=AVERAGE(IF(MOD(ROW(A1:A4)-1,2)=0,A1:A4))}
where the {} appears after pressing ctrl+shift+enter due to it being an array formula (cannot type that in manually).
The -1 is the offset based on where the data starts, and depending on the modulus operation, since MOD(ROW(A1),2) was 1,
i.e.: if my data instead started on A27, and I instead wanted to average values in every 4 rows, then MOD(ROW(A27),4) would return a 3 and the formula would correspondingly be offset by -3.
You could avoid array formulas using the below:
=IF((INT(ROW()/2)=ROW()/2)=TRUE,AVERAGE((A1,OFFSET(A1,-1,0))),"")
Image:

Excel Index to look up multiple values

I have a small data set of 2 columns and several rows (columns A and B)
I want to return each instance of codeblk 3 in a formula that is elsewhere in my sheet, (so a vlookup is out as it only shows the first instance) if it does not appear then a message to say its not there should come up.
I have the formula partially working but i cant see the reason why its not displaying the values.
My formula is as below:
This is an array
{=IF(ISERROR(INDEX($A$55:$B$70,SMALL(IF($B$55:$B$70=3,ROW($B$55:$B$70)),ROW(1:1))-1,1)),"No value's produced",INDEX($A$2:$C$7,SMALL(IF($B$55:$B$70=3,ROW($B$55:$B$70)),ROW(1:1))-1,1))}
The result that shows up is only "No values produced" but it should reflect statement B, C and D in 3 separate cells (when changing ROW(1:1), ROW(2:2) etc)
{=SMALL(IF($B$56:$B$69=4,ROW($B$56:$B$69)),ROW(1:1))} - This produces the result 68 which is the correct row.
Any ideas?
Thanks,
This is an array formula - Validate the formula with Ctrl+Shift+Enter while still in the formula bar
=IFERROR(INDEX($A$55:$B$70,SMALL(IF($B$55:$B$70=3,ROW($B$55:$B$70)-54),ROW(1:1)),1),"No value's produced")
The issue you are facing is that your index starts it's first row on $B$55, you need to offset the row numbers in the array to reflect this. For example, the INDEX contains 16 rows but if you had a match on the first row you are asking for the 55th row from that INDEX(), it just can't fulfil that.
EDIT
The offset was out of sync as your original formula included another -1 outside of the IF(), I also left an additional bracket in play (the formula above has now been edited)
The ROW() function will essentially translate $B$55:$B$70 into ROW(55:70) which will produce the array {55;56;57;58;59;60;61;62;63;64;65;66;67;68;69;70} so the offset is needed to translate those row numbers in to the position they represent in the indexed data of INDEX().
The other IF() statement then produces and array of {FALSE;2;3;4;FALSE etc.
You can see these results by highlighting parts of the formula in the formula bar and hitting F9 to calculate.

Excel multiple variable lookups

have a table that i would like it to select the smallest size picture frame that could be used based on the size values,
basically return the smallest frame that would fit the image.
For example i have 4 standard sizes:
a b c
Size1 150 150
Size2 300 300
Size3 540 570
Size4 800 800
I want to have a size in another cell e.g. 290 x 300 and would like it to pick the smallest size possible to fit i.e. in this case size2.
I've followed a few guides and have the following that will print out the value if the values are exact but not if they are slightly under one of the options
=VLOOKUP($A$8,CHOOSE({1,2},$B$2:$B$5&", "&$A$2:$A$5,$C$2:$C$5),2,0)
Any helo / direction would be much appreactiated!
Thanks
Assuming order does matter (e.g. there is a difference between 500x550 and 550x500), you can use this array formula:
= INDEX($A$2:$A$5,MATCH(2,MMULT((E2:F2<=$B$2:$C$5)+0,{1;1}),0))
Note this is an array formula, so you must press Ctrl+Shift+Enter after typing this formula rather than just pressing Enter.
See below for working example.
Assuming order does not matter (e.g. there is not a difference between 500x550 and 550x500), the formula gets considerably longer because of reversing the order of the E2:F2 array. There is possibly a better way to do this but this is the easiest way I can think of to do it. Unfortunately Excel has no way of handling 3D arrays, otherwise this would be not much different from the original formula above. Anyway, here is the formula (line breaks added for readability)
= INDEX($A$2:$A$5,MIN(MATCH(2,MMULT((E2:F2<=$B$2:$C$5)+0,{1;1}),0),
MATCH(2,MMULT((INDEX(E2:F2,N(IF({1},MAX(COLUMN(E2:F2))-
COLUMN(E2:F2)+1)))<=$B$2:$C$5)+0,{1;1}),0)))
Note this is also an array formula.
See below, working example. Note how it yields the same result as above in every cell except cell G4, since again this is considering 550x500 and 500x550.
It is not clear what is in cell A8. Going by your question, I assume it must be dimensions in the format "W x H" (example: 290 x 300). If so, try:
In D2: 1
// Copy next down
In D3: D2+1
// Wherever you want it
=CONCATENATE("Size ",MIN(VLOOKUP(LEFT(A8,FIND(" ",A8)-1)+0,B2:D5,3,TRUE),VLOOKUP(RIGHT(A8,LEN(A8)-FIND("x ",A8)-1)+0,C2:D5,2,TRUE)))
Alternatively, if you split the width and height into 2 cells A8 and B8, this simpler version should do the trick:
In D2: 1
// Copy next down
In D3: D2+1
//Wherever you want it
=CONCATENATE("Size ",MIN(VLOOKUP(A8,B2:D5,3,TRUE),VLOOKUP(B8,C2:D5,2,TRUE)))
These assume the sizes all use a "Size #" naming convention. If otherwise, you could add another column at the right to equal column A, then use vlookup to identify the match, like this (again assumes "W x H" in cell A8):
In D2: 1
// Copy next down
In D3: D2+1
// Copy next down
In E2: =A2
// Wherever you want it
=VLOOKUP(MIN(VLOOKUP(LEFT(A8,FIND(" ",A8)-1)+0,B2:D5,3,TRUE),VLOOKUP(RIGHT(A8,LEN(A8)-FIND("x ",A8)-1)+0,C2:D5,2,TRUE)),D2:E5,2,FALSE)

Use a variable for columns in SUMPRODUCT and VLOOKUP formula

I'm trying to use this formula:
=SUMPRODUCT(VLOOKUP(B$4778,$D$4:$DC$4623,{4,5},0))
It works fine but I'd like to try to use a variable for the {4,5} portion of the formula (columns in the array to be summed) as the formula needs to change based on sheet inputs before this formula.
I have cells on the sheet that are to be used to set the initial and final columns to be searched (likely 10 columns, but the 10 columns would have to be selected from 90 some columns available).The columns are populations related to each age. So, if I need population of those aged 10 through 15, I'd need to sum up 5 columns. If 20-25, need to sum up 5 different columns.
I tried to use the Columns function but it didn't seem to work for me.
The columns are selected by users entering in cells the upper and lower limits of the search range and then I convert those values to the corresponding numerical column value.
So if they select 5 as lower and 10 as upper limit, I know I have to add 7 to get the correct data column on the data page (column 12) and likewise for upper (column 17).
The entire possible area to search is $D$4:$DC$4623. So, in the formula, if I wrote it out long way it would be:
=SUMPRODUCT(VLOOKUP(B$4778,$D$4:$DC$4623,{12,13,14,15,16,17},0))
I'd prefer to write it out using variables, something like this:
=SUMPRODUCT(VLOOKUP(B$4778,$D$4:$DC$4623,{L:U},0))
Where variable L would be 12 and variable U would be 17.
Can anyone suggest a way to write the formula?
use this array formula:
=SUM(VLOOKUP(B$4778,$D$4:$DC$4623,ROW(INDIRECT(D5 & ":" & E5)),FALSE))
Where D5 is the Lower and E5 would be the upper.
Being an array formula it must be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode. If done correctly then excel will put {} around the formula.
Or better yet use this non array formula:
=SUM(INDEX($D$4:$DC$4623,MATCH(B$4778,$D$4:$D$4623,0),D5):INDEX($D$4:$DC$4623,MATCH(B$4778,$D$4:$D$4623,0),E5))

Resources