How to exclude zero entry from a dynamic formula (SUBTOTAL + SUMPRODUCT) in excel - excel

I'm working on a formula to get the standard deviation. It has been working not until I encountered a zero value which makes the result into #DIV/0!.
This is the screenshot of the expected value.
However, when I used my formula, the Game Time SD returned 0.
How do I exclude it in the calculation if the value in F column is zero? I tried IF(F5:F9 <> 0) but it won't work.
This is the formula I used.
F3 = IFERROR(SUBTOTAL(1,F5:F9),0)
G3 = IFERROR(SUMPRODUCT(SUBTOTAL(2,OFFSET(F5:F9,ROW(F5:F9)-MIN(ROW(F5:F9)),,1))*(G5:G9*F5:F9))/SUBTOTAL(9,F5:F9),0)
H3 = IFERROR(((SUBTOTAL(9,F5:F9)*(SUMPRODUCT(SUBTOTAL(2,OFFSET(F5:F9,ROW(F5:F9)-MIN(ROW(F5:F9)),,1)) *
((H5:H9^2*F5:F9*(F5:F9-1)+(G5:G9*F5:F9)^2)/F5:F9)))-(SUMPRODUCT(SUBTOTAL(9,OFFSET(G5:G9,ROW(G5:G9)-MIN(ROW(G5:G9)),,1)),SUBTOTAL(9,OFFSET(F5:F9,ROW(F5:F9)-MIN(ROW(F5:F9)),,1))))^2)/(SUBTOTAL(9,F5:F9)*(SUBTOTAL(9,F5:F9)-1)))^(1/2),0)
I know the problem is somewhere in F5:F9, since the divisor used is zero

The part you suspected in the code involves dividing by a denominator that happens to be a factor in the numerator. You can avoid a division by zero by simplifying that fraction.
((H5:H9^2*F5:F9*(F5:F9-1)+(G5:G9*F5:F9)^2)/F5:F9)))
can be reduced to
(H5:H9^2*(F5:F9-1) + (G5:G9^2*F5:F9))
Resulting in the formula (3rd line modified)
=IFERROR(((SUBTOTAL(9,F5:F9)*
(SUMPRODUCT(SUBTOTAL(2,OFFSET(F5:F9,ROW(F5:F9)-MIN(ROW(F5:F9)),,1))*
(H5:H9^2*(F5:F9-1) + (G5:G9^2*F5:F9))))-
(SUMPRODUCT(SUBTOTAL(9,OFFSET(G5:G9,ROW(G5:G9)-
MIN(ROW(G5:G9)),,1)),SUBTOTAL(9,OFFSET(F5:F9,ROW(F5:F9)-
MIN(ROW(F5:F9)),,1))))^2)/(SUBTOTAL(9,F5:F9)*
(SUBTOTAL(9,F5:F9)-1)))^(1/2), 0)
In my tests without the enclosing IFERROR, I could set some rows to zero and get values. Only when the square rooted subtotal was negative (which logically should not happen) was the result #NUM.
Hope this helps.

Related

Can't figure out why excel is rounding currency

Here is my excel table:
The cell with 8.83 = =((C8-B8)*24)-D8
*C8 = 4:50PM
*B8 = 7:30AM
*D8 = 0.50
The cell $371.00 = =(E8*B3)
Why does my total show $371.00 when B3 = $42? It should be $370.86. I don't have it set to round but for some reason it keeps on doing it.
Because, the actual result of formula =((C8-B8)*24)-D8 is 8.833333333. Due to cell formatting you are seeing 8.83. If you want result for only two digit after decimal point then use round function like-
=ROUND(((C8-B8)*24)-D8,2)
Then you will get result 370.86. Or you can directly use in resulting cell.
=ROUND(E8,2)*B3
$371 is “technically” the correct amount, mathematically. You are actually doing rounding when you are hand-calculating your cross-check, and that isn’t matching Excel’s unfounded calculation.
( 4:50pm - 7:30am ) is 9.3333333 repeating, or “9-1/3”. Divided by 24 leaves you 8.8333333 repeating, not 8.83. Excel is doing what it’s supposed to do, and 371.00 is the correct amount. If your use case calls for times to be rounded to .01 hours and no further then you’ll need to apply rounding somewhere in cell E8.

Odd value returned by LEN in EXCEL

