Excel: Can you use IFS for multiple criteria on median - excel

Excel does not have a function to sort for multiple criteria for MEDIAN() as it does with AVERAGEIFS() or SUMIFS().
I have been sorting multiple criteria for median with nested IF() statements. For example, suppose I have a rent roll and I'm looking to calculate the median rent of a particular unit type that's occupied, I would do:
=MEDIAN(IF(unitType="1x1",IF(leaseStatus="Occd",rent)))
Where unitType, leaseStatus, and rent are arrays of data.
Is it possible to rewrite this function using IFS()? I have not been successful. I tried for example:
MEDIAN(IFS(unitType="1x1",leaseStatus="Occd",rent))
with no success.
Thanks in advance.
This post does not discuss how:
Optimizing multiple-criteria IFs

Here /screenshot(s) refer.
RE your Q:
"Is it possible to rewrite this function using IFS()? "
(1) (v.) SHORT ANS..
YES
(if one must... cf. cell G8):
=MEDIAN(IFS((Table1[Letter]="A")*(Table1[Colour]="blue"),Table1[value],1,""))
High level conclusions
See below for further info RE: M1-4 (corres. Method 1-4 resp.)
M1. Nested if (M1, given) is natural starting pt. yet rendered unnecessary by latest software version (i.e. Office 365 compatible Excel); thus room for improvement/refinement remains
M2. Prosaic 'single-if' method appears to be an improvement over M1 given elimination of nested if method (however, this depends upon one's defn. of optimality to begin with).
M3. Parsimonious: filter - per below: recommended method provided Office 365 Excel version is avail. (failing which, M2)
M4. Ifs (M4) possible yet inappropriate/superfluous given nature of
filter in Q
---------------------------------------------------------------------
(2) VARIANTS & REL. MERITS
IFs statement akin to If/else if/else if etc. compound statement; you're looking for a compound If statement as opposed to a series of sequential filters that suffer from the unnecessary ordered dependency for the filtration in question.
Here is a comparison table highlighting relative merits/otherwise for 4 different methods/calc. bases (incl. the variant given in the body of the Q [M1] and the IFs variant / equivalent [M4]:
functions corres. to respective cells/comparison table (G5-G7):
M1: cell G5
(see Q for gen. basis of formula/compound-nested If function)
M2: cell G6
M3: cell G7
M4: cell G8
Relies upon double ifs per Q.
fn: see v. first function 'v. short A' above
---------------------------------------------------------------------
(3) COMPARISON OF M1-4
See table in first screenshot provided above

Related

Excel advanced vlookups for a schedule comparison

I wondering if anyone will be able to help me sort the formula below out:
=IFERROR((VLOOKUP($D96,August!$C:$P,F$78,FALSE))-(VLOOKUP($D96,July!$C:$O,(F$78+1),FALSE)),IF(U96="NEW PART",(VLOOKUP($D96,July!$C:$O,(F$78+1),FALSE)),IF(V96="NEW PART",(VLOOKUP($D96,August!$C:$O,(F$78),FALSE)),"")))
Originally the formula was
=IFERROR((VLOOKUP($D95,August!$C:$P,F$78,FALSE))-(VLOOKUP($D95,July!$C:$O,(F$78+1),FALSE)),"BLANK")
However rather than returning "BLANK" if either sheet does not include that part number I would like the formula to return the figure on the one sheet they appear on. Columns U and V highlight weather the product number is on each sheet. These figures would be + figures if they appear in august and minus figures if they appear in July.
Link/screenshot refer:
In short - replace final 'FALSE' with an additional iferror(Aug,-July)
(see revision at end, following comments / feedback re sound applications/customizing soln as required)..
Formula - per OP request
=IFERROR(VLOOKUP(H4,B4:C14,2,FALSE)-VLOOKUP(H4,E4:F14,2,FALSE),IFERROR(VLOOKUP(H4,B4:C14,2,FALSE),-VLOOKUP(H4,E4:F14,2,FALSE)))
Improvised version
(pre-requisite: Office 365 compatible version of Excel)
=LET(A,INDEX(C4:C14,MATCH(H4#,B4:B14,0)),B,INDEX(F4:F14,MATCH(H4#,E4:E14,0)),IFERROR(A-B,IFERROR(A,-B)))
Motive
Arguments in favour of this version include:
OP version: 127 chars (vs 104) i.e. ~20-25% length reduction on this basis
Audit/review - arguably easier given let function
Flexibility: unless you plan to take advantage of vlookup 'approximate matching' (using True flag instead of False), Index more robust in that it can handle forward and backward references in relation to the indexed column (i.e. with vlookup, index has to lie to left of the column comprising the cell to be returned)
The usual benefits assoc. with 'spill' ranges (i.e. potential for 'dynamic' range feature and automatic calc. from single cell entry)
REVISION:
The following screenshot should shed some light on references/ranges you may wish to alter for 1st formula in present response to operate as you intend within your workbook (corresponding ranges are colour-coded with clear visual link between each)...
So to apply in your case, you'd need to replace shaded/boxed ranges/references in my proposal with those you're using (as indicated - i.e. replace by H4 with your $D95 etc,..."
JB: replace final 'FALSE' with an additional iferror(Aug,-July)
This concept is clearly delineated within screenshot above.
OP: "I tried and just got N/A"
As link in opening line provides evidence of two alternative solns. working error-free, presume 'n/a' result of incorrect application...

Excel - Row-wise calculation without helpers

Recently I answered a question about how to retrieve the MEDIAN() of each MEDIAN() in a 2-column matrix without helpers, e.g:
The row-wise calculation without helpers wasn't too hard because the median with only two values is always the average. Therefor a simple formula was all it took:
=MEDIAN((A1:A3+B1:B3)/2)
But for curiosity sakes however, wat if I would have at least a 3-column matrix?
The median will actually need to be calculated. Here the medians are {8,2,2}.
I can't seem to find a way to to get a row-wise calculation for 3+columns. In this case it's about MEDIAN() but I can imagine there could be other functionalities. Since this could be simplified data I don't want to resort to something like =MEDIAN(MEDIAN(A1:C1),MEDIAN(......
I tried to fiddle around with OFFSET(), though not a fan of volatile functions I was hoping it would either work directly with an array, or would be triggered correctly through using MEDIAN(LET(X,SEQUENCE(ROWS(A1:A3)),MEDIAN(OFFSET(A1:C1,X-1,0)))). I then moved on to combinations of either MMULT() or LARGE(), however none of my attempt were succesfull.
Question
So the question ultimately is; how do we return the result (array) of an row-wise calculation without helpers. And if not possible, that's also a perfectly fine answer so I can rest my head =)
New Answer
With the new BYROW() function one could use:
=MEDIAN(BYROW(A1:C3,LAMBDA(a,MEDIAN(a))))
The nested LAMBDA() in the 2nd parameter makes it a piece o' cake to loop all rows in a dynamic array (not a range per se).
Previous Answer (Pre-BYROW())
So. After a long thought, as far as my understanding goes this is not possible through current formulae. However, currently in BETA, Excel365 will feature the new LAMBDA() function which makes it possible to create your own function without VBA and even recursively call itself. It isn't the prettiest of solutions but I thought I would share what I did here:
Formula in E3:
=MED(A1:C3,"",ROWS(A1:A3))
Where MED() is our own LAMBDA() function created at the "name manager" menu. It reads:
=LAMBDA(rng,txt,rws,IF(rws=0,MEDIAN(FILTERXML("<t><s>"&txt&"</s></t>","//s")),MED(rng,TEXTJOIN("</s><s>",,txt,MEDIAN(INDEX(rng,rws;0))),rws-1)))
As can be seen there are 4 main parameters of which 3 variables:
rng - The range to be examined.
txt - A reserved variable to be used in FILTERXML().
rws - A counter.
The 4th parameter is a nested IF() which if the counter is as 0 will return the median of all medians. This is done through FILTERXML() which I will not get into detail right now.
If the counter is not yet at 0 it will recursively call the LAMBDA() function untill it is, and what it does is using the same three parameters but we can alter them right there and then. Therefor we leave rng intact, we concatenate the MEDIAN() of the row (current counter) through TEXTJOIN() to create a valid xml construct. And last but not least we need to lower the counter.
It's a struggle, but with LAMBDA() it will now be possible to do a rowwise calculation.
Note, if you are interested in the FILTERXML() construct, you might like this post where I now also included a LAMBDA() version of a SPLIT() function.

Is it possible to return a dynamic formula in VLOOKUP?

I am looking for a possibility to use VLOOKUP in combination with a dynamic formula (or a different solution if possible).
A simplified problem is provided in the image below. Based on a category the number of outlets in a room is calculated. The number of outlets can either be a fixed amount or based on the total area of a room which is provided in a separate column.
What is the best method to apply this to a (much larger) sample?
If "based on total area" is always a x per unitA, then enter it as a proportion, e.g.: 0.1a instead of 1 per 10 m^2, and use a formula that checks for the trailing 'a' and responds accordingly. e.g.:
=IF(RIGHT(VLOOKUP(B2,$F$2:$G$3,2,FALSE),1)="a",CEILING.MATH(SUBSTITUTE(VLOOKUP(B2,$F$2:$G$3,2,FALSE),"a","")*C2),VLOOKUP(B2,$F$2:$G$3,2,FALSE))
(I used "Ceiling" to get the integer value. Replace with Floor or Round as needed).
Probably easier from a formula writing (and readability) POV would be a separate column that holds the a (or rather: a "fixed/proportional" column) and key off of that, but the result is the same.

Iterative/Looped Substitute without VBA

Abridged Question:
If I have a concatenated string of "|#|#|#|...|#|", how can I apply a multiplier to each of the numbers and update the concatenated text? For example, for |4|12|8|, multiply by a factor of 2 and update the concatenated text to |8|24|16|.
Background
I have three columns of interest. The first column contains a date, the second an amount or factor, and the third column concatenates data into the format "|#|#|...|#|" (e.g., |2|5|, |2|5|12|, |4|12|, etc.). At times, a multiplying factor needs to be applied to the concatenated data, and the individual numbers would need to be updated accordingly.
An example would be—
Date Amt Concatenated Data
01/01/18 2 |2|
01/05/18 5 |2|5|
02/06/18 12 |2|5|12|
03/25/18 -3 |4|12|
03/31/18 8 |4|12|8|
04/01/18 F2 |8|24|16| (factor of 2 applied)
04/15/18 12 |8|24|16|12|
04/01/18 F1/4 |2|6|4|3| (factor of 1/4 applied)
With a formula, how can I apply the factor to the concatenated data, and update the individual numbers?
I'm bound by the following conditions:
Excel 2007, so no TEXTJOIN function
No VBA or UDFs (due to security policies)
Individual numbers are dynamic (i.e., I can't use a static value for the "old_text" parameter of the SUBSTITUTE formula)
Amount of individual numbers within concatenated data is also dynamic (may contain one number, or may contain dozens of different numbers)
I can pull out the individual numbers using an array formula. I can even then multiply those numbers by the factor to produce an array result. However, I can't rebuild the concatenated data, because CONCATENATE doesn't work on an array. I've also tried SUBSTITUTE, but I can't iterate through the "|" separators. I can only substitute a given segment (e.g., change all entries of "|2|" to "|4|"). Nesting SUBSTITUTE or using individual columns won't work, since it could potentially involve dozens of instances.
Just to add some info on the concatenated data:
Amt>0, then value is concatenated to the end of the previous concatenated value
Amt<0, begin reducing individual numbers in concatenated value (CV) until reduction amount reached (e.g., for |2|5|12| and Amt=-3, reduce CV to |4|12|, which is -2 from the first segment and -1 from the second segment)
Amt reduction is limited to the sum of the previous CV's individual numbers (e.g., for |4|12|, the reduction cannot exceed 16)
Amt=F#, indicates a multiplying factor, and the CV's numbers need to be updated
The CV has no max (could have dozens to hundreds of individual numbers, with numbers going from 1 to 100,000+), other than any max applied by Excel itself on string length
HIGH LEVEL
Four parts to this solution
They satisfy pre-requisites (2007 compatibility, no VB, no Office 365 requirement, no custom VB functions, provide for complete 'dynamic' nature of variable length of cells to concatenate)
Caveat: to best knowledge / research, there is no parsimonious single-cell function & therefore an interim step has been proposed)
One more caveat: I imagine the simple 'hack' of wrapping a graph around the delimited data is out of question (see 'Other/Various' below ☺)
PARTS 1-4
Accompanying parts 1-4 below are functions which relate to the following screenshot:
I have also uploaded / amended to meet requirements of Google Sheets (see here)
Parts 1 & 2:
Similar in that they rely upon FilterXML technique to count component / terms, and split cells respectively:
Part 1:
=COUNT(2*TRANSPOSE(FILTERXML("<AllText><Num>"&SUBSTITUTE(LEFT(MID(D12,2,LEN(D12)-1),LEN(MID(D12,2,LEN(D12)-1))-1),"|","</Num><Num>")&"</Num></AllText>","//Num")))
Note: google sheets doesn't recognise FilterXML, so have amended technique/functions accordingly. For instance, above can be determined using counta on the split cells in Part 2 (easier / much more simpler than proposed approach above, albeit less robust given any cells lying to the right of the split cells will interfere with ordinary functionality of this approach).
Part 2:
It's either a manual approach, a fancy series of 'mid' &/or substitute / left/right functions, or the following FilterXML code which, per various sources (e.g. here) should be compatible with Excel 2007:
=IF(LEFT(C12,1)="F",1*SUBSTITUTE(C12,"F",""),1)*TRANSPOSE(FILTERXML("<AllText><Num>"&SUBSTITUTE(LEFT(MID(D12,2,LEN(D12)-1),LEN(MID(D12,2,LEN(D12)-1))-1),"|","</Num><Num>")&"</Num></AllText>","//Num"))
Commonality with Part 1 (re: FilterXML) can be seen - the only difference is that the count(Part 1) has been replaced with the transformation (multiplicative factor, as given in O.P's Q).
Part 3
Nothing fancy here - a simple concatenation (which is a far cry from a 'recursive' substitution function, I know, but hey - it does the trick and can always be placed in a mirror copy of the original sheet to avoid space issues/cell interaction issues)
=IF(H12="","",IF(G24="","|","")&G24&H12&"|")
Part 4
Thanks to the number of terms derived in Part 1, an offset function can easily determine the final cell pertaining to the concatenated 'build up' of 'transformed' values (per Part 3):
=OFFSET(H31,0,E31-1,1,1)
OTHER / VARIOUS
Various other proposals and 'workarounds' exist; unfortunately, these appear to fall short in one way or another of the pre-requisites set forth, videlicit:
a) Function/formula based
b) No VB
c) Excel 2007
d) Dynamic (variable/unknown number of terms)
Manual: e.g. function = concatenate(transpose(desired range)), and then components of the concatenate function and pressing F9 to convert to calculated values, which are readily applicable in the concatenate function. Disadvantage: time consuming in relation to 'automated solution' (needs to be done for each applicable toy). Advantage: no additional 'spreadsheet real estate' required, quicker/straightforward implementation in first instance.
Variants of the 'build-up' method: e.g. per Part 3, however, this alone does not ensure for an automated approach across an unknown number of terms in the original concatenated list.
Have mentioned in a previous solution (here), but may be case that you are eligible for Office 365 functionality whilst on a previous version of Excel (see Office Insider here)
Other proposals (above/below in this forum mind you) propose textjoin (so not sure if this is a comprehension issue or what ☺)
And yes, as alluded to at outset, you can easily achieve the desired outcome using a simple graph! Just for fun then, sort the data in reverse order, and include the split/delimited values as a bar graphs' "x-values" (which, by defn. for this type of graph, will now appear along the ordinary Cartesian 'y/vertical' axis)...
Zero points for this but thought it was an interesting discovery on my part!
(and if still in doubt, here's what the 'graph' would look like if I didn't kill everything except for the axis labels...):
Numerous references for relevant other items above, including research areas, as follows:
Excel Champs
StackOverflow - alternative applications for FilterXML
JUST ONE MORE THING...
In true Columbo style modus operandi, other ideas/approaches considered:
Application of pivot table?
Constructing matrices: I got a solution with a series of offset functions, but couldn't think of a feasible way to implement given space issues
Converting the split cells into a long digit through summation: e.g. 8 22 16 = 80 000 + 22 00 + 16. Using a substitute function with text (long digit, "General") I was able to successfully introduce the delimiter character ('|') for pairs of adjacent 'tuples' (e.g. I could get '8|2216', '822|16', but then a 'build up' formula where one cell depends upon converted values of the previous and so one was required once more, which landed me back to the proposal I have set out above
fyi - the matrix consideration only solves tuples of 2, for n-dimensional /combination one would need to 'pass' a string of characters over its mirror copy - e.g. {6,10,22} would pass over {6,10,22}, ignoring duplicate values would yield a trapezium as follows:
6
10
22
6
10
22
6
10
22
after the copy has 'passed' over the original (first row), we have the desired combination (22,10,6) (on the 'diagonal' such a matrix). This is akin to how Fourier Transforms work (kind of); but that aside, it was tempting to construct a matrix like this, but couldn't be bothered at this stage.
Will probably turn out to be a far simpler way that someone comes up with (I won't be the only person surprised based upon the various sources I've considered...)

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