Eliminate 0's in MMULT - google-sheets

Consider the following formula:
=ARRAYFORMULA(MMULT(N('E0:Sample'!$D$2:$AY),TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY))))))
The formula produces an array, in which blank cells are interpreted as 0. How do I get rid of all 0 in the produced range? I've tried to FILTER() it with
=ARRAYFORMULA(FILTER(MMULT(N('E0:Sample'!$D$2:$AY),TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY))))),'E0:Sample'!$D$2:$AY<>0))
but that produces FILTER range must be a single row or a single column.
Any ideas? Thank you!

Try the following pattern
=IF(formula=0,,formula)
In your case the final formula is
=ARRAYFORMULA(IF(
MMULT(N('E0:Sample'!$D$2:$AY),TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY)))))=0,,
MMULT(N('E0:Sample'!$D$2:$AY),TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY)))))
))

Related

How to use COUNTIFS with ARRAYFORMULA

I have this formula that checks for the 2nd(onwards) instance of duplicate using 2 columns. I want it to be automatically applied to new rows but can't seem to figure out how to use ARRAYFORMULA for COUNTIFS. Can anybody please help me convert this formula =COUNTIFS($K$2:$K2, $K2, $T$2:$T2, $T2)>1 to an arrayformula or something similar? Thanks!
MAP() function may be a good solution. Try-
=MAP($K$2:INDEX($K$2:$K,COUNTA($K$2:$K)),$T$2:INDEX($T$2:$T,COUNTA($K$2:$K)),LAMBDA(x,y,COUNTIFS($K$2:$K,x,$T$2:$T,y)>1))
K2:INDEX(K2:K,COUNTA(K2:K)) will return a array of range from K2 to next non empty cell of K column.
Same T2:INDEX(T2:T,COUNTA(K2:K)) will return a array of range from T column still base on K column last non empty cell.
Edit: As per comment, try below formula-
=INDEX(MAP(A2:INDEX(A2:A,COUNTA(A2:A)),C2:INDEX(C2:C,COUNTA(A2:A)),LAMBDA(x,y,COUNTIFS(A2:A,x,C2:C,y,ROW(A2:A),"<="&ROW(x))>1)))
Change ranges for your sheet.

Array formula for a rolling AVERAGEIF formula?

I have a working formula that I need to drag to autofill down a column and want to make it into an array formula:
=AVERAGEIF(INDIRECT("A2:A"&ROW()), ">=0",INDIRECT("A2:A"&ROW()))
So if you put this formula in column B it will take the values in column A and continually average them going down, skipping any values that are less than 0. Here is an example screenshot: https://i.imgur.com/nRq8hAH.png
How can I make an array formula for this?
This formula comes close but I couldn't figure out how to add the ">=0" conditional:
=ArrayFormula(IF(LEN(A2:A),SUMIF(ROW(A2:A),"<="&ROW(A2:A),A2:A)/COUNTIF(ROW(A2:A),"<="&ROW(A2:A)),))
Lambda Update
There is no longer any need to use ArrayFormula for this.
=MAP(SEQUENCE(COUNTA(A2:A)),
LAMBDA(rowOff,
AVERAGEIF(OFFSET(A2,0,0,rowOff),">=0"))
)
How?
For each element rowOff in 1..# items in column:
Use AverageIf to get the average of everything starting at the top taking rowOff rows, excluding everything >=0
Old solution
Here's a single formula that can go into B2 (no need to drag), but it's fairly complicated:
=ArrayFormula(IFERROR(IF(LEN(A2:A),MMULT(TRANSPOSE((SEQUENCE(COUNTA(A2:A),1,2)<=TRANSPOSE(SEQUENCE(COUNTA(A2:A),1,2)))*FILTER(A2:A,LEN(A2:A))),--(FILTER(A2:A,LEN(A2:A))>0))/COUNTIFS(SEQUENCE(COUNTA(A2:A)),"<="&SEQUENCE(COUNTA(A2:A)),FILTER(A2:A,LEN(A2:A)),">=0"),"")))
Readable:
=ArrayFormula(IFERROR(
IF(
LEN(A2:A),
MMULT(
TRANSPOSE(
(SEQUENCE(COUNTA(A2:A),1,2)<=
TRANSPOSE(SEQUENCE(COUNTA(A2:A),1,2))
)*FILTER(A2:A,LEN(A2:A))
),
--(FILTER(A2:A,LEN(A2:A))>0)
)/
COUNTIFS(
SEQUENCE(COUNTA(A2:A)),
"<="&SEQUENCE(COUNTA(A2:A)),
FILTER(A2:A,LEN(A2:A)),
">=0"
),
""
)
))
How?
We can achieve a running sum using MMULT on a Lower Triangular Matrix of size COUNTA(A2:A) of all 1's and all non blanks of A2:A, which we filter out if the number is negative. In this case, it produces {2;2;6;6;6;6}.
The COUNTIFS() produces an array of the number of elements we want to divide by. Here, it's {1;1;2;2;3;4}
Then ignore any blanks at the with IF.
Blank out any errors with IFERROR. (#DIV/0! errors can happen if the leading numbers are negative.)
Perhaps, this formula can help:
=ARRAYFORMULA(AVERAGE(IF($A$2:A2>=0,$A$2:A2,"")))

How to find a value from a range of cells and place at a specific in google sheet

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)

Arrayformula sum one column until this row

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))

Google Sheets right() in Sum in Arrayformula returning false values

I've a column of sample data where each cell is either blank or (3 alpha chars, 1 white space, 1 digit). For example:
I need to check if the cell begins with "GTR" or "DBT", then return the number, and sum the return of the column. I'm using the formula below:
=ARRAYFORMULA(sum(IF(OR(left(A1:A10,3)="GTR",left(A1:A10,3)="DBT"),VALUE(right(A1:A10,1)),0)))
The problem is that instead of returning 20, it returns 52.
In fact it appears to return the last char of any cell in the range. (eg. if "A5" has a value of 'someText' the formula returns an error because value() can't parse 't' into a number.
I'd like to know if anyone can tell me how to solve this problem, or if there's something wrong with my formula?
Here's an example of this problem in a Google Sheet:
https://docs.google.com/spreadsheets/d/1XNVUWhI43UW2ABrja8rmplmxhhkSu-je45F-9F_3GQM/edit#gid=0
Thanks,
Onji
The ArrayFormula plus OR will evaluate to TRUE if any of the cells in the range is in the codition, to overcome this remove the OR, and add an IF for every condition, as such:
=ARRAYFORMULA(sum(IF(left(A1:A10;3)="GTR";VALUE(right(A1:A10;1));0);IF(left(A1:A10;3)="DBT";VALUE(right(A1:A10;1));0)))
In addition to the solution of Kriggs, this formula should also work:
=ArrayFormula(sum(if(regexmatch(B3:B12, "GTR|DBT")=TRUE, right(B3:B12)+0,)))

Resources