Consider, for example, the following function strings inside some cells:
A1 = B1 - INT(B1)
A2 = LEN(A1)
A2 will return 17 regardless of the value returned by the function (and thus held) in A1. I suspect that this has to do with the precision returned by INT(B1), but I don't know enough of Excel's inner-mechanisms to confirm.
The end goal is to obtain the length of the decimal part of a number held in B1. For example, if B1 = 978.01194, A2 would hold 5 (LEN(01194)). Obviously this would require a subtraction of 2 to eliminate the counting of the leading (0.) in my implementation above, but that's assuming I can get proper results with this method. Any help or guidance in other methods would be greatly appreciated!
EDIT:I realized that the loss of proper precision occurs only when I subtract the two quantities. INT(B1) returns proper precision, and using its length I can obtain the decimal by subtracting from the original. Would still like to know what is causing the operation in A1 to lose precision internally for LEN.
Alternatives are to use number that is not result from a calculation :
= LEN(B1) - LEN( INT(B1) ) - 1
or round the number to less than 15.95 significant digits :
= LEN( ROUND( B1 - INT(B1), 16 - LEN(INT(B1)) ) ) - 2
= LEN(TEXT(B1,"0.##############")) - LEN(INT(B1)) - 1
Another alternative is to FIND where the decimal occurs and use that as an offset, e.g.
= LEN(B1)-FIND(".",B1)
In general, it is not wise to perform a mathematical operation on a number when what you are really interested in is the text that represents the number for this exact reason. Floating points are not very reliable for dealing with exactness which is why you are experiencing the extra trailing numbers after the decimal in this case.

Round to nearest integer non-zero

