Array Formula To Find 2nd Largest Number - arrays

I currently use the following formula to find the largest number in a dataset (Sheet1K7:K106), conditional on some corresponding values (Sheet2!C7:C106) being less than a certain number (Sheet3!C18):
=MAX(Sheet1!K7:K106*(Sheet2!C7:C106<Sheet3!C18))
I would like to now find the second largest number given the same condition. I would assume that this requires the LARGE function, although I can't seem to apply the aforementioned condition.

If you're using Excel 2010 or later:
=AGGREGATE(14,6,Sheet1!K7:K106/(Sheet2!C7:C106<Sheet3!C18),2)
Otherwise, array formula**:
=LARGE(IF(Sheet2!C7:C106<Sheet3!C18,Sheet1!K7:K106),2)
Regards
**Array formulas are not entered in the same way as 'standard' formulas. Instead of pressing just ENTER, you first hold down CTRL and SHIFT, and only then press ENTER. If you've done it correctly, you'll notice Excel puts curly brackets {} around the formula (though do not attempt to manually insert these yourself).

Related

Excel maximum difference between consecutive values in array

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.

SUM with IF conditions for cells containing both strings and numbers

I've got a bigger table with one column that I want to focus on, containing designation and a number. I want to simply sum the numbers that meet the criteria based on a designation.
For the simplification, I made an exercising sheet (on the pic) where I split second column into two - one string and one numeric. Since my file is quite large with many columns that would need this it would be inconvenient.
In the left column it's easy to solve the problem, it could be even easier with simple SUMIF function, but an array SUM(IF... function is, at least I think, only viable option here.
So I solved the first table with array function, but what confuses me is how to modulate the TRUE statement. Simple replacement of C:C
with
VALUE(MID(F:F;4;4))
which would format my cells to get the numbers from string does not work that way - returns zero in E12 field. F12 is just application of string to number for last cell, F10.
THIS formula does not work, even adapting to different versions of the tool.
I could use VB but if possible anyhow I would like to avoid it since parts will be shared on mobile phones.
Any ideas? Thanks a lot!
Left table was split, right original format
The array formula which you used can be replaced by the SumIf formula like below...
=SUMIF(B:B,"B",C:C)
Also without the helper column, you can use the Sumproduct formula to achieve the desired output.
But don't refer the whole column in the formula like in the above SumIf formula.
Try this..
=SUMPRODUCT((B1:B10="B")*MID(F1:F10,FIND(",",F1:F10)+1,255)*1)
Change the ranges as per your requirement but remember to make them equal in size.

How to count instances of a string occurring in an array of cells

I have a spreadsheet that tracks where consumers are referred to. To record individual referrals, users select places from a drop down list. This list then populates a cell, with values separated by commas.
On a separate sheet, I need to count the number of referrals for each referral type. So I need to count the # of times DHHS shows up in the array, for example. I've attempted to do this using the following formula:
=SUM(LEN(range))-LEN(SUBSTITUTE(range,"string",""))/LEN("string")
This is working fine for single word strings, but is not working for multiple word strings like "CHIP Water Inquiry". Any ideas why, and what I can do about it?
You need to make two minor corrections, as you are breathtakingly close in your formula. Add a second SUM formula, tally the subtracted length and then house the two subtracted sections within parentheses as you see in the posted formula. As Boris said, Ctrl + Shift + Enter it, as you probably already know. F1 is assumed to hold your "string" that you wish to count.
=(SUM(LEN(range))-SUM(LEN(SUBSTITUTE(range,F1,""))))/LEN(F1)

Excel: Sum The Values Other Than the Top Three in a Range

Using Excel I would like to get the total of the values in a range other than the top three values.
The range has #N/A values I would like to ignore.
The range in horizontal.
In the case where as an example the top 4 values are all 8, I would only want three of the 8s to be excluded from the sum.
I have managed to sum the top three values in the range using the following function:
=SUM(LARGE(IF(NOT(ISNA(AW2:BH2)),AW2:BH2),{1,2,3}))
I assume there is a small adjustment I can make to the above, but my brain's not working.
You can use the AGGREGATE function to ignore the errors:
=AGGREGATE(9,6,AW2:BH2)-SUMPRODUCT(AGGREGATE(14,6,AW2:BH2,{1,2,3}))
Function_num 9 = SUM
Function_num 14 = LARGE
Option 6 = Ignore errors
You will get an error if there are less than three values in the row. You could trap for that with either COUNT or IFERROR if that might be an issue.
Array formula**:
=SUM(IF(ISNUMBER(AW2:BH2),IF(1-ISNUMBER(MATCH(AW2:BH2+COLUMN(AW2:BH2)/10^6,LARGE(IF(ISNUMBER(AW2:BH2),AW2:BH2+COLUMN(AW2:BH2)/10^6),{1,2,3}),0)),AW2:BH2)))
Regards
where the values in the range AW2:BH2 are assumed to of an order greater than 1E-6.
**Array formulas are not entered in the same way as 'standard' formulas. Instead of pressing just ENTER, you first hold down CTRL and SHIFT, and only then press ENTER. If you've done it correctly, you'll notice Excel puts curly brackets {} around the formula (though do not attempt to manually insert these yourself).

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.)

Resources