Why is my COUNTA formula counting too high? - google-sheets

I know a similar but different question has been asked, but I don’t know how to use query or where to learn, so I figured I’d ask…
I’d like to use this formula:
=COUNTA(FILTER($L:$L,OFFSET($L:$L,0,1)="Draw",$L:$L=$E2))
L:L is a range of names, which it should test against E2:E, a range of unique names. I also need to ensure that the cell in the column to the right of each instance of the name in E2:E has a specific word in it (“Draw”). I tried using AND, but this just sets everything to 1, even when one of them has 3 draws. There are no losses, so the loss column should show up as all 0s, but it is instead 1s. The infuriating thing about this is that the draw column is all right for some reason. Picture below. For reference, Losses(as well as draws and wins)are the end goal.
image

COUNT is meant for counting numeric values, COUNTA for non empty cells. COUNTIF or COUNTIFS would probably be your best choice. Try with:
=COUNTIFS($L:$L,E2,OFFSET($L:$L,0,1),"Draw")

Related

How do I create a formula that recommends a matchup of 2 names?

I’m trying to make a formula that accomplishes this:
From a list of numbers, find the pairs of numbers with the lowest difference and second lowest difference, and write their differences elsewhere(I don’t know how to do this)
Use those numbers to find and use the value(a name)of the cell to their left(I don’t know how to do this with duplicate numbers)
How would I go about this?
The final product should include all 4 numbers, names, and both differences.
In the picture below, the pink shaded section is the goal.
What I did is to first SORT the values:
=SORT(A2:B,2,1)
Then, wrapped it in LAMBDA (in order not to repeat those formula again and again), and started "scanning" those values to find the differences. Since it's already sorted, the "smallest" will be found in this comparison.
For this, I used MAP. Used SEQUENCE, COUNTA and INDEX in order to find the amount of values in the first column; and SEQUENCE will help me do the "navigation". With the variable resultant "p" I searched each row with the next one (p+1). Resulting in something like this:
=LAMBDA(sorted,MAP(SEQUENCE(COUNTA(INDEX(sorted,,1))-1),LAMBDA(p,{INDEX(sorted,p,1),INDEX(sorted,p+1,1),INDEX(sorted,p+1,2)-INDEX(sorted,p,2)})))(SORT(A2:B,2,1))
With that, you're already one step away. Just with SORTN you can find the four smallest differences:
=LAMBDA(diff,SORTN(diff,4,1,3,1))
(LAMBDA(sorted,MAP(SEQUENCE(COUNTA(INDEX(sorted,,1))-1),LAMBDA(p,{INDEX(sorted,p,1),INDEX(sorted,p+1,1),INDEX(sorted,p+1,2)-INDEX(sorted,p,2)})))
(SORT(A2:B,2,1)))
I hope it's already useful! You can split those values in two columns, obviously; just using INDEX to access the desired row of this formula; or just locate the formula somewhere and refer to those cells. Let me know if it's useful!
you can try:
=LAMBDA(z,SORTN(MAP(INDEX(z,,1),INDEX(z,,2),LAMBDA(a,b,{a,b,ABS(XLOOKUP(a,A:A,B:B,)-XLOOKUP(b,A:A,B:B,))})),4,0,3,1))(INDEX(SPLIT(QUERY(UNIQUE(MAP(LAMBDA(z,FLATTEN(z& "🐠" &TRANSPOSE(z)))(FILTER(A2:A, A2:A<>"")),LAMBDA(y,JOIN("🐠",SORT(UNIQUE(TRANSPOSE(SPLIT(y,"🐠")))))))),"Select Col1 Where Col1 CONTAINS '🐠'"),"🐠")))

vlookup an item within range

I was faced to a situation where I have to classify a list of numbers based on the size of the number.
For example, number between 2 and 8 is classified in class A. Number 16 to 25 is classified in class C. I can work on it with IF formula, but it doesnt feel good since it was like brute forcing IF within IF within IF and it is bad.
Is there any ARRAYFORMULA that can help me work on this? An arrayformula that doesnt need to be dragged down when data is added below. Maybe a formula that is related to VLOOKUP or any other formula will do.
This is the sample case:
https://docs.google.com/spreadsheets/d/1Dlrgp-aAlU2DknlG5u5XWJdXDpU5qj6EfofiCO3UTDQ/edit#gid=0
Range A:A is the given data
Range B:B is the desired outcome
Range E:F is hte condition that has to be met
You can do a lookup on the lower end of each range:
=ArrayFormula(if(A:A="","",vlookup(A:A,{split(E1:E9,"-"),F1:F9},3,true)))
assuming there are no values more than 1200.

