I'm trying to understand this auto-increment formula, that my colleague has written. I understand how arrayformula usually works and also countifs.
Formula from the screen: =ARRAYFORMULA(COUNTIFS(ROW(B2:B), "<="&ROW(B2:B)))
I'm stacked about why ROW(B2:B) (1param in COUNTIFS) as a range works fine. It should be a range, not just a number that ROW function returns.
I have been trying to find an answer, read documentation, but nothing helped.
I think that, for example, for 4th line the formula would look like this (if we seperate from ARRAYFORMULA):
COUNTIFS(ROW(B4:B), "<="&ROW(B4:B)),
COUNTIFS(4, "<=4")
I need to understand this code, not other solutions.
The best way to understand how an ARRAYFORMULA works is to write down the equivalent drag-down formula.
The equivalent drag-down formula for:
=ARRAYFORMULA(COUNTIFS(B2:B, B2:B, ROW(B2:B), "<="&ROW(B2:B)))
is
=ARRAYFORMULA(COUNTIFS($B$2:$B, B2, ROW($B$2:$B), "<="&ROW(B2)))
=ARRAYFORMULA(COUNTIFS($B$2:$B, B3, ROW($B$2:$B), "<="&ROW(B3)))
=ARRAYFORMULA(COUNTIFS($B$2:$B, B4, ROW($B$2:$B), "<="&ROW(B4)))
...
(We only need ARRAYFORMULA because ROW($B$2:$B) is an array formula, which means that if you type it in a cell without wrapping it an an array-enabling function it will only evaluate ROW($B$2))
If we recall the COUNTIFS parameters:
=COUNTIFS(criteria_range1, criterion1, criteria_range2, criterion2)
We can see that in the drag-down formula, every parameter that by default expects a range, becomes an absolute reference and every parameter that by default does not expect a range, is just a single value that increments each row.
This is true for any other function: if a function has a parameter that by default expects a range, when we wrap it in ARRAYFORMULA(), that range stays the same throughout the entire computation, which means that every single value in that range is seen by the array formula at any time. What increments, and therefore is only seen by the array formula on that specific row, are the parameters that do not natively expect a range.
This seems like an obvious observation but I'm sure it's the reason many people are confused about how that formula works.
If you understand this concept, then you can also understand how the other variants of the formula work:
=ARRAYFORMULA(COUNTIFS(B2:B, B2:B, ROW(B2:B), "<"&ROW(B2:B)))
=ARRAYFORMULA(COUNTIFS(B2:B, B2:B, ROW(B2:B), ">="&ROW(B2:B)))
=ARRAYFORMULA(COUNTIFS(B2:B, B2:B, ROW(B2:B), ">"&ROW(B2:B)))
every next row is by logic an incrementation of the previous row +1. what this formula does it checks the given row number against row number. for example, for row 4, COUNTIFS checks if ROW(A4) is smaller or equal to ROW(A4). then the evaluation is "yes, row 4 is equal to row 4" and the output is TRUE. what COUNTIF actually does is counting these TRUE outputs up to every row summing all the previous rows. something like:
rows
COUNTIFS processing
output
counting TRUEs
final output
row 1
row 1 equal to row 1?
TRUE
1st TRUE
1
row 2
row 2 equal to row 2?
TRUE
2nd TRUE
2
row 3
row 3 equal to row 3?
TRUE
3rd TRUE
3
row 4
row 4 equal to row 4?
TRUE
4th TRUE
4
row 5
etc
etc
etc
etc
Related
I am having trouble with arrayformula.
I have some data at Col A & B, SUMIF($A$2:$A2,"ABC",$B$2:$B2) works perfectly fine, but I'd like to use arrayformula so I don't have to drag down the formula.
But using ArrayFormula(SUMIF($A$2:$A2,$C$1,$B$2:$B2)) doesn't do anything at all, is there any way I can make it work? I have no idea how.
Here is another option (say, in E2):
=ArrayFormula(IF(A2:A="",,SUMIF(ROW(A2:A)*IF(A2:A="ABC",1,9^9),"<="&ROW(A2:A),B2:B)))
How It Works:
IF(A2:A="",, means "If a row in A2:A is blank, do nothing for that row."
ROW(A2:A)*IF(A2:A="ABC",1,9^9) will create a number based on the row number at each row: the row number itself multiplied by 1 for rows matching "ABC" (resulting in the row number again, since anything times 1 is itself) or multiplied by 9^9 (i.e., some enormous number, which will be the result of for all rows that are not "ABC").
This will be matched against the condition "<="&ROW(A2:A). So only rows at or before "each row" that matched "ABC" will deliver results.
try in E2:
=INDEX(IF(A2:A="ABC",MMULT(1*TRANSPOSE(IF((TRANSPOSE(ROW(
INDIRECT("A2:A"&MAX(ROW(A2:A)*(A2:A<>"")))))>=ROW(
INDIRECT("A2:A"&MAX(ROW(A2:A)*(A2:A<>"")))))*(
INDIRECT("A2:A"&MAX(ROW(A2:A)*(A2:A<>"")))=TRANSPOSE(
INDIRECT("A2:A"&MAX(ROW(A2:A)*(A2:A<>""))))),
INDIRECT("B2:B"&MAX(ROW(A2:A)*(A2:A<>""))), 0)), ROW(
INDIRECT("A2:A"&MAX(ROW(A2:A)*(A2:A<>""))))^0),))
Suppose I have only one value anywhere at the cell range C2:Z2, I want that value at B2. What can I do?
I need this solution for all the rows bellow this also. The value might at C:C column at one row, at H:H column at another, that means it is dispersed at the range but there will be only one value at the range in a row.
Place this formula in B2:
=ARRAYFORMULA(TRIM(TRANSPOSE(QUERY(TRANSPOSE(C2:Z), , COLUMNS(C2:Z)))))
The formula above works for any type of values.
If your values are numbers then a simpler formula could be used (MMULT does row wise sum here):
=MMULT(
ARRAYFORMULA(--(C2:Z)),
SEQUENCE(COLUMNS(C2:Z), 1, 1, 0)
)
You can use FILTER()
=FILTER(C2:Z2, NOT(ISBLANK(C2:Z2)))
Reference:
FILTER()
if there will be only one value in the row then a simple sum function will do the job for you. put this in B2 ..
=sum(C2:Z2)
I'm looking to use PERCENTRANK in an ARRAYFORMULA for a column in a spreadsheet. I put the following formula in AB1.
={"Daily Total Ranking";arrayformula(if(isblank(A2:A),,PERCENTRANK($AB$2:$AB, AB2)))}
But the result is the same ranking (the one for cell AB2) down the entire column.
You need to put the range of the whole column from AB2 onwards in the second PercentRank parameter so that the function is evaluated for each value in the range AB2:AB where A2:A is not blank, instead of just for AB2:
={"Daily Total Ranking";arrayformula(if(isblank(A2:A),,PERCENTRANK($AB$2:$AB, $AB$2:$AB)))}
I'm trying to make an array formula which sums up all the rows until this row.
For clarification column a will be the input and column b would be the output. I'm looking for a way to do this with an arrayformula.
a1:1 b1:1a2:2 b2:3a3:5 b3:8a4:3 b4:11
I tried to use =ARRAYFORMULA(SUM(INDIRECT("F1:"&ADDRESS(ROW(),COLUMN(F2:F))))) but this doesn't work.
How about
=arrayformula(sumif(row(A1:A4),"<="&row(A1:A4),A1:A4))
The sumif is evaluated separately for each value in the criteria part so:
In the first row of the output array you have
=sumif(row(A1:A4),"<=1",A1:A4)
giving you just the first row of column A.
In the second row of the output array you have
=sumif(row(A1:A4),"<=2",A1:A4)
giving you the sum of the first 2 rows and so on.
Since OP changed the question with a clarification, A different answer is submitted below:
B1:
=ARRAYFORMULA(MMULT(transpose(A1:A5)*--IF(row(1:5),COLUMN(A:E)<=row(1:5)),ROW(1:5)^0))
I have a bunch of columns that holds scores like 3-1 1-4 1-0 2-2.
I would like to count all columns that are winning, ie. left number is higher than right one.
I have this formula to know if a column is winning : =LEFT(H2; FIND("-"; H2)-1)-RIGHT(H2; FIND("-"; H2)-1)
What I want to do now is to use this formula within COUNTIF, something along the line :
=COUNTIF(A1:A10; "LEFT(CURRENT_COLUMN; FIND("-"; CURRENT_COLUMN)-1)-RIGHT(CURRENT_COLUMN; FIND("-"; CURRENT_COLUMN)-1)")
Is there any way I can do it with a single formula ?
Complex filtering like this can be done with filter, and then the results can be counted with counta. Example:
=counta(filter(A:A, LEFT(A:A, FIND("-", A:A)-1) > RIGHT(A:A, FIND("-", A:A)-1)))
The first argument of filter is the range to be filtered; the second is a formula based on that range (or another range with the same row count) which returns True or False. The rows where the formula evaluates to True are returned.