I am looking to come up with a crafty and "nice-looking" way of rounding to the nearest NON-ZERO whole number (I will only ever have positive integers). Three restraints I have are:
Must be a non-UDF solution as I will have some users who will want to trace formulas. Even though a VBA solution will result in a cleaner entry in the formula bar, they are not easily traceable by "front-end" users.
Some of the cells I am looking to round are quite long formulas themselves.
Think something like =(SUMPRODUCT((A1:A20),(B1:B20)) / SUMPRODUCT((A21:A40),(B21:B40))) - (SUMPRODUCT((A41:A60),(B41:B60)) * SUMPRODUCT((A61:A80),(B61:B80))) + SUMPRODUCT((A81:A100),(B81:B100))
I am unable to round the values in A1:B100 to make it whole numbers to begin with.
I am unable to use the cells with my formulas as a reference due to how the sheet must be styled for users. (e.g. I can only have one column of visible cells with my results. Therefore, if I used the formula cells as a reference, the formula cells would have to be hidden. This breaks restraint #1 because users would have difficulty with formula tracing.) This restraint is described in more detail below.
The most succinct formula I can think of is thus:
=IF(AND(C1 > 0, C1 < 1), ROUNDUP(C1, 0), ROUND(C1, 0))
Due to #3, I cannot use C1 as a reference. So my end result would be more like:
=IF(AND((SUMPRODUCT((A1:A20),(B1:B20)) / SUMPRODUCT((A21:A40),(B21:B40))) - (SUMPRODUCT((A41:A60),(B41:B60)) * SUMPRODUCT((A61:A80),(B61:B80))) + SUMPRODUCT((A81:A100),(B81:B100)) > 0, (SUMPRODUCT((A1:A20),(B1:B20)) / SUMPRODUCT((A21:A40),(B21:B40))) - (SUMPRODUCT((A41:A60),(B41:B60)) * SUMPRODUCT((A61:A80),(B61:B80))) + SUMPRODUCT((A81:A100),(B81:B100)) < 1), ROUNDUP((SUMPRODUCT((A1:A20),(B1:B20)) / SUMPRODUCT((A21:A40),(B21:B40))) - (SUMPRODUCT((A41:A60),(B41:B60)) * SUMPRODUCT((A61:A80),(B61:B80))) + SUMPRODUCT((A81:A100),(B81:B100)), 0), ROUND((SUMPRODUCT((A1:A20),(B1:B20)) / SUMPRODUCT((A21:A40),(B21:B40))) - (SUMPRODUCT((A41:A60),(B41:B60)) * SUMPRODUCT((A61:A80),(B61:B80))) + SUMPRODUCT((A81:A100),(B81:B100)), 0))
Not very "nice-looking".
Any recommendations?
EDIT Overly complex formulas removed
Another, simpler option
=MAX(1,ROUND(your_formula,0))
My formula assumes that your_formula will only return a positive value. If that is not the case, please clarify what results you expect for zero or negative results.
EDIT
With regard to possible zero values, try this. I cannot test it since I am not at computer:
=--(TEXT(your_formula, "[>1]0;[>0]1;0"))
Except for negatives (of which there aren't any) this formula:
=(C1<>0)*IF(C1<1,1,ROUND(C1,0))
produces the same results as:
=IF(AND(C1>0,C1<1),ROUNDUP(C1,0),ROUND(C1,0))
and is 15 characters shorter.
It deals with 0 with (C1<>0) by returning FALSE when C1 is zero, which the * effectively converts to 0. Otherwise TRUE and then by multiplying by 1 instead of 0 it does not affect the result of the rest of the formula.
The IF statement then tests whether or not C1 is less than 1. If so, returns 1 and otherwise applies standard rounding (to integers).
The formula might be shortened if the output range were formatted with Cells Format but otherwise anything more succinct is quite likely to be less intelligible - and may be more a matter for Programming Puzzles & Code Golf than SO.
Though:
=--(TEXT(C1,"[>1]0;[>0]1;0"))
is indeed 4 characters shorter still.

How to use "or" in Excel Solver constraint

I am adding a constraint to Excel Solver.
The constraint is saying an input data at location A3 must be either 0 or between 3 and 8.
How could I add this constraint in Excel Solver since I could not find 'or' function in solver constraint box. It only has ">=", "<=", "=", "int", "bin", "dif" operators there.
Many Thanks
This is a little bit of a hack, but you could create a function that is zero when your constraints are met, and nonzero when they are not. For example, if you have (in named ranges) a number of individual values val_1, val_2 etc. that are all valid, and a range llim and ulim (lower and upper limit), then the following equation will evaluate to zero if your conditions are met:
=(A3 - val_1) * (A3 - val_2) * FLOOR.PRECISE(ABS((A3 - (llim + ulim) / 2) / ((ulim - llim) / 2)))
When cell A3 is either val_1 or val_2, you will multiply your expression by zero; and when A3 is between llim and ulim, the expression inside the FLOOR.PRECISE() function will evaluate to something smaller than 1 - so the FLOOR will be zero.
Enter that expression in a cell, and make your constraint that this cell must be zero... It ought to work. It did for me - with the function to optimize being "3 * A3", and limits set to 3 and 8, the solution was 7.99999.
Note - one problem with this is that you will most likely get the solver "stuck" in just one interval - it will never notice the other possible values. If that is important, you may have to come up with a transformation of a continuous variable into one that has discrete values plus a range. Example:
=IF(A3<-1,val_1,IF(A3<0,val_2,llim+(ulim-llim)*ATAN(A3)*2/PI()))
Now A3 can vary over the full range, and yet the cell with this formula in it will always have a "valid" value in it. Again, if you need more fixed values you can add more nested IF statements...
It is used for the purpose where the situation is if one condition is also correct then it should show true.

Binning in Excel

Which formulae in MS Excel can we use for -
equi-depth binning
equi-width binning
Here's what I used. The data I was binning was in A2:A2001.
Equi-width:
I calculated the width in a separate cell (U2), using this formula:
=(MAX($A$2:$A$2001) - MIN($A$2:$A$2001) + 0.00000001)/10
10 is the number of bins. The + 0.00000000001 is there because without it, values equal to the maximum were getting put into their own bin.
Then, for the actual binning, I used this:
=ROUNDDOWN(($A2-MIN($A$2:$A$2001))/$U$2, 0)
This function is finding how many bin-widths above the minimum your value is, by dividing (value - minimum) by the bin width. We only care about how many full bin-widths fit into the value, not fractional ones, so we use ROUNDDOWN to chop off all the fractional bin-widths (that is, show 0 decimal places).
Equi-depth
This one is simpler.
=ROUNDDOWN(PERCENTRANK($A$2:$A$2001, $A2)*10, 0)
First, get the percentile rank of the current cell ($A2) out of all the cells being binned ($A$2:$A$2001). This will be a value between 0 and 1, so to convert it into bins, just multiply by the total number of bins you want (I used 10). Then, chop off the decimals the same way as before.
For either of these, if you want your bins to start at 1 rather than 0, just add a +1 to the end of the formula.
Best approach is to use the built-in method:
http://support.microsoft.com/kb/214269
I think the VBA version of the addin (step 3 with most versions) will also give you the code.
Put this formula in B1:
=MAX( ROUNDUP( PERCENTRANK($A$1:$A$8, A1) *4, 0),1)
Fill down the formula all across B column and you are done. The formula divides the range into 4 equal buckets and it returns the bucket number which the cell A1 falls into. The first bucket contains the lowest 25% of values.
General pattern is:
=MAX( ROUNDUP ( PERCENTRANK ([Range], [TestCell]) * [NumberOfBuckets], 0), 1)
You may have to build the matrix to graph.
For the bin bracket you could use =PERCENTILE() for equi-depth and a proportion of the difference =Max(Data) - Min(Data) for equi-width.
You could obtain the frequency with =COUNTIF(). The bin's Mean could be obtained using =SUMPRODUCT((Data>LOWER_BRACKET)*(Data<UPPER_BRACKET)*Data)/frequency
More complex statistics could be reached hacking around with SUMPRODUCT and/or Array formulas (which I do not recommend since are very hard to comprehend for a non-programmer)

Resources