Converting a multi column range into one column

I have an instance where I would love to be able to get a column of all the unique names in a range. The problem I am having is that the range is multicolumn.
Let's assume my data is in A1:B3
This works fine if I do:
=unique({A1:A3;B1:B3;C1:C3})
But if that range is named and I do
=unique(NamedRange) or =unique(A1:C3)
Then it will spill over the column. Worse if I want to filter or sort the results in the same formula and then run into errors because the formulas want single column/row or the rows/columns don't match anymore.
I don't deal with named ranges a lot, but I did just make a formula today that had 10 columns in it that I stuck into a range like that so that I could do a complex (for me) filter that gave me the difference of two different ranges, similar to: =FILTER({B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}, NOT(COUNTIF(H5:H, {B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}))). I would REALLY love if I could clean that up and make that messy set B4:F instead.
Is there any formula level function that could stick these all in one column?
Usually I am looking to do other things with it like sort and filter and the multiple columns get even messier.
Thanks for your time. I DID try searching for this, but I could not seem to find the answer.
Use FLATTEN:
=UNIQUE(FLATTEN(A1:C3))
or
=UNIQUE(FLATTEN(NamedRange))

Is there a way to specify an input is a single cell in Google Sheets?

I want to iterate over an array of cells, in this case B5:B32, and keep the values that are equal to some reference text in a new array.
However, SPLIT nowadays accepts arrays as inputs. That means that if I use the array notation of "B5:B32" within ARRAYFORMULA or FILTER, it treats it as a range, rather than the array over which we iterate one cell at a time.
Is there a way to ensure that a particular range is the range over which we iterate, rather than the range given at once as an input?
What I considered was using alternative formulations of a cell, using INDEX(ROW(B5), COLUMN(B5)) but ROW and COLUMN also accept array values, so I'm out of ideas on how to proceed.
Example code:
ARRAYFORMULA(
INDEX(
SPLIT(B5:B32, " ", 1), 1
) = "Some text here"
)
Example sheet:
https://docs.google.com/spreadsheets/d/1H8vQqD5DFxIS-d_nBxpuwoRH34WfKIYGP9xKKLvCFkA/edit?usp=sharing
Note: In the example sheet, I can get to my desired answer if I create separate columns containing the results of the SPLIT formula. This way, I first do the desired SPLITS, and then take the values I need from that output by specifying the correct range.
Is there a way to do this without first creating an output and then taking a cell range as an input to FILTER or other similar functions?
For example in cell C35 I've already gotten the desired SPLIT and FILTER done in one go, but I'd still need to find a way to sum up the values of the first character of the second column. Doing this requires that I take the LEFT value of the second column, but for that I need to output the results and continue in a new cell. Is there a way to avoid this?
Ralph, I'm not sure if your sample sheet really reflects what you are trying to end up with, since, for example, I assume you are likely to want the total of the hours per area.
In any case, this formula extracts all of the areas, and the hours worked, and is then easy to do further calculations with.
=ArrayFormula({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))})
Try that in cell E13, to see the output.
The first REGEXEXTRACT pulls out all the text in front of the first space and number, and the second pulls out all the digits in a string of " #hr" in each cell. These criteria could be modified, if necessary, depending on your actual requirements. Note that it requires the use of VALUE, to convert the hours from text to numeric values, since REGEXEXTRACT produces text (string) results.
It involved concatenating your multiple data columns into one long column of data, to make it simpler to process all the cells in the same way.
This next formula will give you a sum, for whatever matching room/task you type into B6, as an example.
=ArrayFormula(QUERY({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))},
"select Col1, sum(Col2) where Col1='"&B6&"' group by Col1 label sum(Col2) '' ",0))
I will also answer my own question given what I know from kirkg13's answer and other sources.
Short answer: no, there isn't. If you want to do really convoluted computations with particular cell values, there are a few options and tips:
Script your own functions. You can expand INDEX to accept array inputs and thereby you can select any set of values from an array without outputting it first. Example that doesn't use REGEXMATCH and QUERY to get the SUM of hours in the question's example data set: https://docs.google.com/spreadsheets/d/1NljC-pK_Y4iYwNCWgum8B4NJioyNJKYZ86BsUX6R27Y/edit?usp=sharing.
Use QUERY. This makes your formula more convoluted quite quickly, but is still a readable and universally applicable method of selecting data, for example particular columns. In the question's initial example, QUERY can retrieve only the second column just like an adapted INDEX function would.
Format your input data more effectively. The more easily you can get numbers from your input, the less you have to obfuscate your code with REGEXMATCHES and QUERY's to do computations. Doing a SUM over a RANGE is a lot more compact of a formula than doing a VALUE of a LEFT of a QUERY of an ARRAYFORMULA of a SPLIT of a FILTER. Of course, this will depend on where you get your inputs from and if you have any say in this.
Also, depending on how many queries you will run on a given data set, it may actually be desirable to split up the formula into separate parts and output partial results to keep the code from becoming an amalgamation of 12 different queries and formulas. If the results don't need to be viewed by people, you can always choose to hide specific columns and rows.

