ARRAYFORMULA with COUNT - google-sheets

im trying to come up with an ARRAYFORMULA to substitute formulas on every row
=IF(ISBLANK(A2);""; COUNTA(FILTER((Derivatives!B:B);INDEX((Derivatives!D:D);0;0)= left(A2;4);INDEX((Derivatives!F:F);0;0)= "EQUITY CALL")))
Exemple
example is almost correct, most of 1 results should be 0, i belive thats caused by COUNTA, not sure, bigger numbers should be correct on my exemple
basicly to COUNT number of times Derivatives!B:B, those are UNIQUE
WHERE Derivatives!D:D matches LEFT(Example!A2;4),
AND Derivatives!F:F is EQUITY CALL

use:
=ARRAYFORMULA(IFNA(VLOOKUP(LEFT(A2:A; 4);
QUERY({LEFT(Derivatives!D:D; 4)\ Derivatives!F:F};
"select Col1,count(Col1) where Col2 ='EQUITY CALL' group by Col1"); 2; 0); 0))

Related

How to make an arrayformula count values by row?

I have tried many approaches but I can't seem to figure out a solution to a fairly simple problem with an array formula it seems:
I have a sheet where I get results of individual results of runs of a certain scientific experiment by row.
Next, I'd like to count the occurrence of each output value. Output values can be a number from 1 to 10 so I'd like to individually count how many times the output has been per value.
Also, I'd be then summing up how many individual outputs have been generated in total. So I'd be counting the number of unique outputs within a row.
Now my issue is that when using Arrayformula the way I normally use it it doesn't work because it would count and sum up everything for the whole Matrix specified. However, I just want the current row to be counted. I tried using ROW to get there, but i failed.
I also tried some things like =ARRAYFORMULA(SUMIF(IF(COLUMN(B1:F1),ROW(B2:F5)),ROW(B2:F5),B2:F5)) to understand how to apply the logic, but I fail to get it working as COUNTIF version if itself.
Test Sheet
Any help and ideas would be highly appreciated!
in H2 use:
=INDEX(MMULT(IF(INDIRECT("B2:F"&MAX((ROW(A2:A)*(A2:A<>""))))=""; 0; 1);
FLATTEN(COLUMN(B:F)^0)))
in J2 use:
=INDEX(ARRAY_CONSTRAIN(QUERY(QUERY({IFERROR(SPLIT(FLATTEN({ROW(A2:A)&"×"&B2:F}); "×"));
{SEQUENCE(10)*9^9\SEQUENCE(10)}};
"select count(Col1),Col1 where Col2 is not null group by Col1 pivot Col2");
"where Col11 < 100000 offset 1"; 0); 9^9; 10))
update:
H1:
={"Total No. of outcomes"; ARRAYFORMULA(IFNA(VLOOKUP(ROW(A2:A);
QUERY(SPLIT(UNIQUE(FLATTEN(ROW(B2:F)&"×"&B2:F)); "×");
"select Col1,count(Col1) where Col2 is not null group by Col1"); 2; 0)))}
J1:
=INDEX({"Occurence of "&SEQUENCE(1; 10); ARRAY_CONSTRAIN(QUERY(QUERY({IFERROR(
SPLIT(FLATTEN({ROW(A2:A)&"×"&B2:F}); "×")); {SEQUENCE(10)*9^9\SEQUENCE(10)}};
"select count(Col1),Col1 where Col2 is not null group by Col1 pivot Col2");
"where Col11 < 999999 offset 1"; 0); 9^9; 10)})
demo sheet
Just an afterthought to this, I think the accepted answer is optimal but I did wonder if you could solve it using only countifs. The answer is yes, but you have to force the array arguments to be the same size and shape otherwise you get the 'array arguments different sizes' error so in J2:
=ArrayFormula(countifs(B2:F6,mod(sequence(5,10,0),10)+1,row(B2:F6)+B2:F6-B2:F6,int(sequence(5,10,0)/10)+2))
Note the the total number of outcomes column gives the number of different outcomes using the formula below in H2:
=ArrayFormula(mmult(sign(J2:S6),sequence(10,1,1,0)))

How can I sum across multiple sheets using a named range with multiple conditions?

