I have two classes (ABC and XYZ) and some students which have taken test in these classes. However, due to personal reason, a few students couldn't take several of the exams. I want to find the top 3 amounts of test not taken and top 3 names of the students that haven't taken the most exams. Below is an illustration of what I'm trying to do:
In cell F3, I've written the following code to get the top 3 amount of test not taken:
=LARGE(COUNTIFS(C:C,"="&"",B:B,UNIQUE(FILTER(OFFSET($B$2,0,0,COUNTA(B:B)-1,1),OFFSET($A$2,0,0,COUNTA(A:A)-1,1)=$F$2))),ROWS(B$2:B2))
My goal is to now list the top 3 non test taker names. I've tried a variation of the above code but can't seem to make it work. I have excel version 2209 if this helps. Thank you in advanced!
Try:
Formula in E2:
=LET(x,UNIQUE(FILTER(B:B,(A:A=F1)*(C:C=""))),SORTBY(x,MAP(x,LAMBDA(y,COUNTIFS(A:A,F1,B:B,y,C:C,""))),-1))
Or, for both names and count:
=LET(x,UNIQUE(FILTER(B:B,(A:A=F1)*(C:C=""))),SORT(HSTACK(x,MAP(x,LAMBDA(y,COUNTIFS(A:A,F1,B:B,y,C:C,"")))),2,-1))
You can use the following in E2 cell:
=TAKE(SORT(HSTACK(UNIQUE(B2:B14),
COUNTIFS(B2:B14, UNIQUE(B2:B14), C2:C14, "")),2,-1),3,1)
or using LET to avoid repetition and define the inputs first:
=LET(x, B2:B14,y, C2:C14,
TAKE(SORT(HSTACK(UNIQUE(x),COUNTIFS(x, UNIQUE(x),y,"")),2,-1),3,1))
Here is the output:
COUNTIFS counts the total number of blanks for unique names, the rest is just to accommodate the result to the output needs, i.e. sorting via SORT, pick the first three rows and only select names via TAKE.
If you need the result for a specific class, you can add an additional condition to COUNTIFS as follow or using a reference. For example for ABC class:
=TAKE(SORT(HSTACK(UNIQUE(B2:B14),
COUNTIFS(B2:B14, UNIQUE(B2:B14),A1:A14, "ABC", C2:C14,"")),2),3,1)
Related
I think that it is not possible after some search, but here is my question:
I have a row of values, which correspond to a quantity we calculate every day. We alternate the experiments between product A and product B.
Now, I want to run student tests on the averages of 3 consecutive experiments, on product A versus product B. A toy example can be found below:
I would like to run a T.Test to compare the sets of values (B2,D2,F2) to (C2,E2,G2). However, nothing seems to work, at least not the following:
=T.Test((B2,D2,F2);(C2,E2,G2);2;1)
=T.Test((B2;D2;F2);(C2;E2;G2);2;1)
=T.Test({"B2";"D2";"F2"};{"C2";"E2";"G2"};2;1)
Note that I was able to get my test results by reorganizing the data so that the ranges are contiguous, but this has definitely made be curious to see if there is a solution.
For those with access to HSTACK() (or VSTACK() for that matter), try:
=T.TEST(HSTACK(B2,D2,F2),HSTACK(C2,E2,G2),2,1)
If not available, try:
=T.TEST(INDEX(B2:G2,{1,3,5}),INDEX(B2:G2,{2,4,6}),2,1)
EDIT: for those with older versions of Excel, as per #JosWoolley you'd indeed need to pursuade Excel to use arrays:
=T.TEST(INDEX(B2:G2,N(IF(1,{1,3,5}))),INDEX(B2:G2,N(IF(1,{2,4,6}))),2,1)
I would like to count the number of times a specific number lies between multiple ranges.
For instance,
Specific number: 2.5 (let's say this one is in AD1)
J3=14
K3=22
L3=0
M3=6
N3=6
O3=14
P3=2
Q3=8
I need to find how many times 2.5 is between:
J3&K3
L3&M3
N3&O3
P3&Q3
The reason I would like a formula for this is because I have many "specific numbers" that there are many numbers that I need to test within the same range.
I know I can combine multiple CountIf, but the formula would be way too long.
I remember I can use Sum(CountIf("INSERTFORMULA")) but I think somehow using a combination of Sum(CountIf(Median())) will be simpler to read
SUM(Countif(MEDIAN($AD$1,J3,K3)=$AD$1,TRUE),MEDIAN($AD$1,L3,M3)=$AD$1,TRUE),MEDIAN($AD$1,N3,O3)=$AD$1,TRUE),MEDIAN($AD$1,P3,Q3)=$AD$1,TRUE))
Expected result: 2 (i.e. between L3&M3 and between P3&Q3)
Try: (Edited to correct typo)
=SUMPRODUCT(($AD$1>=INDEX(J3:Q3,1,N(IF(1,{1,3,5,7}))))*($AD$1<=INDEX(J3:Q3,1,N(IF(1,{2,4,6,8})))))*emphasized text*
The N(IF(1,{array})) is a method of returning discontinuous elements of an array using the INDEX function.
Depending on whether you want to include/exclude the bounds of the ranges when you write between, you may want to remove the equal = sign from the comparisons.
Try:
=SUMPRODUCT((J3:P3<=AD1)*(K3:Q3>=AD1))
divide your formula on two parts:
first one - just calculate MEDIAN($AD$1,J3,K3) and put it in J4 (for example), then drag and copy this formula on the all raw (so in K4 will be MEDIAN($AD$1,K3,L3), and so on)
second one - just summarize raw 4 with formulas - SUM(A4:AA4)
it takes more space on the sheet, but more simple for creation and checking.
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.
I'm trying to rank values and have managed to work out how to sort ties. My data looks at the total number of entries, ranks based on that and if there is a tie it looks to the next column of values to sort them out. However, I have two classes (East and West I've called them) of data within my dataset and want to rank them both separately (but stick to the rules above). So, if I had seven entries, 3 of them West and 4 of the East, I want West to have ranking 1,2,3 based on all the values that lie in that subset and East would have ranking 1,2,3,4. Can you explain what your formula is doing so I can understand how to apply your answer better in the future.
Effectively I'm asking what formula needs to go in achieve my result.
Cheers
Paul
There are a few related ways to do this, most involving SUMPRODUCT. If you don't like the solution below and would like to research other ways/explanations, try searching for "rankif".
The function looks up the Class and Value columns and, for every value in those columns, returns a TRUE or 1 if the current Class is a match AND if its Value is larger than the current Value, False or 0 if otherwise. The SUM adds up all these 1s, and the 1+ is for decoration. Remember to enter as an array formula using Ctrl+Shift+Enter before dragging down.
I used the array formula and SUM above to explain, but the following also works and might even be faster since it's not an array formula. It's the same idea, except we hijack SUMPRODUCT's ability to spit out a single value from an array.
=1+SUMPRODUCT(($A$2:$A$8=A2)*($B$2:$B$8>B2))
EDIT
To extend the rank-if, you could add more subsets to rank by multiplying more conditions:
You can also easily add tiebreakers by adding another SUMPRODUCT to treat the ties as an additional subset:
The first SUMPRODUCT is the 'base rank', while the second SUMPRODUCT is tiebreaker #1.
I'm doing like a bit of a competition for my students in which they have a weekly test they have to complete and submit. The grade is stored in an excel column next to their names.
Following instructions i found, i was able to create a full working general TOP3 with the Average of the tests' grade and when i get to the TOP5 for the grades of the last submitted test, i get a three-way tie.
I use the LARGE function to find the top grades and the combination of the INDEX and MATCH functions to find and display the name associated to that mark.
(Something like this =INDEX($A$1:$A$29;MATCH(M12;$F$1:$F$29;0))
The problem is that the function compares the grade on it's left to find that value in the range of grades and then returns the corresponding name associated to that row; so, it returns the same name for the three grades.
I tried using an IF function to exclude the first-result-cell from the array in which the formula is looking so that when it finds a match it will be different from the previous one, but i have not manage to work it out...
You need to use a pivot table and filter the results to the top 3. A pivot table will display the ties.
Here is a link that #Jeeped gave which basically solves the problem!
Thank you all for commenting!
Multiple Ranked Returns from INDEX(…) with Duplicate Values:
http://tinyurl.com/naavhgf