Ranking in Google Sheet - if-statement

I have some data about people on my Google Sheet and they are given some points based on their activities. What I want in the next column is that their rank based on their points. I would change the points manually on a regular basis and accordingly, their rank should be changed automatically with a formula.
At present the data ranging from A1 to J50 where row 1 is the header. I need the rank in K.
I would like to know to rank in two ways.
One in numerical. Like, Rank 1, 2, 3, etc.
Other in text, 'Outstanding', 'Good', or any text.

I think the rank function is your best option for the ranking portion, and you can use a vlookup for the ranking if the mapping of your values won't change at all.
Here is a sample workbook I threw together with the formulas. If you want to have the text ranking be dynamic as well, you'll need to provide thresholds for each value (top 20% are 'Outstanding', next 30% are 'Good', etc).
Hope this is close to what you're looking for!

=ARRAYFORMULA(IFERROR(RANK(B2:B, B2:B)))
=ARRAYFORMULA(IFERROR(VLOOKUP(IFERROR(RANK(B2:B, B2:B)), {
1, "the best";
2, "great";
3, "good one";
5, "lama xD"}, 2, 0)))

Related

How can I adjust this spreadsheet formula to take a random *non-blank* value from the specified range?

I am trying to achieve a certain unusual result using Google Sheets and here's what I've got so far.
My formula takes the value of a randomly selected cell within the named range "IntroLines":
=INDEX(IntroLines,RANDBETWEEN(1,ROWS(IntroLines)),1)
The only problem with it is that some of the cells in that named range are blank and I would like NOT to select those cells. Any ideas how I could update this formula to enforce that a non-blank value is selected?
Note: I would strongly prefer to solve this problem without removing blank cells from the named range.
Try:
=INDEX(SORT(IF(IntroLines="",,{IntroLines, RANDARRAY(ROWS(IntroLines))}), 2, 1), 1, 1)

How to use the Growth and Filter functions to make a dynamic range in Google Sheets based on ID and missing values?

I have a list of accounts featuring their product usage monthly within their current contract dates. I want to use the Google Sheets Growth function to look at where they are currently in their contract and where we expect them to land. Obviously, customers are at different stages in their contract and I want to be able to dynamically write a formula to analyze this.
A very close tutorial to what I think I need is located here, but this does not account for having multiple customer IDs in the same list:
https://infoinspired.com/google-docs/spreadsheet/dynamic-ranges-in-growth-trend-forecast-in-google-sheets/
A sample of the raw data can be seen here where I have manually entered growth formulas based on contract dates:
Any help would be appreciated, I am simply not advanced enough with the FILTER function to work this one out!
delete E2:F range and paste this into E2 cell:
=ARRAYFORMULA(IF(A2:A<>"", COUNTIFS(A2:A, A2:A, ROW(A2:A), "<="&ROW(A2:A)), ))
paste this into F2 cell and drag down:
=IF(D2<>"(null)",,GROWTH(
INDIRECT(ADDRESS(MIN(FILTER(ROW(E:E), A:A=A2)), 4, 4)&":"&
ADDRESS(MIN(FILTER(ROW(E:E), A:A=A2, D:D="(null)"))-1, 4, 4)),
INDIRECT(ADDRESS(MIN(FILTER(ROW(E:E), A:A=A2)), 2, 4)&":"&
ADDRESS(MIN(FILTER(ROW(E:E), A:A=A2, D:D="(null)"))-1, 2, 4)), B2))

Calculate ever expanding number of columns with data to the right

Currently have a spreadsheet that tracks attendance. First column is name, second column is attendance % and contains the formula I need to revise, subsequent columns simply have an X or O in them and denote whether someone attended or not (headers for these columns are dates).
Currently using a COUNTIF() I can check how many X's there are and then the formula is SUM(100/no_of_columns*COUNTIF(A3:A12))
Ideally I want to firstly replace no_of_columns with the actual number of columns with data to the right.
I've thought about replacing this with a SUM(COUNTIF('X')+COUNTIF('O')) but it seems pretty messy?
Secondly I want to replace the A12 with whatever the last column value is.
I could just make the last column a very high column value, but again feels messy and would like to know if there is a better way...
Example: https://docs.google.com/spreadsheets/d/1rjnUQP7V-U1EZTp3Z8yO7HybBCuQjf2y4LJ4Dv4ctF8/edit?usp=sharing
Presume you only have the attendance dates in Row 1 without other information such as headers for Column A and B,
Put the following formula in Cell B2 and drag it down,
=COUNTIF(INDEX(OFFSET($C2,,,,COUNTA($1:$1)),),"x")/COUNTA($1:$1)*100
The logic is to use INDEX + OFFSET function to dynamically return the range of columns on the right, and use COUNTA to find out how many dates are there, and you should understand the use of COUNTIF, the calculation is self-explanatory.
EDIT #2
After looking into your worksheet, I guess you are adding the new dates by inserting columns between B and C so you probably want to use the following formula in Cell B2 instead to avoid the system shifting the starting cell reference automatically:
=COUNTIF(INDEX(OFFSET($B2,,1,,COUNTA($1:$1)),),"x")/COUNTA($1:$1)*100
The logic is the same as the previous one but just a little change to the OFFSET references so it starts looking for the range from Column B instead of C.
I have tested the above in both Excel and Google-sheets working just fine. Let me know if you have any questions. Cheers :)
paste in B2:
=ARRAYFORMULA(IFERROR(IF(LEN(A2:A),
MMULT(IF(INDIRECT("C2:"&ADDRESS(ROWS(A2:A), MAX(IF(1:1<>"", COLUMN(1:1), ))))="x", 1, 0),
TRANSPOSE(COLUMN(INDIRECT("C2:"&ADDRESS(ROWS(A2:A), MAX(IF(1:1<>"", COLUMN(1:1), )))))^0))/
MMULT(IF(INDIRECT("C2:"&ADDRESS(ROWS(A2:A), MAX(IF(1:1<>"", COLUMN(1:1), ))))<>"", 1, 0),
TRANSPOSE(COLUMN(INDIRECT("C2:"&ADDRESS(ROWS(A2:A), MAX(IF(1:1<>"", COLUMN(1:1), )))))^0))*100, ), 0))
spreadsheet demo