I believe what I am trying to do should be simple in Google Sheets formulae, but any solution based on an Excel formula should be easily transferable.
Because additional characters will be added periodically, I have a named range: "Heroes".
Heroes
Bilbo
Gandalf
Saruman
Wormtongue
Tom Bombadil
For each hero, I have a worksheet in one overall workbook. On these worksheets, there are columns for Date, Time, Quest, and Count. Several times per day, a hero will venture out on a quest of a certain type, returning with a certain count as a prize. Each venture has its own row distinguishable by date and time. Eg-:
Date
Time
Quest
Count
12/4
3:00P
Ring
9
12/5
8:00A
Mordor
6
12/5
4:15P
Sting
3
Meanwhile, I have a summary worksheet, on which I am manually entering (for now... bonus points to help create an =arrayformula() or equivalent to grab all unique date/time combinations from each character's worksheet) the date and time at which one or a batch of heroes are sent to quest. I am trying to figure out the formula template that will sum the counts for each quest type for each hero at the specific date and time signified by its corresponding row (starting at 12/4, 3:00P, Ring, the count should be 9, for example, which is Bilbo's prize for questing at that time; of course, other heroes are also sent out at 3:00P, resulting in prizes for the other quests, and multiple heroes may venture on the same type of quest at any given time):
Date
Time
Ring
Sting
Mordor
Moria
12/4
3:00P
9
3
4
1
12/4
9:30P
1
0
8
0
12/5
8:00A
5
3
6
9
12/5
12:10A
3
1
3
8
12/5
4:15P
4
5
2
5
Since not every date and time in the summary sheet will exist on each hero's worksheet, I seem unable to use "SUMIFS", which functions in such a way that each sum_range and criteria_range are added on only across the same row when conditions are met. I think there is a SUMPRODUCT(), or INDEX(MATCH()) way to do this, but when including the named range to read across multiple worksheets, only the first hero's numbers were added in my tinkering with this.
I'm dancing around the solution here. Anyone care to tango ? Many thanks !
Sample Workbook for support: https://docs.google.com/spreadsheets/d/142IE9r2ip6YHsGdMr-zt_IHd6W7glqUId_UiGQnCUZs/edit?usp=sharing
it would be done like this:
=QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1)
if you want a specific order of places you can do:
=TRANSPOSE(SORT(TRANSPOSE(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)),
MATCH(FLATTEN(QUERY(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1), "limit 0", 1)),
{"Date"; "Time"; "Ring"; "Sting"; "Mordor"; "Moria"}, ), 1))
or manually like this:
=QUERY(QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1),
"select Col1,Col2,Col5,Col6,Col3,Col4")
if you thinking to outsmart it with the list of Heroes... don't. referring a range from other sheets requires the usage of INDIRECT. and surprise surprise, INDIRECT is not supported under ARRAYFORMULA so you cant build an array. at this point, you either re-think your life choices or you use a script where there is support for such indirected arrays. the best you can do without script is to hardcode it like:
=QUERY({
INDIRECT(Main!A2&"!A:D");
INDIRECT(Main!A3&"!A:D");
INDIRECT(Main!A4&"!A:D");
INDIRECT(Main!A5&"!A:D");
INDIRECT(Main!A7&"!A:D")},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
and ofc this will only work if sheet exists on the list and list does not contain empty cells otherwise you will get ARRAY error like this because Main!A6 sheet does not exist:
so to counter it we can do some slide of hand tricks with IFERROR which will allow us to not get the error and still use non-existent sheets and even empty cells so we can pre-program it for future additions like this:
=QUERY({
IFERROR(INDIRECT(IF(Main!A2="", 0, Main!A2)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A3="", 0, Main!A3)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A4="", 0, Main!A4)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A5="", 0, Main!A5)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A6="", 0, Main!A6)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A7="", 0, Main!A7)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A8="", 0, Main!A8)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A9="", 0, Main!A9)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A10="", 0, Main!A10)&"!A:D"),{"","","",""});
IFERROR(INDIRECT(IF(Main!A11="", 0, Main!A11)&"!A:D"),{"","","",""})},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
note: 4 columns in range A:D = 4 empty cells {"","","",""}

SUMPRODUCT of last nth values with criteria

