count occurence of values individually and as a group in excel row - excel

o/p is the required column which is how many times D and P occured in a row either individually or as a group i.e if D and P occurs continuously, it is counted as 1. I am pretty sure there must be a formula for this somewhere only it is difficult to phrase the right words to search it. Hence this question here. Looking for a formula that does the job.

Give the following a try, assuming it's either "U", "D" or "P":
Formula in A1:
=BYROW(B1:L4,LAMBDA(a,IFERROR(COLUMNS(TEXTSPLIT(CONCAT(a),"U",,1)),0)))
Above works for newest versions of Excel, for older CSE-required versions of Excel try:
=SUM(N(FREQUENCY(IF(B1:L1<>"U",COLUMN(B1:L1)),IF(B1:L1<>"U",0,COLUMN(B1:L1)))>0))

If U can be any text or character other than P or D then the following should work:
=LEN(TEXTJOIN("",1,0,MMULT({1,1},--({"D";"P"}=B2:L2))))-LEN(SUBSTITUTE(TEXTJOIN("",1,0,MMULT({1,1},--({"D";"P"}=B2:L2))),"01",2))
Or using Office 365 this spills the result:
=LET(t,BYROW(B2:L12,LAMBDA(b,TEXTJOIN("",1,0,MAP(b,LAMBDA(m,--(OR(m={"D";"P"}))))))),
DROP(REDUCE(0,t,LAMBDA(x,y,VSTACK(x,LEN(y)-LEN(SUBSTITUTE(y,"01",2))))),1))
Both formulas convert the cells to 0 (FALSE) or 1 (TRUE) if the cell equals P or D. The results of one row are joined with a leading 0 and SUBSTITUTE looks for each occurrence of 01 in given string and replaces these 2 characters by 1. If we then compare it to the stringlength prior to the substitute, we have the answer to your question.

Related

excel - count if multiple words are in a cell