Using VLOOKUP in an array formula on Google Spreadsheets

Effectively I want to give numeric scores to alphabetic grades and sum them. In Excel, putting the LOOKUP function into an array formula works:
{=SUM(LOOKUP(grades, scoringarray))}
With the VLOOKUP function this does not work (only gets the score for the first grade). Google Spreadsheets does not appear to have the LOOKUP function and VLOOKUP fails in the same way using:
=SUM(ARRAYFORMULA(VLOOKUP(grades, scoresarray, 2, 0)))
or
=ARRAYFORMULA(SUM(VLOOKUP(grades, scoresarray, 2, 0)))
Is it possible to do this (but I have the syntax wrong)? Can you suggest a method that allows having the calculation in one simple cell like this rather than hiding the lookups somewhere else and summing them afterwards?
I'm afraid I think the answer is no. From the help text on
http://docs.google.com/support/spreadsheets/bin/answer.py?answer=71291&query=arrayformula&topic=&type=
The real power of ARRAYFORMULA comes when you take the result from one of those computations and wrap it inside a formula that does take array or range arguments: SUM, MAX, MIN, CONCATENATE,
As vlookup takes a single cell to lookup (in the first argument) I don't think you can get it to work, without using a separate range of lookups.
Google Spreadsheets does not appear to have the LOOKUP function
Presumably not then but it does have now:
grades Sheet1!A2:A4
scoringarray Sheet1!A2:B4
I still can't see the formulae in your example (just values), but that is exactly what I'm trying to do in terms of the result; obviously I can already do it "by the side" and sum separately - the key for me is doing it in one cell.
I have looked at it again this morning - using the MATCH function for the lookup works in an array formula. But then the INDEX function does not. I have also tried using it with OFFSET and INDIRECT without success. Finally, the CHOOSE function does not seem to accept a cell range as its list to choose from - the range degrades to a single value (the first cell in the range). It should also be noted that the CHOOSE function only accepts 30 values to choose from (according to the documentation). All very annoying. However, I do now have a working solution in one cell: using the CHOOSE function and explicitly listing the result cells one by one in the arguments like this:
=ARRAYFORMULA(SUM(CHOOSE(MATCH(D1:D8,Lookups!$A$1:$A$3,0),
Lookups!$B$1,Lookups!$B$2,Lookups!$B$3)))
Obviously this doesn't extend very well but hopefully the lookup tables are by nature quite fixed. For larger lookup tables it's a pain to type all the cells individually and some people may exceed the limit of 30 cells.
I would certainly welcome a more elegant solution!
I know this thread is quite old, but I'd been struggling with this same problem for some time. I finally came across a solution (well, Frankenstiened one together). It's only slightly more elegant, but should be able to work with large data sets without trouble.
The solution uses the following:
=ARRAYFORMULA(SUM(INDIRECT(ADDRESS(MATCH(), MATCH())))
as a surrogate for the vlookup function.
I hope this helps someone!
you can do so easily like this by hardcoding it in VR table:
=SUM(IFERROR(ARRAYFORMULA(VLOOKUP(A2:A, {{"A", 6};
{"B", 5};
{"C", 4};
{"D", 3};
{"E", 2};
{"F", 1}}, 2, 0)), ))
or you can use some side cells with rules:
=SUM(IFERROR(ARRAYFORMULA(VLOOKUP(A2:A, E2:F, 2, 0)), ))
alternatives: https://webapps.stackexchange.com/a/123741/186471

Resources