How to set up COUNTIF or COUNTIFS formula in Google Sheets to compare columns?

I am trying to compare the numerical data in two columns in Google Sheets (say, Col. A and B) and return a count of all of the times that they vary by say, more than 1 (e.g., if A3 = 5 and B3 = 2, this should get counted). The two-column arrays will always be of equal size.
At first, I thought that either COUNTIF or COUNTIFS would be my go-to tool, but I can't get this to work with either formula. These formulas seem to handle criteria within a cell, but - as far as I can tell - can't handle criteria comparing data within two different (adjacent) cells.
Can someone help me with some super syntax work-around to get COUNTIF/COUNTIFS to work... or is there a more appropriate formula to the job (perhaps involving FILTER)?
*Quick Edit: I know I could always add an additional column, which would be very simple in this example. But my real-world spreadsheets are a lot more complex and are already suffering from column overload. A lot of other formulas are already set up around existing columns, and I was hoping to discover a more elegant solution that would allow me to come up with the count without having to add a new column for each and every comparison calculation.
=ARRAYFORMULA(IF(LEN(A:A&B:B), IF(A:A-B:B>1, 1, )+IF(B:B-A:A>1, 1, ), ))
if you want final sum instead of "per row" count use:
=SUM(ARRAYFORMULA(IF(LEN(A:A&B:B), IF(A:A-B:B>1, 1, )+IF(B:B-A:A>1, 1, ), )))
Add a third column, containing e.g. =ABS(SUM(A3-B3)). (The ABS gives you the positive difference regardless of which value is larger.)
At the bottom of that column, use COUNTIF like =COUNTIF(C1:C25, ">1") (where C1:C25 is the range of cels containing those positive differences).

Countif and ArrayFormula with multiple levels

I have a formula. It works - but feels like it could be made much simpler.
I have many departments across several columns. Each row has an item that we're tracking and each column has a status text that changes as we do the work.
'queue' - it's in line waiting to be done and weighs down the average
'active' - in process and provides a half value across the average
'done', 'ok'd', 'rcvd' - finished and contributes to the final average
'none' - denotes a department that's inactive on this job and should not count in the final average.
The formula is:
=iferror(((ArrayFormula(sum(countif(B3:O3,{"done","ok'd","rcvd"}))))+(countif(B3:O3,"active")/2))/(counta(B3:O3)-(countif(B3:O3,"none"))),)
The formula works but I'm looking to see if there's an easier way to approach it. Would a query or array modification work better in this scenario?
What if I wanted to add other text strings based on syntax for my current application?
Here's a link to a sample sheet with it in context.
https://docs.google.com/spreadsheets/d/1zPFAcSxM7tYjZmlATYde7qKsDoeH6AW_xjFooOZFOf4/edit#gid=0
EDIT:
As a followup question - how do I get the same thing to work across the columns?
I did some reverse engineering to the solution and can see the formula working across the top of my sheet - but it's giving me an error:
"MMULT has incompatible matrix sizes. Number of columns in first matrix (13) must equal number of rows in second matrix (1)."
Here's the formula I've added (it's also in the linked sheet).
=ARRAYFORMULA(IF(LEN(B4:N4), MMULT(IFERROR(( N(REGEXMATCH(B4:N9, "ok'd|done|ready|rcvd"))+ N(REGEXMATCH(B4:N9, "active"))/2)/MMULT(N(REGEXMATCH(B4:N9, "[^none]")),TRANSPOSE(ROW(B4:B9)^0)), 0), TRANSPOSE(ROW(B4:B9)^0)),))
As a followup question - how do I get the same thing to work across the columns?
=ARRAYFORMULA(TRANSPOSE(IF(LEN(TRANSPOSE(B4:N4)), MMULT(IFERROR((
N(REGEXMATCH(TRANSPOSE(B4:N16), "ok'd|done|ready|rcvd"))+
N(REGEXMATCH(TRANSPOSE(B4:N16), "active"))/2)/MMULT(
N(REGEXMATCH(TRANSPOSE(B4:N16), "[^none]")),
(ROW(B4:B16)^0)), 0),
(ROW(B4:B16)^0)), )))
=ARRAYFORMULA(IF(LEN(B3:B9), MMULT(IFERROR((
N(REGEXMATCH(B3:N9, "ok'd|done|ready|rcvd"))+
N(REGEXMATCH(B3:N9, "active"))/2)/MMULT(
N(REGEXMATCH(B3:N9, "[^none]")),
TRANSPOSE(COLUMN(B3:N3)^0)), 0),
TRANSPOSE(COLUMN(B3:N3)^0)), ))