Nested OR with AND and IF - Excel - arrays

Simple question that I wasn't able to figure out. Trying to calculate counts and medians of arrays with a conditional that depends on numbers in two columns in Excel, as seen below.
=MEDIAN(IF(AND($D$3:$D$1216=1,OR($B$3:$B$1216=3,$B$3:$B$1216=6,$B$3:$B$1216=9,$B$3:$B$1216=12)),$M$3:$M$1216))
Please see above for the function, which I input as an array. All I'd like to do is scan Column D for all 1s and then 3/6/9/12 in Column B.
The function works but only returns zeroes for all relevant values in Column D, which I find strange.
Thank you for your help!

Is 0 in fact the most common element in $M$3:$M$1216? i.e., are a lot of those cells just blank?
When I keep the range large, but only enter a few values, I get the same result as you. When I shrink the range to something more manageable, and fill in the values, the function returns what I'd expect.
Also, here's a somewhat simpler syntax for the same result:
=MEDIAN(($D$3:$D$5=1)*OR($B$3:$B$5=3,$B$3:$B$5=6,$B$3:$B$5=9,$B$3:$B$5=12)*($M$3:$M$5))

Related

Dynamic Spill Formula For Reduce Function Mixed With Split

My sample sheet is probably easier to understand than my writing but here's the issue: I have a sheet that I'm trying to create a spill formula that sums an array of numbers up in each line.
Columns B:D is my existing data that's being evaluated
If values exist in Column D (which is not always the case), split values (defined by , ) and lookup each one's most recent entry (column B) and sum its value from column C with other members in same cell.
I can accomplish this using the Reduce formula shown in my sample data in blue column F, and dragging the formula to the latest entry, however it will not spill down dynamically.
=iferror(REDUCE(0,SPLIT(D2,",",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)
I can get the C values to spill down dynamically (as shown in green columns in sample) as numeric values, but I can't figure out how to sum them.
=Filter(iferror(XLOOKUP(SPLIT(D2:D,", ",false),B:B,C:C,"",0,-1),0),A2:A>0)
I would have expected something like either of these to work, but both generate a #N/A
=Filter(iferror(REDUCE(0,SPLIT(D2:D,", ",false),
lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0),A2:A>0)
=Filter(sum(iferror(XLOOKUP(SPLIT(D2:D,", ",false),B:B,C:C,"",0,-1),0)),A2:A>0)
I've also tried these as named functions with only the spilled variables as input, but same result.
I know the reduce function can perform a spilled range, as shown here on Ben Collins' site, however I can't figure out how to get it to do so with my dataset. It's occurred to me that because I'm generating a horizontal array, a verticle array may not be possible?
Any helpful answers will be upvoted if not accepted. Thanks.
Here's one approach:
=byrow(index(map(iferror(split(D2:index(D:D,match(2,1/(D:D<>""))),", ",0,1)),lambda(z,xlookup(z,B:B,C:C,)))),lambda(y,sum(y)))
To have your formula spill down you can use MAP or BYROW:
Your formula:
=iferror(REDUCE(0,SPLIT(D2,", ",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)
With MAP:
=MAP(D2:D7,LAMBDA(ζ,iferror(REDUCE(0,SPLIT(ζ,", ",false),lambda(total,value,xlookup(value,B:B,C:C,"",0,-1)+total)),0)))
Here's another solution using FILTER:
=MAP(D2:INDEX(D:D,MAX(ROW(D:D)*(D:D<>""))),LAMBDA(ζ,IFNA(SUM(FILTER(C:C,COUNTIF(SPLIT(ζ,", ",),B:B))),0)))

Excel Array formulas details and guidance needed (INDEX,MATCH and SUM/COUNTIF)

So I'm having difficulties understanding fully how arrays works and when they are used by excel and specifically what happens in the background.
From reading the past few hours I understand that one of the reasons my Index Match doesn't work without array is simply because its a multicriteria Match that I use as below:
{=INDEX(D30:E36,MATCH(F33&G33,B30:B36&C30:C36),2)}
From what I understand the reason is that Match returns a {x,y} result which classifies it as an array formula. But considering the point is to get a row number, if the row I'm looking for is 5 then Match will return a {5,5} for row number for Index. And then Index interprets this as just 5? or what exactly happens in the background here?
Then I found an article which showed how to circumvent the array formula and not need ctrl+shift+enter as shown below. How does the below change things and what happens in the background?
=INDEX(D30:E36,MATCH(F33&G33,INDEX(B30:B36&C30:C36)),2)
The below is a an array SUM/COUNTIF formula which counts unique cells only which does not work without array brackets. Why is that and how does it work? It involves maths so I'm not sure.
{=SUM(1/(COUNTIF(A1:A5,A1:A5)))}
Thank you!

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 arrange table data differently by using if, match, and index?

As shown in the attached image, I need to convert A2:D10 to the format of A12:E17. The 4 tables from F1 to AB12 are my experiments using if, match, and index. Same formula gets different results and it seems to be dependent on the row position of the tables. In My previous question, I was trying to pinpoint the problem to the if function.
What am I doing wrong here?
Thanks,
Lu
enter image description here
Again, as I said in your last question: The formula has not been array entered. Array formulas need to be confirmed with Ctrl-Shift-Enter.
Without that, the first array in the IF statement does not get resolved and the Match does not return the correct result.
Make use of the Evaluate Formula tool and step through the formula.
The merged cells don't help with the cell referencing. Unmerge the cells and fill in all the labels in row 1, then use this slightly amended formula and confirm it with Ctrl-Shift-Enter. Then copy across and down.
I hope that I get the English names of the functions right:
In D14 and following cells:
=INDEX($C$1:$C$5;MATCH(1;MMULT(($B$3:$B$10=$A14)*($A$3:$A$10=B$13);1);0))
The MATCH function tells which value (by number counted from the top) matches both conditions. The INDEX function returns this value from C1:C5.

Unexpected COUNTIF behavior when mixing number and text (EXCEL)

This question is about how Excel's COUNTIF function treats different data types when used as an array formula.
There are lots of good posts out there detailing how to use COUNTIF for tasks such as extracting unique values from a list, for example this post. I've managed to use examples from this and other posts to solve specific problems, but I'm trying to get a deeper understanding of array formulas in order to adapt my formulas to new needs.
I came across a peculiar behavior of COUNTIF. In general, Excel seems to treat strings as "larger than" numbers, so that the following examples are valid:
Cell Formula Returns
=1<2 TRUE
="a"<"b" TRUE
="a">"b" FALSE
=1<"b" TRUE
Now, suppose range A1:A6 contains the following data set:
1
2
3
A
B
C
For each cell in this set, I want to check how many of all the cells in the set that are smaller than or equal to that cell (a useful technique in more complex formulas). I enter the following array formula in range B1:B6:
{=COUNTIF($A$1:$A$6,"<="&$A$1:$A$6)} (CTRL + SHIFT + ENTER)
Based on the examples above comparing numbers and strings (also illustrated in Column D below), I would expect the output shown below to look like Column C. However, the array formula returns the result shown in Column B, which suggests that strings and number elements are counted separately by arraywise COUNTIF.
Column A Column B Column C Column D
1 1 1 A1<"C" = TRUE
2 2 2 A2<"C" = TRUE
3 3 3 A3<"C" = TRUE
A 1 4 A4<"C" = TRUE
B 2 5 A5<"C" = TRUE
C 3 6 A6<"C" = FALSE
So the question is how to produce the output in Column C? (EDIT: Just to clarify, I'm specifically looking for solutions that make use of COUNTIF's array properties.)
Any insight into why arraywise COUNTIF apparently behaves differently than the single-cell examples would also be much appreciated.
NOTE: I've translated the examples from a non-English version of Excel, so I apologize in advance for any typos.
PS. For a background, I ran into this problem when I tried to build a formula that would both extract unique values from a list with possible duplicates, and sort the unique values in numerical/alphabetical order. My current solution is to do this in two steps. One solution for how to do it in one step is proposed here.
First of all, excellently laid-out question, and on an interesting topic to boot.
I also raised an eyebrow when I first came across this behaviour of the COUNTIF(S)/SUMIF(S) functions. In their defence, I suppose we could construct situations in which we actually want strings and numerics to be considered separately.
In order to construct your required in-formula array, you will need something like:
MMULT(0+(TRANSPOSE($A$1:$A$6)<=$A$1:$A$6),ROW($A$1:$A$6)^0)
though note that the necessary transposition will mean that any set-up which includes this construction will require committing with CSE.
Regards
The different behavior can easily shown if you compare
=COUNTIF($A$1:$A$6,"<=A")
with
{=COUNT(IF($A$1:$A$6<="A",1))}
The first will only get text values from $A$1:$A$6 because it is clearly text to compare and it is faster ignoring other values then. =COUNTIF($A$1:$A$6,"<=3") will only get numeric values from $A$1:$A$6 because of the same reasons. Even if the criterion would be a concatination with a cell reference, then the concatination would be the first process and would lead either to "<=A" or "<=3". So it is ever clear what to compare, text or numbers.
The second first needs an array of the comparisons, then performs the IF, gets so an array of 1 or FALSE and counts then. But the "A" could also be a cell reference. So it is not clear what to compare at the beginning and the first array has to compare all values in $A$1:$A$6.
So COUNTIF(S) and SUMIF(S) cant be used comparing mixed text and numeric data.
The solution is shown already by XOR LX.
Btw.: with your PS. For a background you should consider the following solution from an German Excel site: http://www.excelformeln.de/formeln.html?welcher=236.
In your linked example:
Formula in B2 downwards
{=INDEX($A$2:$A$99,MATCH(LARGE(COUNTIF(A$2:A$99,">="&A$2:A$99)+99*ISNUMBER(A$2:A$99),ROWS($1:1)),COUNTIF(A$2:A$99,">="&A$2:A$99)+99*ISNUMBER(A$2:A$99),0))&""}
In this solution the COUNTIF compares with >= so the biggest text or number will count lowest and so get the lowest position. All number positions are added with 99. So they are ever greater than all possible text positions. So we have a descended sorted array. Then, using LARGE, the list is created from the highest to the lowest position.
I doubt that countif is the right function for what you want to achieve here.
try this (ctrl+shift+enter):
={SUM(IF(A1>=$A$1:$A$6,1,0))}
You will get
1
2
3
4
5
6
PS: CountIf is an basically an array function internally. Using it in another array function results into multiple array functions and their behaviour becomes complex. Array functions are best used with clear logical path.
As tested in Excel 2013, you will only get 1 in all results instead of what was proposed in Column B.
Currently, in the function provided by you, countif cannot figure out which cell to compare to which cell. Array functions expand ranges and then perform the provided action. Therefore, it is comparing each cell to same cell and resulting into 1.
Try this FormulaArray in B1 then copy till B6:
=SUM(($A$1:$A$6<=$A1)*1)

Resources