I am trying to find the third most frequent value in a google sheet. I saw how to find the second and first one, but I can't find out how to find the third and up. I need to know how to calculate the third, fourth, fifth, sixth, seventh, and eighth places. I am working on a leaderboard system for the school I work at.
I know this is how to find the second most frequent:
=ArrayFormula(MODE(IF((F1:F85=MODE(F1:F85)),"",F1:F85)))
and this is how to find the first:
=mode(F1:F65)
I need to find all the ones that come after that, though.
I need to find all the ones that come after that, though.
The more scalable solution that avoids nested IFs would be something along the lines of:
=ArrayFormula(QUERY({F1:F85,LEN(F1:F85)},"select Col1, count(Col2) where Col2 > 0 group by Col1 order by count(Col2) desc",0))
This produces a table of each number and their associated frequency, sorted from most frequent to least. You can retrieve the specific value from this table using INDEX:
=INDEX(QUERY({F1:F85,LEN(F1:F85)},"select Col1, count(Col2) where Col2 > 0 group by Col1 order by count(Col2) desc",0),n+1,1)
where n is the position you require (1 = most frequent, 2 = second-most frequent, etc).
Your initial This question was referring to a 2-dimensional range, which will be a bit more complicated, but still doable.
Given B1:B99 as our range, if A1 is most common, A2 is second most common, et cetera:
A1 = ArrayFormula(MODE(B1:B99))
A2 = ArrayFormula(MODE(IF((B1:B99=A1),"",B1:B99)))
A3 = ArrayFormula(MODE(IF((B1:B99=A1),"",(IF((B1:B99=A2),"",B1:B99)))))
A4 = ArrayFormula(MODE(IF((B1:B99=A1),"",(IF((B1:B99=A2),"",(IF((B1:B99=A3),"",B1:B99)))))))
I'm curious if anyone has a better solution though.
I'm pretty sure there is a more elegant solution to this than the other answers give.
Try using this Google Visualization API Query:
=query(A:B,"select A, count(B) group by A order by count(B) desc label count(B) 'Count' ",1)
This should give you 2 columns – the first gives the distinct values in your Column A, the second gives the number of occurrences for each value (sorted in descending order).
You should note that it seems that queries on single columns aren't supported, so I admit that the query is a little messy (although it should work if you just keep the B column empty).
Related
This might be something fairly simple but struggling to find a way to do it.
In Column B, I have a list of foods required.
In Column C, I have the amount needed.
In Column D, I have g (for grams) ml (for mills) etc.
I would like to combine the duplicates in Column B and update the totals from Column C, with the g or ml in Column D beside it.
The list I have has been created by using an array formula based on dropdowns in another sheet.
I have seen people using UNIQUE formula in 1 column (this works) and then a SUMIF formula in another column and then a JOIN formula in another... I tried this but the SUMIF is always returning 0.
Would someone please be able to advise on how I can do this?
TIA :D
It's hard to be sure exactly what you need without seeing the data. But based on my understanding of solely what you've posted, this QUERY formula should generate a condensed mini-report:
=QUERY({B2:D},"Select Col1, SUM(Col2), Col3 WHERE Col1 Is Not Null GROUP BY Col1, Col3 LABEL SUM(Col2) ''")
In plain English, this means "Arrange the data from the range B2:D in the same order as the raw data, but sum the second column's data according to matches in both the first and third columns. Only return results for the raw data where the first column is not blank. Replace the default 'sum' header on the second column with nothing; I don't need it."
This formula assumes that every ingredient will always be attached to the same measurement (e.g., 'salt' in Col B is always paired with 'mg' in Col D, etc.). If this is not the case, you will wind up with ingredients being listed as many times as there are different measures in Col D.
I have simple table that looks like this:
All i need is to SUM points for specific player (John) in his last 3 matches.
I was able to come with this formula:
SUMPRODUCT(LARGE((A2:B="John")*(C2:D);{1;2;3}))
The problem is that instead of what I was looking for, it sums the highest 3 values, that can be anywhere in that range.
Is there some similar formula, that can do only the last 3 matches?
I think a SUMPRODUCT can get you there with some constructed arrays using a COUNTIFS() and ROW() to get the most recent 3.
This formula:
=SUMPRODUCT((COUNTIFS(A:B,G2,ROW(A:B)*{1,1},">="&ROW(A:B)*{1,1})<=3)*(A:B=G2),C:D)
on this sheet I made seems to work.
I thnk I have a formula that gives what you want. It's not pretty, and I'm sure it can be made simpler, but this works:
=query( query(
{ arrayformula( {ROW(A1:A) } ),
query(A1:D,"select A, B, C, D",1)
} , "select * order by Col1 desc",1),
"select Col2, Col3, Col4, Col5
where (Col2 ='John' or Col3 = 'John')
order by Col1 desc limit 3",1)
Basically, it adds the row number as an extra column to the data, so that we can sort the data in reverse order by row number. Then we query the result to find the first three occurences of 'John', in either Col A or Col B.
Here is a sample sheet:
https://docs.google.com/spreadsheets/d/1-mhTb5Cpp3D-1OltlmCfwlmM-vc2OknHxfJAyHD7BjI/edit?usp=sharing
Credit to Erik Tyler for a previous answer on a different question, on how to add the row number to a query.
Edit: Updated the sheet to provide the SUM of John's (or any player's) scores from the last three matches. This can be combined with the previous formula, if you want a single formula to place somewhere. Or will you have a list of all the players, and you'll want their last three scores beside each of their names?
If I can simplify the formula, I'll update it here.
Let me know if you need something more than this, or if this has answered your question.
Approach
I would use the query formula to get the cells that you need so that you can leverage the limit statement.
You should put a column with the indexes so that you can order the cells in descending order and take the first 3.
Given that your table headers are:
+-----------------------------------------------+
| INDEX | NAME 1 | NAME 2 | POINTS 1 | POINTS 2 |
+-----------------------------------------------+
I would use this query to get your desired result:
=SUMPRODUCT(QUERY(A2:E, "Select D * E where B = 'John' or C = 'John'" order by A desc limit 3"))
I'm looking for solution for my problem. I have a sheet to summarize lap times for some competition. We make 3 laps in each qualification. We are qualifying to finals by 2 best laps one after another. So we sum first and second lap or second and third lap and then choose the smallest one sum. I've managed to get array of pairs and filter out empty cells (run not finished). Number of pairs may vary form 1 to 20.
Now is my question. How to find the smallest sum of pairs from my array in one elegant formula?
Here is my sample sheet: example sheet
=QUERY(QUERY({A17:B17;B17:C17;D17:E17;E17:F17;G17:H17;H17:I17};
"select Col1+Col2
where Col1 is not NULL
and Col2 is not NULL");
"select min(Col1)
label min(Col1)''")
I know this isn't exactly your question and fair play if it gets marked down, but in your quest for an 'elegant formula', I was wondering if there was a more general way to get the pairs in the first place.
You can do it with by using two ranges offset by one cell together with the mod of the column number:
=ArrayFormula(query(
query({transpose({A17:H17;B17:I17;mod(column(A17:H17),3)})},"select Col1+Col2 where Col1 is not null and Col2 is not null and Col3>0")
,"select min(Col1) label min(Col1) ''"))
I have a rather complex goal in mind, but in short, I'm trying to make a filter on a range that would only leave unique names which have a condition "Add" and not "Remove". Problem is, the data will be continuously populated via form submission and some names will be removed and re-added down the road, so if same name is encountered in the range and has both one "Add" and one "Remove"(or equal amount of add and remove) - it shouldn't show up in filtered data. Please see the spreadsheet below for example.
https://docs.google.com/spreadsheets/d/18n7b6hEh9X3A14-PCQSwOPQr8nTin2X9-NBKmPSv48Q/edit#gid=0
Alternatively i was thinking of collecting the latest encounter of the unique name. So if the same name is encountered multiple times - retrieve the entry which is closest to today and only show it if condition matches "Add". This solution would be more beneficial but seem to be harder to achieve.
Either solution would help a lot. Appreciate your insight.
may be use double query:
=QUERY(QUERY(A2:C11,"select C, count(A) where B <> '' group by C pivot B"),"select Col1 where Col3 is null")
also this formula could work:
=UNIQUE(FILTER(C2:C10,ArrayFormula(MMULT(--(C2:C10=TRANSPOSE(C2:C10)),--(B2:B10="Remove")))=0))
You can try this.
=unique(query(arrayformula(iferror(if(isodd(COUNTIF(C2:C8,C2:C8)),C2:C8,""))), "select Col1 where Col1 is not null order by Col1 desc", 0 ))
I am collecting stats for a small library.
I have people completing Google forms when they check out books. I have one field where they enter the call number for each book they borrow. These call numbers fall into three major classifications and take the following form (REF.XX.YYYY, FA.XX.YYYY, AA.XX.YYYY) where X and Y are a combination of letters and numerals.
The result in the spreadsheet would look something like this:
Table
Shared table
I am trying to come up with a way to count the number of instances each classification designation comes up (REF, FA, or AA) throughout the column. For instance, REF should be 3, FA should be 0 and AA should be 1. I made several tries with COUNTIF function but without any success. Any clue about what could be such formula?
The expected output is in red. I want to obtain such output using formulas.
Any help would be appreciated.
You can try getting those classifications using regexextract and then use a query to count everything.
=ArrayFormula(query({A2:A\regexextract(B2:B; "^[A-Z]*")}; "Select Col2, count(Col1) where Col2 <>'' group by Col2 label count(Col1) ''"))
I've added this formula to your table. AA is not showing up in the result because it is not present in the source data.