Excel maximum difference between consecutive values in array - arrays

I have an array of numbers:
46.50, 46.50, 46.50, 50.00, 60.00, 57.00, 50.00, 48.00, 44.00, 42.00
I'd like to create a formula that finds the maximum positive difference between two consecutive pairs. So in the above example, the intermediate calculation would be:
0,0,-3.50,-10.00,3.00,7.00,2.00,4.00,2.00
Therefore the answer would be 7.00

Going to go with a basic array formula for this one. Aussuming your data is layed out as per the image below, used to offset ranges and subtract one range from the other. Then take the maximum of those results. This can be achieved using the following formula entered as an array. meaning you need to confirm it with CTRL+SHIFT+ENTER. You will know you have done it right when {} show up around your formula. They cannot be added manually.
=MAX(B3:B11-B4:B12)
as an alternative non array formula you can got with AGGREGATE which will perform array like calculations:
=AGGREGATE(14,6,B3:B11-B4:B12,1)
The above formulas will provide you with the largest positive difference. If how ever you need to know the largest difference, then -10 is a larger difference than 7. Its just in the opposite direction. To find this you would need to add ABS to the above equations as follows:
=MAX(ABS(B3:B11-B4:B12))
OR
=AGGREGATE(14,6,ABS(B3:B11-B4:B12),1)

Use an array formaula. If your values are in column A (rows 1 to 10 in this case), use
=MAX(A1:A9-A2:A10)
And enter it with CTRL-SHIFT-ENTER instead of just Enter.

Related

Makearray function in Office Excel unable to generate proper amount of columns for the array

