I have the formula:
=IF(C2=$C$1:C2,1,0)
which returns the value 1 (I believe this is correct as C2 will find a match with C2). My problem is that if I turn this into an array formula
{=IF(C2=$C$1:C2,1,0)}
this returns a value of 0, however I am not sure why.
Could someone provide an explanation on the different results from each formula?
In the non-array version, the fact that you are passing an array of cells to the IF function is redundant, since, without array-coercion, the array resolves to just the first cell within that array, i.e. C1, so effectively the (non-array) construction:
=IF(C2=$C$1:C2,1,0)
is identical to simply:
=IF(C2=$C$1,1,0)
In the array version, a 1 will only be returned if the values in both C1 and C2 are equal to the value in C1 (though of course this is a little redundant in itself, since the value in C1 will always be equal to itself!).
What exactly are you trying to do with this odd-looking construction?
Regards
Related
I have the File as following format
Name Number Position
A 1
B 2
C 3
D 4
Now on position A3 , I applied =IF(B2=1,"Goal Keeper",OR(IF(B2=2,"Defender",OR(IF(B2=3,"MidField","Striker"))))) But it giving me an error #value!
Looked up at google, and my formula is correct.
What i basically want it
1- Goalkeeper 2-Defender 3-Midfield 4-Striker
Yes the other way is to to just filter the number and copy paste the text
But I want to do it using formula and want to know where did I go wrong.
Your immediate problem lies with the expression (for example):
OR(IF(B2=3,"MidField","Striker"))
| \__/ \________/ \_______/ |
| bool string string |
\____________________________/
string
The OR function expects a series of boolean values (true or false) and you're giving it a string value from the inner IF.
You don't actually need the or bits in this specific case, the if is a full if-else. So you can just use:
=IF(B1=1,"Goal Keeper",IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")))
This means that B1=1 will result in "Goal Keeper", otherwise it will evaluate IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")).
Then that means that, if B2=2, it will result in "Defender", otherwise it will evaluate IF(B2=3,"MidField","Striker").
Finally, that means the B2=3 will result in "MidField", anything else will give "Striker".
The only situation I can envisage when OR would come in handy here would be when two different numbers were to generate the same string. Let's say both 1 and 4 should give "Goalie", you could use:
=IF(OR(B1=1,B1=4),"Goalie",IF(B2=2,"Defender","MidField"))
Keep in mind that a more general solution would be better implemented with the Excel lookup functions, ones that would search a table (on the spreadsheet somewhere) which mapped the integers to strings. Then, if the mapping needed to change, you would just update the table rather than going back and changing the formula in every single row.
If you are actually tasked with solving the problem by using the IF and OR function within the same equation, this is the only way I can see how:
=IF(OR(B1=1, B1 = 2, B1 = 3, B1 = 4),IF(B1 = 1, "Goal Keeper", IF(B1 = 2,"Defender",IF(B1 = 3,"MidField","Striker")))
If B1 does not equal 1-4, the OR function will return FALSE and completely bypass all of the nested IF statements.
While using the isnan(x) operator, I notice that the output is an array with 0s and 1s corresponding whether the element is NaN or not.
The logical way to filter out NaN elements would be x(find(~isnan(x))), as find() returns the indices. As a suprise to me, x(~isnan(x)) also gives the same result.
On checking, ~isnan(x) is just an array of 1s and 0s, and for the simple case of x = rand(10,1), I get all(~isnan(x) == ones(10, 1)) as true. But when I run x(ones(10, 1)), I get an array with just the first element of x repeated 10 times, as expected.
What am I missing here?
MATLAB uses multiple type of indices.
isnan returns logical indices. That is, a matrix or vector of size x where it is 1 if that element is nan. The output is logical "binary" variable
find looks for any element that is not 0 and gives you its index. The output are integers.
As such, both outputs can be used as indices so they will the same result. That being said, if you don't need the actual indices (which you don't in your example above), don't use it. find is slow and redundant in the case above.
Now if you create the arrays of 1s like you did above, it treats it as an index (like find) so it returns the value of the first element 10 times. The reason is that the functions ones does not return a logical variable but actual numbers (real). If you substitute ones with true or convert the results into binary first, it will be treat it as logical indices.
I have no clue why summing over the array formula doesn't return correct results. The formula is:
=SUM(INDEX($C$4:$C$12,TRANSPOSE(OFFSET(K17,0,0,1,COUNT(K17:S17)))))
What I want to do is select multiple values from $C$4:$C$12 based on values in K17:S17 and then sum it. In row K17:S17 there might 1 to 9 positive integers (from 1 to 9), that determine which row to select from C4:C12.
When I use just INDEX($C$4:$C$12,TRANSPOSE(OFFSET(K17,0,0,1,COUNT(K17:S17)))) as an array function it returns the values I want to be sumed properly. but adding sum in frot returns just the first value from this set.
In order to pass an array as INDEX's row_num or col_num parameter, a little coercion is required:
https://excelxor.com/2014/09/05/index-returning-an-array-of-values/
Also, it's better to avoid volatile OFFSET constructions if possible.
=SUM(INDEX($C$4:$C$12,N(IF({1},K17:INDEX(K17:S17,MATCH(9.9E+307,K17:S17))))))
which, incidentally, does not require CSE.
Edit: if the maximum value in the range K17:S17 is 9, we can replace 9.9E+307 with 10:
=SUM(INDEX($C$4:$C$12,N(IF({1},K17:INDEX(K17:S17,MATCH(10,K17:S17))))))
Regards
I am currently using this array formula..
{=LARGE(IF(('Data Input'!$L$3:$L$15000=$B10)*('Data Input'!$H$3:$H$15000>$C10),'Data Input'!$O$3:$O$15000,0),1)}
Where B10 is a text ID, like 658A and L:L is the column with the IDs.
C10 is a date, with H:H being the column with dates.
O:O being the column with the # value that I am retrieving.
This formula works fine with my purposes when used with ctrl,shift,enter
The problem arises when I try to use...
{=IF('Data Input'!$L$3:$L$15000=$B10,1,0)}
It always returns a FALSE result, even though it works correctly in the first formula.
What is different about the second formula that changes the results?
This is very strange to me.
Thanks for any help.
the IF is only comaring the first value of the array that is returned, so only if the first comparison is true, will it return a true value.
Example to illustrate:
formula
Formula:
{=IF(A1:A3=B2,1,0)} will; return 0, unless cell A1 is changed to true. To change the result to have it return true if any of the values are true, you have to resort to a little trickery...
First, use -- to change the True/False values to 1/0, then use SUM to add them together. as IF treats any non-zero result as true, this will result in 1 being returned when any comparison is true.
Working through our example with the new formula {=IF(SUM(--(A1:A3=B2)),1,0)} (still an array formula) we get the following steps in evaluation:
=IF(SUM(--(A1:A3=B2)),1,0)
=IF(SUM(--(A1:A3=2)),1,0)
=IF(SUM(--({1,2,2}=2)),1,0)
=IF(SUM(--({False,True,True})),1,0)
=IF(SUM(0,1,1),1,0)
=IF(2,1,0)
=1
Your second formula is, itself, returning an array. You are only viewing the top left element in that return array - which happens to be FALSE.
Your first formula returns a scalar value; that is the difference.
If you want to sum the '1' values then your second formula could be amended to
{=SUM(IF('Data Input'!$L$3:$L$15000=$B10,1,0))}
which is also a scalar return.
Say I have a vector, for example, x <- 1:10, then x[0] returns a zero-length vector of the same class as x, here integer(0).
I was wondering if there is a reason behind that choice, as opposed to throwing an error, or returning NA as x[11] would? Also, if you can think of a situation where having x[0] return integer(0) is useful, thank you for including it in your answer.
As seen in ?"["
NA and zero values are allowed: rows of an index matrix containing a
zero are ignored, whereas rows containing an NA produce an NA in the
result.
So an index of 0 just gets ignored. We can see this in the following
x <- 1:10
x[c(1, 3, 0, 5, 0)]
#[1] 1 3 5
So if the only index we give it is 0 then the appropriate response is to return an empty vector.
My crack at it as I am not a programmer and certainly do not contribute to R source. I think it may be because you need some sort of place holder to state that something occurred here but nothing was returned. This becomes more apparent with things like tables and split. For instance when you make a table of values and say there are zero of that cell you need to hold that that cell made from a string in a vector has no values. it would not be a appropriate to have x[0]==0 as it's not the numeric value of zero but the absence of any value.
So in the following splits we need a place holder and integer(0) holds the place of no values returned which is not the same as 0. Notice for the second one it returns numeric(0) which is still a place holder stating it was numeric place holder.
with(mtcars, split(as.integer(gear), list(cyl, am, carb)))
with(mtcars, split(gear, list(cyl, am, carb)))
So in a way my x[FALSE] retort is true in that it holds the place of the non existent zero spot in the vector.
All right this balonga I just spewed is true until someone disputes it and tears it down.
PS page 19 of this guide (LINK) state that integer() and integer(0) are empty integer.
Related SO post: How to catch integer(0)?
Since the array indices are 1-based, index 0 has no meaning. The value is ignored as a vector index.