I have values
AA,BB,CC
AA,CC
AA
AA,BB
BB
BB,CC
CC
CC,AA
CC,BB
BB,CC,DD
find all cells that have. how do I search for each values.
AA,BB = 2
BB,CC = 4
Example
COUNTIFS($A:$A,"*AA*",$A:$A,"*BB*") doesn't seem to work.
You could try this using wildcards * with TEXTBEFORE() & TEXTAFTER()
• Formula used in cell D2
=COUNTIFS(A1:A10,"*"&TEXTBEFORE(C2,",")&"*",A1:A10,"*"&TEXTAFTER(C2,",")&"*")
EDIT
As suggested by Tom Sharpe Sir,
• Formula used in cell D2
=LET(x,TEXTSPLIT(C2,","),y,COUNTA(x),
SUM(--(MMULT(N(ISNUMBER(SEARCH(x,$A$1:$A$10))),SEQUENCE(y,,1,0))=y)))
You could try:
Formula in D2:
=MAP(C2:C5,LAMBDA(z,SUM(MAP(A1:A11,LAMBDA(x,LET(y,TEXTSPLIT(z,,","),N(SUM(N(TEXTSPLIT(x,",")=y))=ROWS(y))))))))
Note: My answer assumes no duplicates in the values in column A:A. e.g.: AA,AA.
How about:
=LET(searchvalues, C2,
data, $A$1:$A$10,
split, TEXTSPLIT(searchvalues,","),
count, COLUMNS(split),
SUM(
--(MMULT(
--ISNUMBER(SEARCH(split,data)),
SEQUENCE(count,,1,0))
=count)))
It splits the values you want to search (stored in C2 in my example) into individual values: split
Than split is searched within each row of your data.
This returns TRUE or FALSE wrapped in -- changes TRUE to 1 and FALSE to 0.
This is used within MMULT and this returns the sum of the occurrences of each individual split value. Finally the MMULT result needs to equal the number of splitted search values.
The sum of this being true is the end result.
The following approach considers a variable number of words to search, not just 2 words as in the input sample:
=LET(lk, B1, A, $A$1:$A$11, lks, TEXTSPLIT(lk,, ","),
byr, BYROW(A, LAMBDA(x,SUM(COUNTIF(x,"*"&lks&"*")))), SUM(N(byr=ROWS(lks))))
It has a caveat that if the word is repeated more than one time per row in the first column, it is counted as 1, as you can see in the following output. This is because of how COUNTIF (or COUNTIFS) works with wildcards (other answers provided using SEARCH produce the same result). If that assumption is ok, then it works. The rest is just to drag the formula down (formula1).
UPDATE: Considering #JvdV's comment, to avoid false positive when the word to search could be a substring of the column A on a given row. Like for example, searching the word AA, in the string: AAA will produce a false positive. The following version avoids it:
=LET(lk, B1, A, $A$1:$A$11, lks, TEXTSPLIT(lk,, ","),
byr, BYROW(A, LAMBDA(x, SUM(N(TEXTSPLIT(x,",") = lks)))), SUM(N(byr=ROWS(lks))))
Here is the output:
I added intentionally the highlighted cases to test additional situations. Row 11 repeats the word: AA, and BB, but it is counted as 1 in the final result.
The following approach tries to identify the total number of counts considering repetitions of the word in column A (formula2):
=LET(lk, B1, A, $A$1:$A$11, lks, TEXTSPLIT(lk,, ","),
byr, BYROW(A, LAMBDA(x, LET(match, IFERROR(TOCOL(XMATCH(TEXTSPLIT(x, ","),
lks),2),0), ux, UNIQUE(match), IF(ROWS(ux) < ROWS(lks), 0,
MIN(MMULT(TRANSPOSE(N(match = TOROW(ux))), SEQUENCE(ROWS(match),,1,0))))))),
SUM(byr))
Now we get the following result:
Now we get an additional count for the case of AA, BB.
In formula2, match has the index position as a result of the XMATCH call, we use TOCOL to remove non-found values #N/A. In case no words were found, we use IFERROR to assign the zero value. The IF condition:
IF(ROWS(ux) < ROWS(lks)
Ensures to calculate non-zero counts only if all words were found. We use MMULT to calculate per row the number of repetitions of the lookup words. We take the minimum, to ensure we only consider the scenarios where all the words are present. There could be a situation, where one of the lookup words has more counts than another one, which is why we take the minimum. Therefore we are counting the entire set of lookup words found regardless of the order,
Answer was
COUNTIFS($A:$A,"*"&$C$2&"*",$A:$A,"*"&$C$3&"*")
C2 = AA
C3 = BB

Need to count contents of cells to produce a knitting pattern

So this needs a bit of detail:
n,X,X,X,n is in cells B5 to F5
I need to get the following output:
1n,3x,1n
for this particular row.
Now the n's and X's represent stitches in knitting with the "n" being the background color and the "x" being the front color.
There is an array of cells B5:F12 representing the rows and stitches, so each row will have a different arrangement of stitches or background color.
I need to avoid vba as this needs to be as stable as possible with the user being my Mum who is 90 years old :) and all she needs is a place to enter the name and the layout (which I have done) and a pattern list for each row (also sorted).
I have started to consider things like:
if(B5=C5,1&B5,"")
But given the n umber of combinations that becomes very long.
Any ideas? Cheers.
You could try:
Formula in H5:
=BYROW(B5:F12,LAMBDA(x,LET(z,REDUCE(VSTACK(TAKE(x,,1),1),DROP(x,,1),LAMBDA(a,b,IF(b=#TAKE(a,,-1),IF(COLUMNS(a)=1,VSTACK(b,TAKE(a,-1)+1),HSTACK(DROP(a,,-1),VSTACK(b,DROP(TAKE(a,,-1),1)+1))),HSTACK(a,VSTACK(b,1))))),TEXTJOIN(",",,DROP(z,1)&TAKE(z,1)))))
I'll see if I can golf the bytecount down a bit...
EDIT:
After a considerable amount of golfing (came down to 119), I came up with:
=BYROW(B5:F12,LAMBDA(x,MID(REDUCE("",x,LAMBDA(a,b,IF(RIGHT(a)=b,LEFT(a,LEN(a)-2)&1+LEFT(RIGHT(a,2)),a&",1")&b)),2,99)))
Though less dynamic than the 1st one, but possible due to the fact there are only <10 columns for each knitting pattern.
If your mother doesn't have the latest Excel (with LAMBDA etc), here is an alternative to #JvdV's answer which only uses LET,SEQUENCE and FILTER.
It only accepts a single row, so you'd need to fill the formula down.
=LET(p,LOWER(B5:F5),c,COLUMNS(p),s,SEQUENCE(,c),
a,IF(s=c,c,IF(INDEX(p,,s)<>INDEX(p,s+1),s,0)),
b,FILTER(a,a>0),t,SEQUENCE(,COLUMNS(b)),
n,IF(t=1,INDEX(b,,t),INDEX(b,,t)-INDEX(b,,t-1)),
TEXTJOIN(",",TRUE,n & INDEX(p,,b)))
I might add that it allows for adding more than one colour into the pattern ...
and with a bit of conditional formatting, the good lady can design her own multicolour patterns!
This is just a start of a solution, but in cell "B6" you can put the formula:
=(IF(B5=A5,A6+1,1))
This will generate following list:
B C D E F
5: n x x x n
6: 1 1 2 3 1
From there, you can try to get the Subtotals feature to work, based on the Max formula, ... (as I said, this is just a start).
If you are willing to spread the logic over multiple sheets, it's quite easy to come up with a way to do this. Consider a workbook with three sheets:
Pattern
EqualPrevCol, where each cell of Pattern is checked for equality against the previous column of the same row.
The formula for cell EqualPrevCol!D3 is:
=Pattern!D3=Pattern!C3
And finally PatternResult, where most of the logic resides:
Consider one row of EqualPrevCol:
At every FALSE column, we want to know how many columns until the next FALSE. To do this, we want to find the next exact MATCH for D3 in the rest of the row:
=MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0)
If no match is found, that means the rest of the row is all TRUE. In this situation, we want to return the length of the rest of the row plus this current cell.
=IFNA(MATCH(...), COLUMNS(D3:$H3))
And finally, we append this to the current character:
=IFNA(...) & Pattern!D3
Also, if the 7 row at this column is TRUE, we want to keep this blank:
=IF(EqualPrevCol!D3, "", IFNA(...) & ...)
The full formula of cell PatternResult!D3 is:
=IF(EqualPrevCol!D3, "", IFNA(MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0), COLUMNS(D3:$H3)) & Pattern!D3)
Finally, the pattern is condensed to the Pattern sheet. The Pattern!B3 cell contains:
=TEXTJOIN(", ", TRUE, PatternResult!D3:$H3)
To scale this up, you simply need to change all occurrences of $H in the formulas (this was a reference to the last column) and re-fill the cells on the latter two sheets.

Total occurrences of a single digit from a string of digits across a range of cells in a column

We need to count how many occurrences of each number are in a cell over a range of cells in the same column and output a tally of the totals for each number. See the attached picture and the desired output in the column next to it. We tried other formulas found online in both excel and open office with no results.
letter Count
Working Count
Try the following formula in D1:
=LEN(TEXTJOIN("",TRUE,A:A,"#"))-LEN(SUBSTITUTE(TEXTJOIN("",TRUE,A:A,"#"),C1,""))
and populate down.
(you will need 2016 or later for TEXTJOIN)
Option 1
Single array formula (ctrl+shift+enter !) which will work for strings with a maximum length of [5] alphanumeric characters (but you can easily modify the formula by adding a few numbers in the hard-coded array constant {1,2,3,4,5}):
{=SUM(N(MID($A$1:$A$500,{1,2,3,4,5},1)=TEXT(C3,"#")))}
You can add some further trickery to let Excel define the array constant, so the formula will work for any length of the string of digits :
{=SUM(N(MID($A$1:$A$500,
COLUMN(INDIRECT("A1:"&CHAR(65+MAX(LEN($A$1:$A$500)))&"1"))
,1)=TEXT(C3,"#")))}
The part in the middle (COLUMN()) creates the {1,2,3,4,5} array. You might have seen other versions of this formula, without the CHAR, which I use to create a reference to e.g. cell E1 (knowing that 65 is the code for "A").
.
Option 2
This array formula (ctrl+shift+enter !) works in all Excel versions, but is not very "elegant" as you have to repeat the key part of the formula as many times as the maximum digits you have in your cells (this example is for max 3 characters):
{=SUM(
N(MID($A$1:$A$500;1;1)=TEXT(C3;"#"))+
N(MID($A$1:$A$500;2;1)=TEXT(C3;"#"))+
N(MID($A$1:$A$500;3;1)=TEXT(C3;"#")) )}
The character you are counting is in C3. This will work for numbers and letters. If you can have five alphanumeric characters, you have to add two more N(...) parts, and replace the second parameter of the MID function with 4 and 5 respectively.

Auto increment after concatenating 3 strings

Problem: I need a formula to automatically increment when dragging down. Since the 3 strings are joined by concatenating, it doesn't seem to work.
=CONCATENATE("Sheet2!", SUBSTITUTE(ADDRESS(1,MATCH("String to Search For", Sheet2!$13:$13,0),4),1,""),"17")
String 1 is a separate sheet reference (Sheet2!)
String 2 is the column number converted to column letter where string to be searched is found using MATCH, ADDRESS, and SUBSTITUTE. In this case it was column 2 converted to B.
String 3 is the row number that I need information from IF string searched is found
After concatenating these, I need to drag it down 5000 rows and increment String 3 (the row number) but because the reference is concatenated, it will not increment. I've tried everything! Please help!
Try adding a ROWS function, e.g. if you put the first formula in Z2 use this version copied down
=CONCATENATE("Sheet2!", SUBSTITUTE(ADDRESS(1,MATCH("String to Search For", Sheet2!$13:$13,0),4),1,""),"17"+ROWS(Z$2:Z2)-1)
change depending on actual start cell
ROWS function, used this way, will increment by 1 each row and is more "robust" than alternatives using ROW for example
Assuming your formula is in row 2, you could do this:
=CONCATENATE("Sheet2!", SUBSTITUTE(ADDRESS(1,MATCH("String to Search For", Sheet2!$13:$13,0),4),1,""),text(row()+15,"#"))
If your formulas starts on a different row, just change the 15 as needed.

Find items in a list that contain all sub-items

I have two lists as follows, Column A and Column D:
I would like to find all cells in Column A that do not contain a value from Column D.
For instance, A1 should be 0 because it contains the values 'a', 'b', 'c' and 'd' - all of which are in Column D.
A2 should be 1 because it contains the value 'h' - which is not in Column D.
My formula so far is very simple:
=COUNTIF(D1:D7,"*"&$A1&"*")
I'm guessing I could split the values in Column A to check, but am not too sure how.
I would like to avoid any VBA if possible.
Your question is not entirely clear to me, so far as what you want for results under different circumstances.
Your formula will return an array of values, so you need to account for that. The array consists of a 1 or a 0 depending on whether the character matches a letter in the D1:D7 range.
If you want to return the number of letters in your column "A" item that do NOT match an entry in Column "D", then try:
=LEN(A1)-SUMPRODUCT(COUNTIF(A1,"*"&$D$1:$D$7&"*"))
The SUMPRODUCT functions sums the array that the COUNTIF function is returning.
If you want something else, you will need to be more specific.
Cross-tabular layout
Using your logic, just with different layout of the data, you can achieve this:
Formula for B4 is: =COUNTIF(B$3;"*"&$A4&"*")
Formula for B1 is: =B2-SUM(B4:B10)
This is more along the lines of a comment, but I don't have enough reputation yet for comments.
The accepted answer from #ronrosenfeld will not work if the string in Column A contains repeated characters from the list in Column D. For example, if A1 contains "abca," it will return 1 rather than 0 because the array entry for "a" is 1 rather than 2 (it can only be 0 or 1).
So be aware that it only works if the letters are not repeated.
I cobbled a formula together based on some array magic I found by #ronrosenfeld here. (It seems so appropriate that Ron already got credit for answering this question, as my answer is a modification of another of his.)
The following formula works for any length of string in Column A and for any combination of letters including duplicates. It is entered as a regular formula:
=IFERROR(SUMPRODUCT(MATCH(MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1),D$1:D$7,0)=1),1)
You just enter it in B1, then copy it down as far as you like.
It works for strings of any length. If a cell is blank, it returns 1 because there is nothing there that appears in the list. If you want 0 for a blank cell, you can adjust the formula for that situation. Brute force approach:
=if(isblank(a1),0,IFERROR(SUMPRODUCT(MATCH(MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1),D$1:D$7,0)=1),1))

Resources