I have an Excel table like this shown below. There are some empty cells under each header F1, F2, F3, F4, and F5.
Path F1 F2 F3 F4 F5 NewPath
image1.png 1 0 -1 1
image2.png 1 -1 1
image3.png 1 0 1 -1 1
image4.png 1 0 0 1
image5.png 1 1 1 -1
image6.png 1 -1
image7.png -1 1 1 0
image8.png 0 1 1
I have to write the values in column 1 (under the header "Path") to the column (under the header "NewPath") only if the following conditions are satisfied:
There should be a 1 in F3 and not any other value, i.e., 0, -1, or empty field.
There should not be a 1 or -1 in any of F1, F2, F4, and F5.
Whatever cell you need to write to, you can use an if/and statement. Assuming that the word "Path" is in cell "A1" this might look like the following:
=if(and(d2=1,b2<>1,b2<>-1,c2<>1,c2<>-1,e2<>1,e2<>-1,f2<>1,f2<>-1),a2,"Incorrect Value Found")
Then, just copy down the formulas. I put in "Incorrect Value Found" for those instances that do not satisfy your conditions, but this could be anything. If you need to cut those out after the fact, you could do so by filtering, ordering them to the bottom, or a slicer on a pivot table.
Hope this helps. Let me know if I missed the mark on my understanding of the question.
Would something like
=IF(AND($D2=1,COUNTIF($b2:$f2,"<>0")>=1),$A2,"")
Work for you?
There is no match in the input data based on your requirements. I modified (highlighted cells, see screenshot below) the input data so we can have at least one match for testing purpose.
In cell G2 put the following formula:
=LET(f3Cond, $D$2:$D$9=1, f1f2f4f5Cond,
MMULT(ABS(CHOOSECOLS(B2:F9,{1,2,4,5})),{1;1;1;1})=0,
allCond, IFERROR(XMATCH(f3Cond * f1f2f4f5Cond,1),""),
MAP(allCond, A2:A9, LAMBDA(a,b,IF(a=1, b, "")))
)
and here is the output:
Explanation
We use LET to define intermediate calculations. The variable f1f2f4f5Cond represents the condition for F1, F2,F4 and F5 columns.
MMULT(ABS(CHOOSECOLS(B2:F9,{1,2,4,5})),{1;1;1;1})=0
We use CHOOSECOLS to select the specific columns from range B2:F9 we need to evaluate the conditions. We need to exclude 1, -1, so we use ABS to ensure MMULT returns the sum of all 1's per row. We can use MMULT for this purpose because the only values we have are 0,1 and empty. All the conditions are valid if the total number of 1's is 0.
Note: As an alternative you can replace the MMULT calculation with the following:
= BYROW(ABS(CHOOSECOLS(B2:F9,{1,2,4,5})),
LAMBDA(a, SUM(a)=0))
We use XMATCH to identify the rows where all the conditions are met.
IFERROR(XMATCH(f3Cond * f1f2f4f5Cond,1),"")
#N/A values are converted to empty string. The array allCond has 1 only where all conditions are met, otherwise empty string.
Finally we use a MAP function to populate the Path column value from the rows that matches the conditions, otherwise an empty string.
Related
I have a list of 1s and 0s in excel row ranging from B2:K2, I want to calculate the current streak of 1's in cell M2,
example dataset where streak would be 4
1 0 1 0 1 1 1 1 0
Is there a simple way of doing this? I have tried research but not been able to find anything specific.
Any help would be much appreciated.
Here is a way of doing this with just one formula, no helper columns/rows needed:
The formula used translates to:
{=MAX(FREQUENCY(IF(B1:K1=1,COLUMN(B1:K1)),IF(B1:K1=1,0,COLUMN(B1:K1))))}
Note: It's an array formula and should be entered through CtrlShiftEnter
Assuming your data is layed out horizontally like the image below, the following two formulas should do it for you.
The first cell requires a different formula as the is no cell to the left to refer to. so a simple formula to check if the first cell is one or not is entered in B2.
=--(A1=1)
The part in the bracket will either be true or false. A quirk of excel is that if you send a true or false value through a math operation it will be converted to 1 for true and 0 for false. That is why you see the double - in front. could have also done *1, /1, +0,-0 at the end.
In B2 place the following formula and copy right as needed:
=(A2+1)*(B1=1)
Basically it adds 1 to the series, then check if the number in the sequence is 1 or 0. In the event its one, it keeps the value as it is TRUE sent through the math operator *. If it is false it set the sequence back to zero by multiplying False by the math operator *.
Alternate IF
Now the above while it works and may save a few characters is not necessarily intuitive for most. The go to option would be to use an IF function. The above formulas can be replaced with the following:
A3
=IF(A1=1,1,0)
B3 ->Copied right
=IF(B1=1,A3+1,0)
Longest streak
To get the longest streak, the highest value in your helper row is what you want. You can grab this with the following formula in an empty cell.
=MAX(2:2)
=MAX(A2,I2)
If you have no other numbers in your helper row, you can use the first formula which looks in the entire row. If there are other numbers due to calculations off to the left or right as an example, then you will want to restrict your range to you data as in the second formula.
I've put those values in cells B2 to B8.
In cell C3, I've put this formula:
=IF(AND(B3=1;B2=1);C2+1;1)
Dragging this downto C8, and then take the maximum of the C column.
Given a subset A:
selection
1
2
3
4
5
of Excel sheet:
col1 col2 and so on...
1 kuku
300 pupu
4 abcd
22 sfds
900 aqww
I would like to select "selection" content from the sheet, like we can do in SQL:
select * from excel_sheet where col1 == selection
How can I do this in Excel?
You could try something like this but it has to be pulled down and across to get all the rows and columns that match
=IFERROR(INDEX(A$2:A$6,SMALL(IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-1),ROW()-1)),"")
Has to be entered as an array formula using CtrlShiftEnter
Another approach would be to add a helper column to the database and filter on it.
The operation of the formula is as follows (working from innermost to outermost)
MATCH($A$2:$A$6,$D$2:$D$6,0))
Match normally takes a single lookup value Match(lookupValue,range,options) but can also be used with an array of lookup values in which case it returns an array containing the result of each of the lookup values, in this case for each cell in A2:A6 which when looked up in D2:D6 gives
1; #N/A; 4; #N/A; #N/A
ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0))
We don't want to know where the match is in D2:D6, just whether it has been successful or not. ISNUMBER produces
true: false; true; false; false
IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-1)
We want to find the rows in A2:A6 where the successful matches occur. If the test fails, the output will just be false so you get
2; false; 4; false ; false
and subtract one so you get
1; false; 3; false; false
SMALL(IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-1),ROW()-1)
Row() refers to the row of the cell containing the formula (initially F2) so you get 2, then subtracting 1 from that you get 1. So SMALL will give you the smallest element of the above array: 1. When the formula is pulled down into B3, it will give you the next non-false element in the array: 3.
INDEX(A$2:A$6,SMALL(IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-1),ROW()-1)),"")
Standard use of INDEX to give the nth cell in the range A2:A6. In F2, this is the first cell containing 1. In F3, it's the third cell, containing 4. In G2, the formula is pulled across so it applies to the range B2:B6.
=IFERROR(INDEX(A$2:A$6,SMALL(IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-1),ROW()-1)),"")
If the index/match fails because there are no more matches, IFERROR shows an empty cell.
These formulae look complicated, but they're built up from patterns which are fairly standard and recognised by the community of regular Excel users.
The formula could be improved by removing the hard-coding of -1 so it is less vulnerable to insertions/deletions
=IFERROR(INDEX(A$2:A$6,SMALL(IF(ISNUMBER(MATCH($A$2:$A$6,$D$2:$D$6,0)),ROW($A$2:$A$6)-ROW(A$1)),ROW()-ROW(A$1))),"")
I have a data set. There is a signal triggered at one point: it change from 1 -> 0 ( I know the column number), the column looks like this
00000111111000022222233333 (transpose this line please)
I want to write a command that do this (not necessarily a macro)
if row(x) = = 1 && row (x+1) = = 0
return x
the problem is I don't know how to use IF(AND... without the row number...
Thank you for your help in advance
Supposing the column for the signal is B starting in row 1 then in another column (say C starting in C2 ) enter
=if(AND($B1=1,$B2=0),"Trigger","")
and copy down, then filter on Trigger
The following formula will return the row number of the 1 that precedes the 0
=LOOKUP(2,1/((myRng=1)*(OFFSET(myRng,1,0)=0)),ROW(myRng))
You did not write what you want to happen if there are multiple triggers. The above will return the row number of the last trigger.
myRng cannot refer to the entire column, and could be replaced by, for example, A1:A100. If you do that, you might as well replace the OFFSET(myRng,1,0) with A2:A101 to make the formula non-volatile
Explanation:
(myRng=1)*(OFFSET(myRng,1,0)=0)
This multiplies each cell in myRng by the next cell. If the first = 1, and the second = 0, then the factors resolve to TRUE * TRUE and returns a 1. So the above will return an array looking like:
{0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0}
Dividing that array into 1 returns an array of DIV/0 errors or a 1.
The LOOKUP formula will then return the position of the last 1 and, using an array of row numbers for result_vector, will match it appropriately.
I need to compare two sets of two columns and find the count of number of IDs that match a certain criteria.
A B C D E
ID: ListNum: RefNum: List2Num: Ref2Num:
1 10 5 12 6
2 3 7 10 2
3 12 8 1 5
4 2 15 13 4
5 4 11 2 8
6 6 9 1 3
Let's say that the cell containing ID = "1" is A2 and it goes down to A7
I have to count the number of IDs that have a ListNum that is higher than the RefNum AND also have a List2Num that is higher than Ref2Num. Both criteria must be satisfied in order to count the ID.
I used the following formula: =COUNT(IF(B2:B7 > C2:C7) & (D2:D7 > E2:E7))
I get a value, but it's not the right count (it's taking the total for both conditions rather than only counting it once). The final answer should be 1. Any help would be appreciated, thank you!
One reason why yours didn't work: In your formula you use & to mean AND, but & actually concatenate strings.
Option 1: Array Formula
IF and AND don't work on arrays so a normal formula containing them won't work. So use an array formula instead:
You need to enter this as an array formula (you need to press control-shift-enter instead of enter when you put the formula in):
=SUM((B2:B7 > C2:C7)*(D2:D7 > E2:E7))
When it is in the cell it will display in braces to show it is an array formula. Like so:
{=SUM((B2:B7 > C2:C7)*(D2:D7 > E2:E7))}
In this formula the X>Y will return 1 or 0 for true or false. So multiplication is the same as AND and addition is the same as OR. Then (B2:B7 > C2:C7)*(D2:D7 > E2:E7) means B2:B7 > C2:C7 AND D2:D7 > E2:E7 and it returns an array of 1 and 0 which are then summed up to get the count.
Option 2: SUMPRODUCT
There is a normal function whose sole purpose is to multiply arrays together and then add them up the same way as the array formula does: SUMPRODUCT
The problem with SUMPRODUCT is that the arrays must be numbers and not logical true and false values so any of these works:
=SUMPRODUCT(--(B2:B7 > C2:C7),--(D2:D7 > E2:E7))
=SUMPRODUCT((B2:B7 > C2:C7)*1,(D2:D7 > E2:E7)*1)
=SUMPRODUCT((B2:B7 > C2:C7)+0,(D2:D7 > E2:E7)+0)
And this does not:
=SUMPRODUCT((B2:B7 > C2:C7),(D2:D7 > E2:E7))
But SUMPRODUCT is a normal function so you don't need to enter it with control-shift-enter.
Try entering this formula into cell F1:
=IF(AND(B1 > C1, D1 > E1), 1, 0)
Then just take the sum of the F column for however many rows you really have, and you should be left with the answer (which is 1 for the sample data you gave above).
If you put a simple AND formula next to your table, you can autofill that all the way down. Next, you could count the number of True values in that column (see pic). You could combine into an IF statement as Tim suggests.
The two formulas would be
"=AND(B2>C2,D2>E2)"
"=COUNTIF(G2:G7,TRUE)"
Link to picture of possible solution
I have a table in Excel which looks like this:
A B C
Row 1: 2100-2200 2200-2300 2300-2400
I'm using a VLOOKUP formula. I want this formula to find a number e.g. 2152 in the table above.
Cell A1 is supposed to contain numbers from 2100 to 2200.
Is this possible to do in Excel?
I dont know exactly what you want to return, this array formula will return the correct interval in A1:C1:
=INDEX($A$1:$C$1;MATCH(1;(E1>=VALUE(LEFT($A$1:$C$1;4)))*(E1<=VALUE(RIGHT($A$1:$C$1;4)));0))
Numeric value your looking for in E1
Dont forget to Ctrl Shift Enter to enter the formula...
Instead of providing the ranges, you need to provide only the lower bound. I.e. try this data:
A B C
Row 1: 2100 2200 2300
Because it is a horizontal setup, you need to use HLOOKUP (VLOOKUP will check the cells in the first column of a table, HLOOKUP the cells in the first row) - and you need to leave the fourth parameter of HLOOKUP/VLOOKUP blank (or set it to TRUE which is the same as leaving it blank). E.g. if you number 2152is in cell A2, use this formula:
=HLOOKUP(A2,$A$1:$C$1,1)
and you'll get 2100.
If you want to have the full range returned, you should use the MATCH function instead:
=INDEX($A$1:$C$1,MATCH(A2,$A$1:$C$1))&"-"&INDEX($A$1:$C$1,MATCH(A2,$A$1:$C$1)+1)
This will return 2100-2200
use lower range of your numbers
A B C D
Lower range 2100 2200 2300 2400
Ranking 1 2 3 4
You want to find a number or ranking corresponding to say 2350
Formula: = HLOOKUP(2350,range (range of your values),2,TRUE)
your range includes 2100 -2400 plus 1-4.
the value 2 in the formula indicates the row that you want result returned from - in this case you want ranking - where 2350 will return a 4; change this number to 1 to return exact value.
sample formula:
= HLOOKUP(O65,J74:N75,2,TRUE)
As OP wants to apply HLookUp to numeric range strings ("2100-2200", "2200-2300", etc.), I suggest the following steps:
reconstruct the range contents to their starting values (2100,2200,2300) isolated via Find searching till the - delimiter) by VALUE(LEFT(A1:C1,FIND("-",A1:C1)-1))
define a named search cell MySrch (example value of 2151 due to OP) and apply HLookUp on the above values to get the lower boundary (here: 2100),
Match the found lower boundary (e.g. 2100) plus character "-" and a * wild card to find the ordinal column position (here: 1st column),
return the found range text (e.g. 2100-2200) via Index(A1:C1,1,{column number}) referring to row 1 and the column position as result:
=INDEX(A1:C1,1,MATCH(HLOOKUP(MySrch,VALUE(LEFT(A1:C1,FIND("-",A1:C1)-1)),1)&"-*",A1:C1,0))
Note that it would be necessary to exclude search values outside the given range boundaries either by formula extension (e.g. If(MySrch>...,"?",{above formula}) or to add a last range defining a maximum limit.
if the number you search for is in E1 (aka e1 = 2152) then use 1 of 3:
the easiest and probably the best:
1) =HLOOKUP(E1 & "-" & E1,A1:C1,1,true)
or
2) =index(a1:c1,1, max(ARRAYFORMULA( if($E$1>VALUE(left(A1:C1,4)),column(A1:C1),0) )) )
or
3) =index(A1:c1,1, min(ARRAYFORMULA( if(VALUE(right(A1:C1,4))>=$E$1,column(A1:C1),99) )) )
this the range you want
to get the column remove the index(a1:c1,1, .... ) leaving the .... in 2) and 3) or use the fo;;owin gin 1)
=HLOOKUP(E1 & "-" & E1,{A1:C1 ; arrayformula(column(A1:C1))},2,true)
glad to help