I have two columns (see screenshot)
How can i create a formula that sum the second LATEST column values with a criteria from column A?
For example i need the sum of the last 6 values (from column B) of the cells (in column A) that start with HH, so values starting from the bottom.
I know how to make a sum of all values (from column B) containing HH (from column A)
=SUMIF(A1:A;"HH"&"*";B1:B)
P.S. HH and * are separate because i'll substitute the HH with a cell
but now i need to delimit this to the last N values (let say last 3 values)
P.P.S.
=SUMPRODUCT((COUNTIFS(A1:A;"exact text";ROW(A1:A)*{1;1};">="&ROW(A1:A)*{1;1})<=3)*(A1:A="exact text");B1:B)
This works so far ONLY if i write the exact text, not with values like HH*
Maybe try
=sum(index(query({row(A1:A), A1:B}, "Select Col3 where Col2 contains 'HH' order by Col1 desc limit 6")))
and see if that works?
Note:
*the string HH can be also be in a cell (ex. D1)
=sum(index(query({row(A1:A), A1:B}, "Select Col3 where Col2 contains '"&D1&"' order by Col1 desc limit 6")))
*6 indicates the number of values you want to sum
EDIT: For your locale you'll need to use in G1
=sum(index(query({row($B$1:$B) \ $B$1:$C}; "Select Col3 where Col2 contains '"&E2&"' order by Col1 desc limit 3")))
and fill down. See if that works?
This should also work, not sure if it's any easier to understand/ less complicated than any other approach:
=SUM(SORTN(REGEXMATCH(B:B;E2)*C:C;3;0;ROW(B:B)*REGEXMATCH(B:B;E2);0))
Note the number 3 for the number of values you want from the bottom. and the reference to E2, which is "HH" as on your sample sheet.
use:
=QUERY(FILTER({IFNA(REGEXEXTRACT(SORT(B2:B; ROW(B2:B); 0);
"^([A-Za-z]{1,3})\d"))\SORT(C2:C; ROW(B2:B); 0)}; COUNTIFS(
REGEXEXTRACT(SORT(B2:B; ROW(B2:B); 0); "^([A-Za-z]{1,3})\d");
REGEXEXTRACT(SORT(B2:B; ROW(B2:B); 0); "^([A-Za-z]{1,3})\d");
ROW(H2:H43); "<="&ROW(H2:H43))<=3);
"select Col1,sum(Col2) group by Col1 label sum(Col2)''")
full explanation here

Can't find the formula to count columns with multiple criterias (OR and AND)

I'm trying to figure out the way to count the number of Draw for each team.
To count as a draw, a match had to be played (So no empty score value on both cells, and the team must appear in either column B or E, and the result must be "Draw")
Can anyone help me find the proper formulae? I already tried to use COUNTIFS but couldn't succeed.
=QUERY(FILTER({B2:B; E2:E}, {F2:F; F2:F}="Draw"),
"select Col1,count(Col1) group by Col1 label count(Col1)''", 0)
and F2 cell would be:
=ARRAYFORMULA(IF(E2:E<>"",
IF(C2:C=D2:D, "Draw",
IF(C2:C>D2:D, B2:B,
IF(C2:C<D2:D, E2:E, ))), ))
Use Two COUNTIFS() and add them together:
=COUNTIFS(B:B,"Real Madrid",F:F,"Draw")+COUNTIFS(E:E,"Real Madrid",F:F,"Draw")

How to use Averageifs or Sumifs in an Arrayformula

I'll post a link to the spreadsheet at the bottom of this write-up.
I'm trying to work out the average of a column of numbers that fall between a date range. The formula below works but I have to drag it down the column, I want it to be an array so it auto updates.
=iferror(averageifs(B$2:B,A$2:A,">="&C2,A$2:A,"<="&D2),1)
So I created it as an array as follows:
=iferror(ArrayFormula(averageifs(B$2:B,A$2:A,">="&C2:C,A$2:A,"<="&D2:D)),1
But it stops after the first cell. So I broke up the average function into sum & count in order to divide.
The count array works using this formula:
=iferror(ArrayFormula(countifs(A$2:A,">="&C2:C,A$2:A,"<="&D2:D)),1)
However the sum array does not even go past the first cell:
=iferror(ArrayFormula(SUMIFS(B$2:B,A$2:A,">="&C2:C,A$2:A,"<="&D2:D)),1)
And the combination gets past the first cell but the calculations all come to zero:
=ArrayFormula(iferror(SUMIFS(B$2:B,A$2:A,">="&C2:C,A$2:A,"<="&D2:D)/countifs(A$2:A,">="&C2:C,A$2:A,"<="&D2:D),1))
What I'm trying to achieve is an average for the previous month.
If anyone can help me I'd be very grateful!
https://docs.google.com/spreadsheets/d/1XhoLl5hB-MpXFz9VS2aLqJOWbXk1d_7apnwKWFdDUlg/edit?usp=sharing
you are trying to apply a bit weird structural logic with lots of repeating values with no reason. basically, it looks like you need this:
=ARRAYFORMULA(QUERY({TEXT(A2:A, "yyyy-mmm"), B2:B},
"select Col1,avg(Col2)
where Col2 is not null
group by Col1
order by avg(Col2) desc
label avg(Col2)''", 0))
but if you really really need so:
=ARRAYFORMULA(IF(LEN(A2:A),
IFERROR(VLOOKUP(TEXT(DATE(YEAR(A2:A), MONTH(A2:A)-1, 1), "yyyy-mmm"),
QUERY({TEXT(A2:A, "yyyy-mmm"), B2:B},
"select Col1,avg(Col2)
where Col2 is not null
group by Col1", 0), 2, 0), 0), ))

Resources