Excel conditional counting - excel-formula

This is a doubt that arose in my workplace, and it should be pretty straightforward.
We have two columns of numbers, say:
1 1
1 2
2 1
2 2
And we want to get the number of rows that have equal numbers (2), without a helping column for each comparison. We can't get a working matrix operation (wich is the way we think correct). Any ideas?
Thanks in advance!

Three more to pile on here:
Condensed array function:
{=SUM(--(A1:A10=B1:B10))}
Same function, but wrapped in a SUMPRODUCT rather than an array function:
=SUMPRODUCT(--(A1:A10=B1:B10))
Ignores blanks:
=SUMPRODUCT(--(A1:A10=B1:B10)*NOT(A1:A10="")*NOT(B1:B10=""))

We got it using:
{=SUM(IF(A1:A10=B1:B10;1;0))}

Related

EXCEL - Filtering rows by multiple OR conditions

I have this problem I'm trying to solve in EXCEL, hopefully it's a straightforward one somebody can help with.
Essentially I Have 6 columns, which can be of values 'compliant' or 'missing'.
What I'd like to achieve is that in the 7th column, 'compliant' or 'non-compliant' is written, if the following conditions are met:
1 of column N,L,J is missing (i.e. max of 2 'missing')
Or any of P,V,Z is missing (i.e. none can be 'missing')
I hope that makes sense. At the minute I've cobbled together this horrible formula, but I think I'm on the wrong track completely:
=IF(OR(N2="Missing",L2="Missing",J2="Missing"),"Non-compliant",""),IF(OR(P2="Missing",V2="Missing",Z2="Missing"),"Non-compliant","")
I think the logic you have is close but I don’t think an if statement can check if less than two cells are equal to something. My approach would be to sum a few Boolean values by converting true to 1 and false to 0 with the INT function. So:
=if(or(sum(int(N2=“missing”),int(L2=“Missing),int(J2=“missing))>1,sum(int(P2=“missing”),int(V2=“missing”),int(Z2=“missing”))>0),”non-compliant”,””)
Hope this helps!
=IF(AND(COUNTIF(J1:N1,"m")>1,OR(P1="m",V1="m",Z1="m")),"non-compliant","compliant")

CountIF returns 0 with array and criteria in formula

I have a large array of data, consisting of start and end date/time for license use. I'm trying to count how many users are active at the same time.
I'm using the below formula, but I get a return value of 0 some places, which basically shouldn't be possible.
=CountIFs(E$2:E$5616;"<="&E1108;F$2:F$5616;">"&E1108)
Is the approach wrong or is there a better one?
Edit: Added extra screendump showing the 6 places I have a 0 returned. Have run a clean and trim on the data as well, with no changes to the output.
Edit2: Added npciture showing the difference between my two CountIf and Sumproduct outputs. Is there something I'm missing here, the data should be exactly the same so the output should be 1 and 2 for everything?
Try using SUMPRODUCT instead of COUNTIFS, since it isn't susceptible to the same number coercion issues:
=SUMPRODUKT(--(E$2:E$5616<=E2);--(F$2:F$5616>E2))
Try:
=COUNTIFS(E$2:E$5616, "<=" & E1108, F$2:F$5616, ">" & E1108)
Replace , with ;

Sumproduct with multiple criteria on one range

