Excel AGGREGATE Function: #VALUE error when applying boolean array multiplication - excel

For this example I'm starting with this table:
Table example
Now I want to calculate the average for each row relating to its group identifier. For that, the code I have in Column AvgValueOfGroup is
=AGGREGATE(1,6,([#Group]=[Group])*[Value])
This throws a #VALUE error for me.
The last step of the calculation is looking normal:
=AGGREGATE(1,6,{6;0;0;0;0;2})
What am I doing wrong?
P.S.: I'm aware of the alternative solutions around this specific case, but I'll require a solution using aggregate.

The problem is that the aggregate function does not allow array arguments for SUM, AVERAGE, COUNT etc - it always returns #Value. You can only use array arguments with aggregate for things like Large, Small, StDev etc.

It's a bit vague what would be considered the "best", however you could consider adding all these amounts together (subtract the protein) would give you a matrix in which you can get the minimum.
Try:
=INDEX(A2:A5,MATCH(MIN(INDEX(B2:B5+C2:C5+D2:D5-E2:E5+F2:F5,)),INDEX(B2:B5+C2:C5+D2:D5-E2:E5+F2:F5,),0))
Add a multiplication, e.g.: *1.05 to any of the columns if you consider them to be of more importance.

Related

Calculate the minimum value of each column in a matrix in EXCEL

Alright this should be a simple one.
I apologize in case it has been already solved, but I can only find posts related to solving this issue with programming languages and not specifically to EXCEL.
Furthermore, I could find posts that address a sub-problem of my question (e.g. regarding limitation of certain EXCEL functions) and should solve/invalidate my request but maybe, just maybe, there is a workaround.
Problem statement:
I want to calculate the minimum value for each column in an EXCEL matrix. Simply enough, I want to input a 2D array (mxn matrix) in a function and output an array with dimension 1xm where each item is the minimum value MIN(nj) of each nj column.
However, I want to solve this with specific constraints:
Avoid using VBA and other non-function scripting: that I could devise myself;
All in one function: what I want to achieve here is to have one and one function only, not split the problem into multiple passages (such as for example copypasting a MIN() function below each column, that wouldn't do it);
The result should be a transposable array (which is already ok, I assume);
Where I am stranded with my solution so far:
The main issue here is that any function I am trying to use takes the entire matrix as a single array input and would calculate the MIN() of the entire matrix, not each column. My current (not working) function for an exemplary 4x4 matrix in range A1:D4 would be as below (the part in bold is where it is clearly not working):
=MIN(INDEX(A1:D4,SEQUENCE(4,4,1,1)))
which ofc does not work, because INDEX() does probably not "understand" SEQUENCE() as an array of items to take into account. Another, not working, way of solving this is to input a series of ranges (A1:A4;B1:B4;C1:C4;D1:D4) so that INDEX() "understands" the ranges as single columns, but ofc does not know and I do not know sincerely how to formulate that. I could use INDIRECT() in some way to reference the array of ranges, but do not know how and could find a way by searching online.
Fundamental question is: can a function, which works with single arrays, also work with multiple arrays? Basically, I do not know how to communicate an EXCEL array formula, that each batch of data I am inputting is a single array and must be evaluated separately (this is very easily solved with for() cycles, I know).
Many thanks for any suggestion and any workaround, any function and solution works as longs as it fits in the constrains defined above (maybe a LAMBA() function? don't know).
This is ofc a simplification of a way more complex problem (I am trying to calculate the annual mean temperature evolution for a specific location by finding the value - for each year from 1950 to 2021 - that is associated to the lat/lon coordinates that are the nearest to the one of the location inputted, given a netCDF-imported grid of time-arrayed data; the MIN() function is used to selected the nearest location, which is then used, via INDEX() to find temp data). I need to do this in one hit (meaning just pasting the function, which evaluates a matrix of data that is referenced by a fixed range), so that I can just use it modularly for other data sets. I already have a working solution, which is "elegant"* enough, but not "elegant"* as the one I could develop solving this issue.
*where "elegant"= it saves me one click every time for 1000+ datasets when applying the function.
If I understand your problem correct then this should solve it:
=BYCOL(A1:D4,LAMBDA(d,MIN(d)))

Can I use MINIFS or INDEX/MATCH on two non-contiguous ranges...?

Problem is straightforward, but solution is escaping. Hopefully some master here can provide insight.
I have a big data grid with prices. Those prices are ordered by location (rows) and business name (cols). I need to match the location/row by looking at two criteria (location name and a second column). Once the matching row is found (there will always be a match), I need to get the minimum/lowest price from two ranges within the grid.
The last point is the real challenge. Unlike a normal INDEX or MINIFS scenario, the columns I need to MIN aren't contiguous... for example, I need to know what the MIN value is between I4:J1331 and Q4:U1331. It's not an intersection, it's a contiguous set of values across two different arrays.
You're probably saying "hey, why don't you just reorder your table to make them contiguous"... not an option. I have a lot of data, and this spreadsheet is used for a bunch of other stuff. So, I have to work with the format I have, and that means figuring out how to do a lookup/min across multiple non-contiguous ranges. My latest attempt:
=MINIFS(AND($I$4:$J$1331,$K$4:$P$1331),$B$4:$B$1331,$A2,$E$4:$E$1331,$B2)
Didn't work, but it should make it more clear what I'm trying to do. There has GOT to be an easy way to just tell excel "use these two ranges instead of one".
Thanks,
Rick
Figured it out. For anyone else who's interested, there doesn't seem to be any easy way to just "AND" arrays together for a search (Hello MS, backlog please). So, what I did instead was to just create multiple INDEX/MATCH arrays inside of a MIN function and take the result. Like this:
MIN((INDEX/MATCH ARRAY 1),(INDEX/MATCH ARRAY 2))
They both have identical criteria, the only difference is the set of arrays being indexed in each function. That basically gives me this:
MIN((match array),(match array))
And Min can then pull the lowest value from either.
Not as elegant as I'd like... lots of redundant code, but at least it works.
-rt

Excel IF statement Not returning the appropriate Value

I'm trying to grade students by giving them A or B depending on their score. If someone is having absent instead of a score, I return a value of the cell.
However, it does not return the value of the cell. The reference records are in a separate sheet called raw. I think it may be because I'm trying to return a string data.
I am using Excel 2007. Here's the formula:
=IF(raw!E6>=75,"AA",IF(raw!E6>=70,"AB",IF(raw!E6>=60,"B",IF(raw!E6>=50,"C",IF(raw!E6>=40,"D",IF(raw!E6<40,"RT",raw!E6))))))
Don't use Nested IFs if you can avoid it. Instead, use a banded VLOOKUP: it's many times more efficient, and a heck of a lot simpler to troubleshoot. Something like this:
=IF(ISNUMBER([#Score]),VLOOKUP([#Score],Table1,2,TRUE),"Absent")
Notes:
The above uses Tables and the associated Table Notation. I always use
Tables when I can, because they reduce spreadsheet administration and
the Structured Table References have intrinsic meaning.
The VLOOKUP must have TRUE as the forth argument, and the lookup
table must be sorted in ascending order.
The lowest score must be zero, so that anything below 40 gets a "Retake" grade.
Depending on whether or not the students' scores are in whole percentage figures (i.e. 75, 63, etc), you could use the INT-function to force interpretation of the input field as an integer (not that it always round down a score, which I suppose seem to be ok with the nested if-structure you're using here. Your function would then be:
=IF(INT(raw!E6>=75),"AA",IF(INT(raw!E6)>=70,"AB",IF(INT(raw!E6)>=60,"B",IF(INT(raw!E6)>=50,"C",IF(INT(raw!E6)>=40,"D",IF(INT(raw!E6)<40,"RT",raw!E6))))))
you just need to change you last IF condition (raw!E6<40,"RT) because excel will give RT to all the score which is below 40 so add a and condition like if raw!E6>0 , this should resolve your work
if(and(raw!E6<40mraw!E6>0),"RT,raw!E6)
Hope this helps

Frequency() with arrays: adds an element to return arrays

I'm using the following formula as named formula (via name manager). It is then used in a larger sumproduct(). The goal is to ensure that with an array calculation, the calculation is only made once for certain groups of rows (e.g. you have the same data repeated accross many rows for category A. I only need to know how many people are in category A once).
=IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],
tdata[reportUUID],0),0),IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],
tdata[reportUUID],0),0))>0,TRUE)
Let's step through the results one by one with the evaluate formula in Excel. Sorry for the screenshot, but Excel doesn't allow to copy actual steps with real data....
In order of steps:
In the last image, there's now a 7th item in my array. I only have 6 row of data, hence why for the previous steps I only had 6 items in the array, as was expect.
This is messing up my calculations, because the return array from this function gets multiplied by others arrays which all have 6 items (or whatever is the number of data rows I have).
What is this 7th item, and how can I either get ride of it or prevent it from return errors?
I did try to wrap some formula into iferror() or ifna(), however it doesn't feel clean. I feel this might backfire and isn't a strong way to handle this. I rather take it at the source....
EDIT: For example of use with other arrays:
{=SUMPRODUCT(--IFERROR(((tdata[_isVisible]=1)*(f_uniqueUUIDfactor),0))}
Where f_uniqueUUIDfactor is the formula from the initial post. tdata[_isVisible]=1 is used as a way to filter data on the dashboard (e.g. through dropdown, the users can set ranges for dates, and with VBA I hide the rows in the raw data NOT within the range).
The point is that sumproduct() ends up multipliying each raw data row thogheter as 0 & 1 s, so that only those meeting all the criterias get returned. The IFERROR() above is the workaround for the extra array element introduced by frequency(). It works as is, but if a cleaner way exists I'd prefer that. I would also be keen on understanding why that elements get added.
This is a good example of why it is preferable to use multiple, recursive IF statements when evaluating arrays over multiple criteria, rather than form the product of those arrays.
Firstly, though, before coming to the reason for that statement, I should point out a few minor technical inaccuracies/flaws with your construction also.
1) By including a value_if_false clause in your constructions being passed as FREQUENCY's data_array and bins_array parameters, you are risking incorrect results, since zero is a valid numerical to be considered by FREQUENCY, whereas a Boolean FALSE (which would be the equivalent entry in the resulting array had you omitted the value_if_false clause altogether) is disregarded by this function.
2) MATCH with an exact (i.e. 0, or FALSE) match_type parameter is a relatively resource-heavy construction, particularly if the range to be considered is quite large. As such, and since it is not necessary to use this construction for FREQUENCY's bins_array parameter, it is preferable to use the more efficient:
ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1
Moreover, note that repetition of the IF(LEN construction is also not necessary within this second parameter.
In all, then:
IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)
is considerably more rigorous and more efficient than the version you give.
To answer your main question, it is well-documented that FREQUENCY always returns an array having a number of entries one greater than that of the bins_array passed.
As mentioned in my comment to your post, the resolution to the problem you are facing largely depends on precisely what further manipulation you are intending for the resulting array.
However, let's assume for the sake of an explanation that you simply wish to multiply the array resulting from your FREQUENCY construction by some other column within your table, tdata[Column2] say, and then sum the result.
The difference between:
=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)*tdata[Column2])
i.e. using multiplication of the two arrays, and:
=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,tdata[Column2]))
i.e. using a straightforward IF clause, is here crucial.
In fact, the former will always return an error, whereas the latter, in general, will not.
The reason is that the former will resolve to (assuming that your table has e.g. 10 rows' worth of data and assuming some random Boolean results to the FREQUENCY construction):
=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},TRUE)*tdata[Column2])
which is, since the value_if_true clause is superfluous here:
=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])
whereas the second construction I give will resolve to:
=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))
The two may look identical, but the fact that the former is using multiplication to resolve the array, whereas the latter is not, is the key difference.
Although in both cases the array resulting from the FREQUENCY construction, i.e.:
{TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}
comprises 11 entries (i.e. 1 more than the number of entries in the second array being considered), the difference is that, when you then attempt to multiply an 11-element array with a 10-element array (i.e. tdata[Column2]), Excel, rather than outright disallowing such an operation, artificially redimensions the smaller of the two arrays such that it matches the dimensions of the larger.
In doing so, however, any additional entries are automatically set as #N/A error values.
Effectively, then:
=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])
is resolved as:
=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*{38;67;49;3;10;11;97;20;3;57;#N/A})
i.e., as mentioned, the second, 10-element array is redimensioned to one of 11 elements in an attempt to form a legitimate operation. And, as also mentioned, that 11th element is #N/A, which means of course that the entire construction will also result in that value.
In the non-multiplication version, however, i.e.:
=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))
although the same redimensiong also takes place, we are saved by our use of an IF clause in place of multiplication, since the above resolves to:
=SUM(IF({TRUE;FALSE;TRUE;FALSE;TRUE;TRUE;TRUE;FALSE;TRUE;FALSE;FALSE},{38;67;49;3;10;11;97;20;3;57;#N/A}))
and the Boolean FALSE in the 11th position here 'overrides' the error value in the equivalent position from the second array, since the above resolves to:
=SUM({38;FALSE;49;FALSE;10;11;97;FALSE;3;FALSE;FALSE})
Regards

NetSuite saved search filter records with min quantity

How do I apply following requirement in Saved Search criteria?
Filter all inventory items
Where min( {memberitem.quantityavailable} / {memberquantity} ) <> custitem_quantity
Note: custitem_quantity is a custom numeric field.
Note2: NetSuite is throwing error when I use min function in filters.
There is more than one issue here.
You have to be careful with custom numerics in Netsuite.
When your inner condition evaluates, it does not have the same type because it is fractional. At some point it has to be rounded and / or truncated internally. The other side of the expression would need to call a floor or ceiling function to remove everthing past the decimal.
Also, the min function evaluates after the <> conditional, which will be dependent upon whether your custom numeric is type compatible to begin with.
In the expression you provided us, it would have to be an exact match (and an exact type), and that is before you consider whether MIN gets to be evaluated.
Look at how the datatypes are cast and what columns you are processing because memberitem.quantityavailable may need a secondary index depending upon your dependencies and where the formula is being called. If this formula is being used over multiple products, it may not be logically consistent.
When I have similar items in inventory that I want to generate stats for I try to process it separately, even if I have to make a second pass.
What are you trying to isolate exactly - - I cannot think of a quantity-related situation where there would be a need to use division in this way - - please refer to the formula Mike Robbins listed above for a properly structured evaluation and see if it achieves the desired result.
If you post the rest of your code, I will help you resolve this.
The entire expression is not valid and will not evaluate due to the conditional shown, the MIN, nor the division. Index the count on the memberquantity if you are looking to sum over values. Otherwise, CountIF will work for quantities. MIN will only finds the lowest value in a given column, so SumIF appears to be what you are after. You can create a second expression which bounds the values you are searching for as a preliminary step.
I am new here, so please elaborate on what you are trying to accomplish so I can earn the bounty.
You may want to take into account null values as well to avoid errors or inconsistent data.
If you're using formula numeric, try this:
Formula(Numeric):
case when min((NVL({memberitem.quantityavailable},0) / NVL({memberquantity},0)) - (NVL{custitem_quantity},0)) then 1 else 0 end
'IS EQUAL TO' 1
I believe you can use the Formula Text or Formula Numeric Search Filter for that.

Resources