In an excel spreadsheet I have multiple sites with 2 rows of data for each site (A, B). There are 25 observations (columns 1 - 5) for each site. I would like to count the number of cases for each site where A + B > 0.
For example,
Site1 A 0 0 1 2 0
Site1 B 1 0 1 0 0
the count would be 3 (that is A+B >0 for 3 cases in site 1). I could add a third line for each site to get the sum and then count the number of cells > 0, but I am not interested in adding an additional line for each site. I have not found an array formula that works for this situation.
=SUM(--((C1:G1+C2:G2)>0))
This is an array formula.
In older versions of Excel, you can use:
=SUMPRODUCT(--((C1:G1+C2:G2)>0))
Or you can enter the original as an array formula
To enter/confirm an array formula, hold down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula seen in the formula bar.
Related
I have a spreadsheet I'm creating and I have an ARRAYFORMULA for incrementing the number of a field based on another field. My formula looks like this (NOTE: my rows start on row 4 that is why there is a ROW(A4:A)-3):
=ARRAYFORMULA(IF(ROW(A4:A) = 4, 1, IF(B4:B = 1, ROW(A4:A)-3, (ROW(A4:A)-3)-(B4:B - 1))))
What I'm doing is creating groups (A) and then have a sequence counter (B) which is the number of rows within the group. I want the result to look like this where the A just picks up from where it left off (Note: B is manually entered):
A
B
1
1
2
1
3
1
3
2
3
3
4
1
5
1
However, my result is looking this this:
A
B
1
1
2
1
3
1
3
2
3
3
6
1
7
1
I know ROW gets me the row number but when I try and use INDEX formula:
=ARRAYFORMULA(IF(ROW(G4:G) = 4, 1, IF(H4:H = 1, INDEX(G4:G, ROW(G4:G)-1, 1) + 1, INDEX(G4:G, ROW(G4:G)-1, 1)))
to get the actual value of the prior cell I get a constant flashing like it's stuck in an infinite loop of some sort. I know I can probably just accomplish this without ARRAYFORMULA however, this spreadsheet will be shared and contains many other formulas that I just don't want people to have to cut and copy from the row above and get formulas all messed up. I'm dealing with non-technical people that need something to just work very simple.
Sample:
https://docs.google.com/spreadsheets/d/1FqndR4oTm_uaO7aUxYSgb3p0bZ6yBz-KnjUAD8kctd4/edit?usp=drivesdk
use:
=ARRAYFORMULA(COUNTIFS(A4:A, A4:A, ROW(A4:A), "<="&ROW(A4:A)))
reverse:
=ARRAYFORMULA(MMULT(TRANSPOSE((SEQUENCE(COUNTA(B4:B))<=
SEQUENCE(1, COUNTA(B4:B)))*IF(INDIRECT("B4:B"&COUNTA(B4:B)+ROW(B4)-1)=1, 1)),
SEQUENCE(COUNTA(B4:B))^0))
This question is related to this one
I have (3,0), (2,1), and (2,0) in rows 1 to 3. There are ways to generate the array of {0,0,0,1,1,0,0} using cell addresses. (See the reference above.)
Now, my question is can the same array be generated NOT using the cell references but using the three pairs of the numbers only?
NOTE: In the real case, there may be up to six pairs of numbers, A1:B1 to A6:B6, and up to 2880 array elements.
Excel 2010
A B
1 3 0
2 2 1
3 2 0
You can proceed as in the edit to my answer to the original question, by generating an array as follows:
0 0 0
1 0 0
1 1 0
and using Mmult instead of Offset to get the running totals of the first column of numbers.
=SUM(INDEX(INDEX({3,0;2,1;2,0},0,2),N(IF({1},MATCH(ROW(A1:INDEX(A:A,SUM(INDEX({3,0;2,1;2,0},0,1)))),
MMULT(IF(ROW(A1:INDEX($1:$1048576,COUNT(INDEX({3,0;2,1;2,0},0,1)),COUNT(INDEX({3,0;2,1;2,0},0,1))))>
COLUMN(A1:INDEX($1:$1048576,COUNT(INDEX({3,0;2,1;2,0},0,1)),COUNT(INDEX({3,0;2,1;2,0},0,1)))),1,0),INDEX({3,0;2,1;2,0},0,1))+1)))))
If you hard-code the number of pairs of numbers instead of using Countif to count them, the formula is shorter:
=SUM(INDEX(INDEX({3,0;2,1;2,0},0,2),N(IF({1},MATCH(ROW(A1:INDEX(A:A,SUM(INDEX({3,0;2,1;2,0},0,1)))),
MMULT(IF(ROW(A1:INDEX($1:$1048576,3,3))>
COLUMN(A1:INDEX($1:$1048576,3,3)),1,0),INDEX({3,0;2,1;2,0},0,1))+1)))))
This is an extension of this question, which was answered by XOR LX.
In the original question, I wanted to count the number of rows in a matrix that included values that fulfilled at least one column-specific criteria. The columns referenced were sequential (e.g., A1:D4), but the situation requires indexing columns that are not sequential.
Take the data matrix:
A B C D E F G H
4 2 2 2 1 4 2 4
5 2 1 3 4 1
3 2 1 4 5 1
1 2 3 5 3 2 2 2
2 2 2 2 2 2 2 2
With the column-specific criteria:
Column A criteria: >2
Column B criteria: >2
Column C criteria: <2
Column D criteria: >4
Column E criteria: >2
Column F criteria: >3
Column G criteria: >2
Column H criteria: >3
In order to count the number of rows that have values for all columns, as well as meet at least column-specific criterion, we could use XOR LX's code:
=SUM(N(MMULT(IF(MMULT(N(A1:H5=""),TRANSPOSE(COLUMN(A1:H5)^0))=0,COUNTIF(OFFSET(A1,ROW(A1:H5)-MIN(ROW(A1:H5)),COLUMN(A1:H5)-MIN(COLUMN(A1:H5))),{">2",">2","<2",">4",">2",">3",">2",">3"}),0),TRANSPOSE(COLUMN(A1:H5)^0))>0))
...which might have some problems with handling blanks, so the alternative:
=ROWS(A1:D4)-COUNTIFS(A1:A5,"<=2",B1:B5,"<=2",C1:C5,">=2",D1:D5,"<=4",E1:E5,">=2",F1:F5,">=3",G1:G5,">=2",H1:H5,">=3")-COUNT(1/N(MMULT(N(A1:H5=""),TRANSPOSE(COLUMN(A1:H5)^0))>0))
...which as far as I have tested seems to handle blanks regardless of their frequency or location.
But what if only rows with data for certain should be counted, ignoring the other columns. Furthermore, what if only certain columns should be evaluated for their criteria?
Let's take the example above. Our goal is to count the number of rows with i) full data in certain columns and ii) entries in certain columns that meet at least one column-specific criterion.
The relevant columns that should have full data are A:C and F:H. The columns that should be evaluated for their criteria are A:C only. The solution is 2 since:
There are 5 rows in total, but only rows 1, 3, 4, and 5 qualify as they have full data in columns A:C and F:H. Row 2 has missing data in column A and also G, either of which should disqualify its inclusion. Notice that even though row 3 has missing data in columns D and E, it is still included because these columns are not important.
Rows 1 and 3 meet the specified criteria, since i) they have full data in columns A:C and F:H, and ii) at least one entry meets one of the criteria for columns A, B, and C; specifically, the value in row 1, column A (4 > 2), and row 3, column A (3 > 2) and column C (1 < 2). Notice that this is still only counted as one row meeting the criteria, even though the criteria for 2 columns is met.
Your thoughts would be most welcome. Please also show some love to XOR LX in the original post - I am sure you will find his solution helpful.
#PyjamaNinja has encouraged me to try and develop my 'lemma' to their earlier question.
The method is:
A Count rows with entries in all specified columns (A-C and F-H)
B Count rows with entries in all specified columns that do _not_ meet any of the criteria in the columns being evaluated (A-C).
Subtract B from A.
=COUNTIFS(A1:A5,"<>",B1:B5,"<>",C1:C5,"<>",F1:F5,"<>",G1:G5,"<>",H1:H5,"<>")-COUNTIFS(A1:A5,"<=2",B1:B5,"<=2",C1:C5,">=2",F1:F5,"<>",G1:G5,"<>",H1:H5,"<>")
With many thanks to #XOR LX.
I want to merge multiple arrays of unique occurrences to a single array. To get the arrays in the first place I use this code, where image series is a slice from a tiff image imported using imread:
a = unique(img_series);
occu = [a,histc(img_series(:),a)];
I do that multiple times, because the tiff image I'm using has multiple hundred images stacked, which my RAM will not support to import at once. So each 'occu' looks something like this (first number is the unique value, second number is the number of occurrences):
occu1 occu2 .....
0 1 1 2
12 1 10 1
14 1 12 1
15 1 14 2
.. .. .. .. .....
Now I want to merge them all together, or better merge them in each iteration, when I'm reading another stacked image.
The merged results should be a 2D matrix similar to the one above. The number of occurrences of the same values should be added to one another, as this is the whole point of counting them. So the result of the above example should be this:
occu_total
0 1
1 2
10 1
12 2
14 3
15 1
.. ..
I found the join command, but that one does not seem to work here. I guess I could do it the long way of searching the matching number and add the occurrences together and so on, but there must be a quicker way of doing it.
A = [0 1;12 1; 14 1;15 1];B = [1 2;10 1;12 1;14 2];
tmp = [A;B]; %// merge arrays into a single one
tmp(:,1) = tmp(:,1)+1;%// remove zero occurrences by adding 1 to everything
C = accumarray(tmp(:,1),tmp(:,2)); %// add occurrences all up
D = [1:numel(C)].'; %// create numbered array
E = [D C];
E((C==0),:)=[]; %// get output
E(:,1) = E(:,1)-1;%// subtract the 1 again
E =
0 1
1 2
10 1
12 2
14 3
15 1
Job for accumarray. This takes the first argument as your dictionary key, and adds the values of the each key together. The addition and subtraction of 1 is done because 0 cannot be an index in MATLAB. To circumvent this (assuming you have no negative numbers), you can simply add 1 and remove that afterwards, shifting all your indices to positive integers. If you hit negative numbers, subtract tmp(:,1) = min(tmp(:,1)+1 and add E(:,1) = min(tmp(:,1)-1
I can't seem to find something quite like this problem...
I have an array table where each row contains a random assortment of numbers 1-N
On another sheet, I have a table with column and row headers numbered 1-N
I want to count how many rows in the array contain both the column and row headers for a given cell in the table. Since countifs only reference the current cell in the specified array, they don't seem to be working in this scenario.
Example array:
A B C D
1 3 5 7
1 2 3 4
2 3 4 5
2 4 6 8
...
Table results (symmetrical about the diagonal):
A B C D E F
. 1 2 3 4 5 ...
1 - 1 2 1 1
2 1 - 2 2 1
3 2 2 - 2 2
4 1 2 2 - 1
5 1 1 2 1 -
Would using nested countifs work?
I don't agree with your results corresponding to 4/2, which surely should be 3, not 2, but this formula, based on the array table being in Sheet1 A1:D4 and the results table being in Sheet2 A1:F6, placed in cell B2 of the latter, should work:
=IF($A2=B$1,"-",SUMPRODUCT(N(MMULT(N(COUNTIF(OFFSET(Sheet1!$A$1:$D$1,ROW(Sheet1!$A$1:$D$4)-MIN(ROW(Sheet1!$A$1:$D$4)),),CHOOSE({1,2},B$1,$A2))>0),{1;1})=2)))
Copy across and down as required.
Note: If your actual table is in fact much larger than that given, it will probably be worth adding a simple clause into the above to the effect that the results for approximately half of the cells are obtained from their symmetrical counterparts, rather than via calculation of this construction, thus saving resource.
Regards