In a dataset I have answers that participants to a survey gave. The answers are in one example numbered 1 to 5, with 1 being yes, and 2 to 5 being variants of no.
20 or so similar questions have been asked, and participants can be in either one of 20 subgroups. Questions were categorized into 6 classes.
Now the best way to go about such a dataset would normally be the use of a pivot-table, however the way the data is set up doesn't work with a pivot table, and due to the sheer size of the dataset remodelling isn't efficient.
To extract the amount of people in a certain subgroup that answered yes for questions in a certain class I use the following function:
=SuMPRODUCT(--(Test!D$4:$CC$1824=1)*(Test!$C$4:$C$1824=$C3)*(Test!$D$3:$CC$3=D$2))
In which Test!D$4:$CC$1824 is the range where answers are given, and the other two are ranges for subgroup and classes respectively.
By using --(Test!D$4:$CC$1824=1) I convert all data to 0's except for where participants answered yes (cell value = 1).
Now I would like to do the same thing for where they answered no, so the value is either 2 or 3 or 4 or 5. The ideal way would be to append some OR logic into the first test, coming about something like this: --(Test!D$4:$CC$1824={2,3,4,5})
Ofcourse this doesn't work, but is there any simple notation besides retyping the first part 4 times, and adding them together?
I'd say you could just use >1 instead of =1
For selected results like 1 and 3 and 5 you probably need to add the sumproducts of each number.
Sidenote: the -- is not necessary anymore as it is just for converting true and false to 1 and 0 when there is only one bracket inside sumproduct
The OR operation can be mimicked by adding all of the possibilities together.
=SuMPRODUCT(((Test!D$4:$CC$1824=2)+(Test!D$4:$CC$1824=3)+(Test!D$4:$CC$1824=4)+(Test!D$4:$CC$1824=5))*
(Test!$C$4:$C$1824=$C3)*(Test!$D$3:$CC$3=D$2))
If there is any possibilitiy that two could be correct (in this case there isn't) wrap the sum in the SIGN function to get only zero or one.
=SuMPRODUCT(SIGN((Test!D$4:$CC$1824=2)+(Test!D$4:$CC$1824=3)+(Test!D$4:$CC$1824=4)+(Test!D$4:$CC$1824=5))*
(Test!$C$4:$C$1824=$C3)*(Test!$D$3:$CC$3=D$2))

Rank the top 5 entries in different criteria

I have a table that I want to find the top X people in each of the different groups.
Unique Names Number Group
a 30 1
b 4 2
c 19 3
d 40 2
e 1 1
f 9 2
g 15 3
I've ranked the top 5 people by number by using =index($A$2:$A$8,match(large($B$2:$B$8,1),$B$2:$B$8,0)). The 1 in the LARGE function I linked to a ranked range so that when I dragged down it changed up the number.
What I would like to do next is rank the top x number of people in each group. So top 3 in group 1.
I tried =index($A$2:$A$8,match("1"&large($B$2:$B$8,1),$C$2:$C$8&$B$2:$B$8,0)) but it didn't seem to work.
Thanks
EDIT: After looking at the answers below I have realised why they are not working for me. My actual data that I want to use the formula with have multiple entries of numbers. I have adjusted the example data to show this. The problem I have is that if there are duplicate numbers then it returns both of the names even if one is not in the group.
Unique Names Number Group
a 30 1
b 30 2
c 19 3
d 40 2
e 1 1
f 30 2
g 15 3
Proof of Concept
Use the following formula in the example above in cell F2 and copy down and to the right as needed.
=IFERROR(INDEX($A$2:$A$8,MATCH(AGGREGATE(14,6,($C$2:$C$8=F$1)*($B$2:$B$8),ROW($A2)-1),$B$2:$B$8,0)),"")
In the header row provide the group numbers. or come up with a formula to augment and reset the group number as you copy down based on your X number in your question.
Explanation:
The AGGREGATE function unlike the large function is an array function without the need to use CSE. As such we can add criteria to what we want to use. In this case only 1 criteria was used and that was the group number. in the formula it was the following part:
($C$2:$C$8=F$1)
If there were multiple criteria we would use either an + operator as an OR or we would use an * operator as an AND.
The 6 option in the aggregate function allows us to ignore errors. This is useful when trying to get the small. It is also useful for dealing with other information that may cause errors that do not need to be worried about.
As this is technically an array operation avoid using full column/row references as they can bog down your system.
The basics of what the over all formula is doing is building a list that match the group number you are interested in. After filtering your numbers, it then determines which is the largest, second largest etc by what row you have copied down to. It then determine what row the nth largest number occurs in through the match function, and finally it returns to the corresponding name to that row with the index function.
Building on all the other great answers.
Because you have the possibilities of duplicate values in each group we need to do this with two formulas.
First we need to get the numbers in order. I used the Aggregate, but this could be done with the array LARGE(IF()) also:
=IFERROR(AGGREGATE(14,6,$B$2:$B$8/($C$2:$C$8=E$1),ROW(1:1)),"")
Then using that number and order we can reference, we can use a modified version of #ForwardEd's formula, using COUNTIF() to ensure we get the correct name in return.
=IFERROR(INDEX($A$2:$A$8,AGGREGATE(15,6,(ROW($B$2:$B$8)-ROW($B$2)+1)/(($C$2:$C$8=F$1)*($B$2:$B$8=E3)),COUNTIF(E$2:E2,E3)+1)),"")
This will count the number in the results returned and then bring in the correct name.
You could also solve this with array formulas - to filter a group whose name is stored in E1, your code
=INDEX($A$2:$A$8,MATCH(LARGE($B$2:$B$8,1),$B$2:$B$8,0))
would then be adapted to
=INDEX($A$2:$A$8,MATCH(LARGE(IF($C$2:$C$8<>E1,-1,$B$2:$B$8),1),$B$2:$B$8,0))
Note: After entering an array formula, you have press CTRL+SHIFT+ENTER.
Thank you to everyone who offered help but for some reason none of your methods worked for me, which I am sure was to do with the quality of my data. I used an alternate method in the end which is slightly convoluted but seemed to work.
=IF($C2="1",RANK($B2,$B$2:$B$8,1)+ROW()/10000,-1)
Essentially using the rank function and adding a fraction to separate out duplicate values.

Excel VLOOKUP not finding correct row

I have the following table of two columns:
102-6956821-1091413 1
115-8766130-0234619 2
109-8688911-2954602 3
109-7731824-8641056 4
If I put in the following VLOOKUP:
=+VLOOKUP(B2,B$2:C$5,2)
I get the result of:
1
2
1
1
If I change it to =+VLOOKUP(B2,B$2:C$5,2, FALSE) I get the expected:
1
2
3
4
But why is this? There is an exact match available so why does it need to approximate? If it is, why is it generating the numbers it is? How is it reducing that text value to a number that it is approximating from? Thanks!
Transfer from comment for the sake of an answer:
If your search list (ColumnB) were sorted you would see the results you expect anyway (though in a different order). For speed, VLOOKUP is using a binary search method for which an ordered list is necessary if to achieve meaningful results. There are exact matches only in the first half of the unsorted list (hence 1 and 2 are correct but neither 1 nor 1 is).

Resources