I am using Office 365 currently and I want to make a visualization tools using MAKEARRAY functions.
For example, if I want to display sequential of 32 items, I would display it in this way:
I use the following formula of Makearray to generate the custom array for me
Note: Formula is pasted at cell value F3 .
=MAKEARRAY(ROUNDUP(B2/B3,0),IF(E3#=ROUNDUP(B2/B3,0),MOD(B2,B3),B3),LAMBDA(row,col,"O"))
but it seems like after debugging, this part of the formula are giving it the problem are these
IF(E3#=ROUNDUP(B2/B3,0),MOD(B2,B3),B3)
as I debugging the formula separately as shown in picture below, it can generate the correct amount of columns as it is supposed to.
Note: Generate exactly same amount to the no of columns if row number is not matching;
Generate modulus remainder formula if row number is matching to roundup of no. of items divided by no. of columns.
But in the end, I put that problematic formula back into the MAKEARRAY function just give only a single columns, which seems like it is quite wrong.
May I know why it display single columns even though by right, it should display the correct amount of no. of columns?
What about:
Formula in C1:
=WRAPROWS(INDEX("O",SEQUENCE(A1,,,0)),A2,"")
Or rather:
=WRAPROWS(EXPAND("O",A1,,"O"),A2,"")
MAKEARRAY does not expect an array in the number of columns. It is a set number. It will iterate the number of rows and number of columns to create the array. It will always be square and not jagged.
So you need to do the math to change the value:
=MAKEARRAY(ROUNDUP(B2/B3,0),B3,LAMBDA(rw,clm,IF(10*(rw-1)+clm>B2,"","O")))
Now as soon as the space is greater than the 32 it puts in "" instead of "O"

Looking for a array reducing algorithm

I have an array of a structures containing two float values x and y.
x is the position on a x-axis in mm (0.0mm to e.g. 2500.0mm)
y is a height measurement in mm at the x-position (0.0mm to e.g. 50.0mm)
With the length of 2500.0mm I will have an array filled up with 2501 values (one for each mm). As i want to send this array to a visualization which will draw that on a x/y plot i want to reduce that array to exactly 500 values (more than 500 values will slow down the communication too much). Now you might say.. well okay, than just take every 5th value. But what to do if my array has 1653 values? I would have to take every 3,306th value. I definitely need the first and the last value.
Is there any elegant algorithm that might help me out?
You could use interpolation to estimate a function that is similar to yours, and then you could just choose the desired points in the data range and estimate their value. Then, you could simply plot these values.
This is elegant and pretty easy to generalize for more or less points, as long as you stay within the range of original data (and do not try to extrapolate out of this range)

how do you find the nth lowest number in an array when numbers repeat themselves?

I am trying to find the second lowest cost in this list. Clearly, it is $547, but when I put the formula in: =SMALL(F2:F31, 2) I get $488.00, and I am guessing this is because $488 repeats itself a number of times and so it is the second number in the list of numbers to be the smallest?
What formula should I put in to get the second smallest number, despite repeats?
What is the purpose of this? The end result? Do you seek automation or this is adhoc?
If this is adhoc, you can do:
1. copy column with numbers
2. Paste copied column into new sheet
3. Use Remove Duplicates functionality (Data tab) on this column to remove repetitions
4. Use your formula
Also, you can do this with one formula :
=SMALL(F2:F31, COUNTIF(F2:F31, MIN(F2:F31)) + 1)
As long as you only want the second smallest number, and you only have 2 digits of significant influence, you can do this fairly effectively without creating additional arrays of data, or using Array Formulas, as long as you can re-order from largest to smallest, instead of smallest to largest.
First, find the smallest number, which is simply:
=MIN(F:F)
Then, subtract 1 penny from that amount. We can now use price-is-right-rules searching to find the closest number, utilizing the next-best feature of the MATCH function, as follows:
=INDEX(F:F,MATCH(MIN(F:F)+0.01,F:F,-1))
This will take the smallest number in column F, and add .01 to it. Using -1 as the 3rd argument in the MIN function forces MIN to accept the next best alternative if this amount is not matched exactly.
Only because I figure based on your last post we are headed this way. I would as I said in that post make a unique list of all your states and counties.
Then building on #Andrew formula, which should be the one marked as correct, with COUNTIFS() as the k value in the SMALL():
=SMALL(IF(A2=DATA!A:A,IF(B2=DATA!B:B,DATA!F:F)),COUNTIFS(DATA!A:A,A2,DATA!B:B,B2,DATA!F:F,MIN(IF(A2=DATA!A:A,IF(B2=DATA!B:B,DATA!F:F))))+1)
This will give you a clean list of the second value.
Then to find the Insurance company that goes with the quote use:
=INDEX(DATA!E:E,MATCH(SMALL(IF(A2=DATA!A:A,IF(B2=DATA!B:B,DATA!F:F)),COUNTIFS(DATA!A:A,A2,DATA!B:B,B2,DATA!F:F,MIN(IF(A2=DATA!A:A,IF(B2=DATA!B:B,DATA!F:F))))+1),IF(A2=DATA!A:A,IF(B2=DATA!B:B,DATA!F:F)),0))
Put them in the second row. These are both Array formulas and will need to be confirmed with ctrl-shift-enter. Then they can be copied down as far as needed.

Change array dimensions, using spreadsheet functions, when used inside SUMPRODUCT

I am interested in spreadsheet functions, not VBA solutions, to be included in a single cell formula.
[A1:A15 contain numeric values from 1 to 127, B1:B15 contain integers from 1 to 7 that set a divisor.]
Given the function:
=SUMPRODUCT(MOD(FREQUENCY(A1:A15;A1:A15);B1:B15))
FREQUENCY(A1:A15;A1:A15) gives a 1-column array of 15+1 rows, whereas the second part (B1:B15) is a 1-column array of 15 rows.
I would like to change the resulting array given by FREQUENCY (only in memory -not explicit in sheet-) from a 1-column 16 rows array to a 1-column 15 rows array with the first 15 cell values of that array.
[FREQUENCY documentation: https://support.office.com/en-us/article/FREQUENCY-function-44e3be2b-eca0-42cd-a3f7-fd9ea898fdb9 NB: for Excel, second remark states number of elements that depend on bins_array. ]
I would appreciate suggestions.
Thus, both arrays within MOD will have the same dimensions and SUMPRODUCT will not find cells with error values. I can disregard error values using IF and ISERROR within SUMPRODUCT, but I'd rather disregard the non-relevant part of the FREQUENCY resulting array if it is possible.
It has been thought that making it more specific might be more helpful, so it has been heavily reduced and simplified.
With external help, I have been able to fine-tune a way to solve my problem using INDEX in array formula mode. I am posting the answer in case it helps others.
One way: Put FREQUENCY(A1:A15;A1:A15), or any formula that produces an multi-cell array, within INDEX and have 2nd and/or 3rd arguments as array of consecutive values which will represent rows/columns.
INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(FREQUENCY(A1:A15;A1:A15)-1));1)
First argument within INDEX is the resulting array coming from a formula to shrink (from 16x1 to 15x1), which would be a multi-cell array formula if explicitly entered; second argument is the array 1..15 given by row numbers from 1 to the number of total rows of the "array from formula to shrink" MINUS 1: the first 15 (out of 16) values in the array from a formula; 3rd argument is the column of the shrank array (if need be, more than one could be selected using an analogue to the second argument).
In the particular case of FREQUENCY, because it is known that we are interested in the "bins" part of the function, the formula can be simplified by including the total rows of the "bins"/"intervals" array inside FREQUENCY (its second argument). We will have
INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1)
and the complete formula would become
SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15;A1:A15);ROW(INDIRECT("1:" & ROWS(A1:A15)));1);B1:B15))
Now, both dividend and divisor of MOD have exactly the same dimensions (15x1) and because B1:B15 includes integers greater than 0 there are no errors.
Thanks all for helping me in making question more concise and better formatted.
ADDITIONAL INFORMATION: As pointed out correctly in comments by XOR LX, this does not seem to work in the widely popular spreadsheet software Excel. It has been developed for an INDEX function inside SUMPRODUCT as used in Open Office Calc which I had mistakenly thought 100% equivalent to Excel's version. A more complete answer perhaps using other functions would be appreciated.
In the previous answer, XOR LX points out very correctly that this formula cannot work in Excel, due to row_num/column_num argument behaviour. Very kindly XOR LX has shown me how that approach can work, and also thanks and credit for supplying a good answer: "INDEX can be used to redimension array (even dynamically created ones) if the row_num/column_num array is coerced to take an arbitrary array with the right dimensions, as shown on this blog entry " The following formula has been checked in Excel 2010 and has the expected results:
SUMPRODUCT(MOD(INDEX(FREQUENCY(A1:A15,A1:A15),N(INDEX(ROW(INDIRECT("1:" & ROWS(A1:A15))),,)),1),B1:B15))
NB: row_num argument of first INDEX, a ROW generated auxiliary array, has been nested inside N(INDEX([...],,)); at least one comma is necessary to account for the two arguments minimum of the nested INDEX. It is in itself interesting the discussion that applies generally to INDEX's arguments, and other functions', that need to be coerced to take arrays (see, here and here at XOR LX's blog). For Open Office users it might be worth stressing the point made at the blog
Unlike OFFSET, (...) for which the first parameter must be a
reference (...) in the worksheet, INDEX can also accept –
and manipulate – for its reference arrays which consist of values
generated e.g. via other subfunctions within the formula. XOR LX's blog
That would be indeed the case in changing the dimension in an array as in this question, but also useful in reversing or displacing the values in an array, for example. Open Office accepts arrays as row_num/column_num, so the coercion is not needed and some formulas rely on this, but without it, these formulas are unlikely to work when files are open in Excel.
Regrettably, this type of coercion is not passed correctly to Open Office, and formula need to be "decoerced" to work, at least in my casual tests.
In order to use a formula that would work in both spreadsheet programs regarding shortening arrays, the only thing I have managed is the following (required: arrays must be single-column)
SUMPRODUCT(
(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
-ROW(COLUMN(INDIRECT("R1C1:R"& ROWS(vals_to_mod) &"C"& ROWS(FREQUENCY(vals_for_freq,vals_for_freq)),FALSE))
=0)
*MOD(TRANSPOSE(FREQUENCY(vals_for_freq,vals_for_freq)),vals_to_mod)
)
(it "shortens" one array to the shortest of the pair, by creating an auxiliary array with TRUE/1s on the diagonal starting top-left and FALSE/0s elsewhere, therefore disregarding all defined values outside the square section of the array. Thus, SUMPRODUCT adds values within the diagonal of the square section which are the product of the corresponding values up to the last value of the shorter array.)

Excel, counting positive numbers such that next column is top 10

I am looking to count/sum positive numbers in a column given that we are taking only top 10 in next column. For e.g.
I am using the formula: =SUM(LARGE(IF($E$3:$E$58>0,$F$3:$F$58),ROW(A1:A10)))
But it is summing the top 10 right F column such that E column is positive, which is the other way round. Any help is appreciated.
It doesn't sound as if you need anything more elaborate than a COUNTIFS function and a SUMIFS function. The LARGE function can provide a criteria to govern what is included in the count or sum. You've provided no row numbers so I will just use full column references.
     
The formulas are in the image much as your sample data was. As you can see, I used a greater than zero to determine what is a positive number. These are not array formulas. I was a little confused why you were asking for a count as your description seemed to refer to the Top 10. Maybe you can transcribe this for your own purposes.

Resources