I have a list of numbers (ex. 5, 7, 10, 11, etc.) and 0s in excel rows from D2:BH2, and I want to calculate the longest streak of 0s in each row (with 2 conditions).
The first condition is to ignore streaks that start the row with 0
Ex. (0 0 0 1 5 6 0 0 1) -> this would have a longest streak of 2 instead of 3 due to the first condition
Ex. ('1 0 0 0 1 5 6 0 0 1') -> this would have a longest streak of '3'
The second condition is to ignore streaks that end the row with 0
Ex. (0 1 5 6 0 0 1 0 0 0 0 ) -> this would have a longest streak of 2 instead of 4 due to the second condition.
Ex. (' 0 1 5 6 0 0 1 0 0 0 0 1') -> this would have a longest streak of '4'
Is there a simple way of calculating the streak of 0s based on these two conditions for each row (in one cell formula)?
Currently I'm using a formula:
=MAX(FREQUENCY(IF(D2:BH2=0,COLUMN(D2:BH2)),IF(D2:BH2=0,0,COLUMN(D2:BH2)
This calculates the longest streak; however, does not take into account the two conditions.
Based on this answer where we could trim only leading/trailing spaces, you could try:
Formula in L1:
=BYROW(A1:J4,LAMBDA(a,LET(x,CONCAT(SIGN(a)),y,TEXTSPLIT(x,0,,1),IFERROR(MAX(LEN(DROP(DROP(TEXTSPLIT(0&x&0,,y),1),-1))),0))))
This also seems to work if you modify the frequency formula slightly so that the counts of all leading and trailing zeroes are gathered into the first and last cells of the Frequency array then drop those cells:
=MAX(DROP(DROP(FREQUENCY(IF(A1:J1=0,COLUMN(A1:J1)),IF(A1:J1<>0,COLUMN(A1:J1))),1),-1))
If you have all zeroes or only one non-zero value it will error but the correct answer should be zero so updated formula should be:
=IFERROR(MAX(DROP(DROP(FREQUENCY(IF(A1:J1=0,COLUMN(A1:J1)),IF(A1:J1<>0,COLUMN(A1:J1))),1),-1)),0)
Of course you can byrow it:
=BYROW(A1:J6,LAMBDA(r,IFERROR(MAX(DROP(DROP(FREQUENCY(IF(r=0,COLUMN(r)),IF(r<>0,COLUMN(r))),1),-1)),0)))
Related
I would need to get the average of the 2nd to the 8th nonzero value per row. Meaning, it would always move depending where the nonzero begins at.
I think what I would need is to determine the following:
Location of the 2nd nonzero value
Location of the 8th nonzero value
Average of numbers between 2nd and 8th nonzero values
Is that possible?
For example
0 | 6 | 10 |5| 9 | 0 | 6 | 0 |3 | 10| 1|9|
Those in bold have to be averaged. The zeroes in between have to be ignored
If you are using Windows Excel 2019, then:
=AVERAGE(FILTERXML("<t><s>" &TEXTJOIN("</s><s>",TRUE,IF(row_ref<>0,row_ref,""))&"</s></t>","//s[position()>1 and position()<10]"))
TEXTJOIN extracts only those values which are non-zero (and non-blank)
By using the appropriate delimiters, we create an XML
The xPath with the position function then extracts the 2nd to 8th values (positions 2 through 9)
AVERAGE
Assuming your data is laid out as per the example below, place the following formula in column T and copy down as required.
=IFERROR(AVERAGE(INDEX(22:22,AGGREGATE(15,6,COLUMN(B22:S22)/(B22:S22<>0),ROW($2:$9)))),"Less than " & rows($2:$9) & " non zero numerical entries")
B22:S22 - represents the row of data you are looking at. Feel free to change the column reference letters to suit your needs. Just ensure all the references with in the formula match.
$2:$9 - Represents the number of entries you want to use as part of the average. 2 is the starting number that you want to use and corresponds to 2nd non zero. 9 is the last number you want to include and makes a total of 8 numbers. Adjust these number to change the data range you want to include.
Ensure you keep the $ to prevent the row number from changing as the formula is copied.
Aggregate performs array like operations. As a result it may cause your system to bog down or crash if there is an excessive number of rows you are looking at. Also, full column references should generally be avoided within the aggregate function to avoid excess calculation.
I placed my answer not in A1 to make sure it will work anywhere on your sheet.
Assuming a layout like this (your first row of numbers from D2 to T2):
Paste this to Y2 (in the combined) column:
=AVERAGEIF(OFFSET(C2,0,AGGREGATE(15,3,((D2:T2)>0)/((D2:T2)>0)*COLUMN(D2:T2)-COLUMN(C2),2)):OFFSET(C2,0,AGGREGATE(15,3,((D2:T2)>0)/((D2:T2)>0)*COLUMN(D2:T2)-COLUMN(C2),8)),">0")
Then copy down to the other rows.
Data I used:
1 2 0 6 4 9 0 7 3 7 1 1 1 2 6 9 7
0 0 7 0 1 1 4 4 1 5 8 3 5 6 4 6 4
1 7 2 8 0 6 4 9 9 7 8 4 6 9 4 2 9
0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0
8 7 8 4 10 0 2 2 10 4 4 8 3 3 0 4 10
In this formula, C2 is the cell (empty or not) before the beginning of the row of numbers and not included in the numbers to be counted.
Assuming you have excel 365, this can be easily done using simply FILTER, INDEX and AVERAGE function
=AVERAGE(INDEX(FILTER(row_ref,row_ref>0),{2,3,4,5,6,7,8,9}))
Example
=AVERAGE(INDEX(FILTER(B5:N5,B5:N5>0),{2,3,4,5,6,7,8,9}))
I have an arbitrary number of columns, one for each period a course is offered, in chronological order, and an arbitrary number of rows, one for each unique participant. The values are '1' for participation in that month, '0' for non-participation.
Fall2019 Spring2019 Fall2018 Spring2018 Fall2017
1 1 0 1 0
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 0 1 1
0 1 1 0 0
0 1 1 0 0
0 1 1 0 0
1 0 0 0 0
I would like to take a sum, at the bottom of each column, for how many participants were first time attendees that period, i.e. the sum of '1's where all values in the row to the right of that '1', are '0'.
In the given example set, Spring2018 should sum to 1, Fall2018 should sum to 3.
Something like the formula below will work for 'Spring2018' when there is just one previous column to compare:
=SUMPRODUCT((D2:D9)*(E2:E9=0))
But this formula cannot be 'autofilled' or extended across multiple columns... i.e. none of these variations work:
=SUMPRODUCT((C2:C9)*(D2:$E9=0))
=SUMPRODUCT((C2:C9)*(SUM(D2:$E9)=0))
=SUMPRODUCT((C2:C9)*(SUMIF(D2:$E9,"0")))
And while it will work, I do NOT want to have to manually create extended versions of this formula e.g.
=SUMPRODUCT((C2:C9)*(D2:D9+E2:E9=0))
=SUMPRODUCT((B2:B9)*(C2:C9+D2:D9+E2:E9=0))
... and so on
I have tried several variations on arrayformula, sumproduct, and sumif, but I'm really stuck. Any assistance is appreciated.
use this array formula:
=SUM(A2:A10*(MMULT(--(B$2:$E$10=1),TRANSPOSE(COLUMN(B$2:$E$10)^0))=0))
Being an array formula it must be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode.
In this article there is directions on determining the number of consecutive cells greater than 0. I want to do something similar, but instead of simply counting the number of consecutive columns there are, I want to sum them up.
For example, 0 0 0 1 2 0 0 5 would be 3 (1+2=3)
Edit: If for example, there is multiple max consecutive numbers (e.g., 0 0 1 3 0 0 4 5) I would want the highest sum (9) to be chosen.
Edit2: The data is set-up in rows (X axis is months I need to sum for consecutives and Y axis is "user") so the formula would match the examples I've given above.
My goal is to count and potentially conditionally format the occurrences when a certain number of days pass with 0 sales.
I am trying to return the number of times 0 is repeated consecutively 3 or more times. So for this example I would like to see the return value of 3. So far I can't wrap my brain around how to do this, any ideas?
1
5
0
0
0
0
0
2
0
0
1
0
2
0
0
0
5
0
0
0
0
Thanks!
So #Barry Houdini's method applied to this problem would give
=SUM(--(FREQUENCY(IF(A1:A21=0,ROW(A1:1A21)),IF(A1:A21>0,ROW(A1:A21)))>=3))
entered as an array formula using CtrlShiftEnter
If you wanted to make it more dynamic and exclude blanks you could use
=SUM(--(FREQUENCY(IF(A1:A100<>"",IF(A1:A100=0,ROW(A1:A100))),IF(A1:A100>0,ROW(A1:A100)))>=3))
How about you make a help column with a simple sum formula with a "window" of three rows (or whatever you need). Then you conditionally format all values which are 0 in that column. That should provide you with the information you are looking for.
I have this example:
I need a formula to count all the numbers after the first aparition of a non zero value.
The Values range is A1:H4. But i need count for every line A1:H1; A2:H2...A4:H4.
0 0 7 2 0 0 0 9 - result of numbers counted 6
5 0 4 0 2 0 0 0 - result of numbers counted 8
0 0 0 0 0 0 7 0 - result of numbers counted 2
0 0 0 0 0 0 0 4 - result of numbers counted 1
Thank you!
c
If the values are in A1:H1, array formula**:
=COUNT(H1:INDEX(1:1,MATCH("",T(1/A1:H1),0)))
To take an example: with A1:H1 containing:
0 0 7 2 0 0 0 9
the reciprocation:
1/A1:H1
will return:
{#DIV/0!,#DIV/0!,0.142857142857143,0.5,#DIV/0!,#DIV/0!,#DIV/0!,0.111111111111111}
Applying the T function to this array returns:
{#DIV/0!,#DIV/0!,"","",#DIV/0!,#DIV/0!,#DIV/0!,""}
i.e. all non-zeroes in the original range have now been reduced to the null string ""; all zeroes to an error.
We can now perform an exact match for the null string, such that:
MATCH("",T(1/A1:H1),0)
which is:
MATCH("",{#DIV/0!,#DIV/0!,"","",#DIV/0!,#DIV/0!,#DIV/0!,""},0)
gives:
3
And so:
INDEX(1:1,MATCH("",T(1/A1:H1),0))
which is:
INDEX(1:1,3)
returns a range reference to the cell:
C1
and so, finally:
COUNT(H1:INDEX(1:1,MATCH("",T(1/A1:H1),0)))
which is:
COUNT(H1:C1)
in which Excel will correct the range reference to:
COUNT(C1:H1)
is:
6
as required.
Regards
**Array formulas are not entered in the same way as 'standard' formulas. Instead of pressing just ENTER, you first hold down CTRL and SHIFT, and only then press ENTER. If you've done it correctly, you'll notice Excel puts curly brackets {} around the formula (though do not attempt to manually insert these yourself).
=LEN(RIGHT(A1,FIND("1",A1&"1")))