I'm trying to create a formula that takes C2-B2 and uses the result to determine which cells to add together. So if the result is 2 it takes AA2 and AB2, adds them together, and displays the result. In other words, it counts cells stemming from a point and adds them, with the amount counted determined by the result of two other cells.
This doesnt sound recursive the way you describe it.
Put this formula somewhere on the sheet and see if this is what you want:
=SUM($AA$2:INDEX($AA$2:$XFD$2, 1, SUM($B$2:$C$2)))
Related
I am new to Excel/Google Sheets. I have a difficulty of writing a formula to compare columns as a pair-wise since the formula would be
so big as the day goes.
For example, there're 2 main columns Foo and Bar. I want to find the total number of days that Foo
and Bar are equal so the current formula is =IF(A3 = G3, 1, 0)+IF(B3 = H3, 1, 0)+IF(C3 = I3, 1, 0)+...
But this is kind of tedious because there're ~40 days to compare with. Are there any other alternatives
to write a formula in efficient way? Either Google-App-Scripts or Excel Formula is appreciated.
Cheers!
Give a try on below google-sheet formula. Adjust ranges as you need.
=ArrayFormula(SUM(IF(A3:E3=G3:K3,1,0)))
Assuming that you're needing to get such a total for each row and not merely a single row, try this:
=ArrayFormula(IF(A3:A="",,MMULT(IF(A3:F=G3:L,1,0),SEQUENCE(COLUMNS(A:F),1,1,0))))
Of course you will need to adjust the three ranges to match your own FOO and BAR ranges.
This one formula will produce all results for all rows.
The MMULT function is tricky to explain to those as yet unfamiliar with it. But it's a powerful tool. I'll add a picture I created that may best explain what it does:
By making the second matrix a simple SEQUENCE of 1s as long as the other matrix is wide, we wind up multiplying everything by 1 before adding together. And since anything multiplied by 1 is itself, this combination serves only to do a row-by-row add.
Things to keep in mind with MMULT:
1.) Every cell in every matrix must be a number or it will produce an error.
2.) As in the above formula, there are ways to use either/or conditions to turn every cell in a matrix into a number.
I am trying to figure out how to reference just one area of a named formula and return it as an array. This is so I can then count the number of rows in the areas referenced and eventually sum them. I going to eventually integrate the results of this into a pretty complicated mess of other formulas that automatically join and rank multiple matrices. I am trying to do this using formulas, not VBA, as a portability requirement. Some folks are a bit weary about running other folks code...
For now, though, I've come up with a simple example. Let's pretend that in the name manager we have a formula named Letters that is defined as:
=A1:A4,C1:C6
The range A1:A4 contains the letters "A" through ."D" and the range C1:C6 contains the letters "E" through "J".
If I write a simple INDEX formula I can return the first or second area of Letters like so:
=INDEX(Letters,,,1)
=INDEX(Letters,,,2)
I know this works by doing an F9 in on the formula and it returns the expected array of letters ({"A";"B";"C";"D"} or {"E";"F";"G";"H";"I";"J"}) for the appropriate area. But doing it this way makes the assumption that there will always be two areas in Letters. I'd like to keep my formula dynamic in case I was to add another area. I can create another formula named Letters_Areas and make it equal to the following:
=ROW(INDEX(Sheet1!$A:$A,1):INDEX(Sheet1!$A:$A,AREAS(Letters)))
This will return an array with the value of {1;2} for the example (or more if there was more areas) and I can pass that to an IF to loop like so:
=IF(Letters_Areas,INDEX(Letters,,,Letters_Areas)
But that doesn't work. It always returns just the first area in Letters because Letters_Areas in the second argument of the IF always returns 1 as the value, not the first and then second value of the array. I guess my question in a formula is:
=IF(Letters_Areas,INDEX(Letters,,,What_Do_I_Put_Here))
Where What_Do_I_Put_Here counts up for each iteration of the IF like a For loop would in VBA. Essentially, I need to be able to get i in my For i = 1 to 2 in this case inside the IF.
I know that the failure is the Letters_Areas in the second argument of the IF because I can test it. At first glance you would just do it as such:
=IF(Letters_Areas,Letters_Areas)
This returns the expected {1,2}. However, this is misleading because you can find the true behavior by doing this:
=IF(Letters_Areas,INDEX(Letters_Areas,Letters_Areas))
And this always returns {1,1} which tells me that is the part that is failing.
The final version of the formula, minus the part I cannot figure out should look something like:
=IF(Letters_Areas,ROWS(INDEX(Letters,,,What_Do_I_Put_Here)))
And in our test example this would return {4;6}. Again, stuck using no VBA. Any ideas?
Could you use this formula to count areas, assuming that your areas always begin in row 1 as in your example: COLUMNS(A1:Z1)-(SUM(IF(ISBLANK(A1:Z1),1,0)))? Any non-blank cells within that range will be counted as an area and will give the correct count. I am not sure if this is what you are seeking according to your question.
I have a (large) array of data in Excel of which I need to compute the average value of certain values in one column, based on the values of another column. For example, here's a snippet of my data:
So specifically, I want to take the average of the F635 mean values corresponding with Row values of 1. To take it a step further, I want this to continue to Row values of 2, Row values of 3 etc.
I'm not familiar with how to run code in Excel but have attempted to solve this by using the following:
=IF($C = "1", AVERAGE($D:$D), "")
which (to my understanding) can be interpreted as "if the values (anywhere) in column C are equal to 1, then take the average of the corresponding values in column D."
Of course, as I try this I get a formula error from Excel.
Any guidance would be incredibly appreciated. Thanks in advance.
For more complicated cases, I would use an array-formula. This one is simple enough for the AVERAGEIF formula. For instance =AVERAGEIF(A1:A23;1;B1:B23)
Array-formula allows for more elaborate ifs. To replicate the above, you could do =SUM(IF($A$1:$A$23=1;$B$1:$B$23;0))/COUNT(IF($A$1:$A$23=1;$B$1:$B$23;0)).
Looks like more work but you can create extremely elaborate if-statements. Instead of hitting ENTER, do CTRL-ENTER when entering the formula. Use * between criteria to replicate AND or + for OR. Example: SUM(IF(($A$1:$A$23="apple")*($B$1:$B$23="green");$C$1:$C$23;0)) tallies values for green apples in c1:c23.
Your sample data includes three columns with potential ifs so my guess is that you're going to need array formulas at some point.
Excel already has a builtin function for exactly this use; AVERAGEIF().
=AVERAGEIF(C:C,1,D:D)
I'm working on data from a population of people with allergies. Each person has a unique ExceptionID, and each allergen has a unique AllergenID (451 in total).
I have a data table with 2 columns (ExceptionID and AllergenID), where each person's allergies are listed row by row. This means that the ExceptionID column has repeated values for people with multiple allergies, and the AllergenID column has repeated values for the different people who have that allergy.
I am trying to count how many times each pair of allergies is present in this population (e.g. Allergen#107 & Allergen#108, Allergen#107 & Allergen#109,etc). To keep it simple I've created a matrix of 451 rows X 451 columns, representing every pair (twice actually because A/B and B/A are equivalent).
I somehow need to use the row name (allergenID) to lookup the ExceptionID in my data table, and count the cases where that matches the ExceptionIDs from the column name (also AllergenID). I have no problem using Vlookup or Index/Match, but I'm struggling with the correct combination of a lookup and Sumproduct or Countif formula.
Any help is greatly appreciated!
Mike
PS I'm using Excel 2016 if that changes anything.
-=UPDATE=-
So the methods suggested by Dirk and MacroMarc both worked, though I couldn't apply the latter to my full data set (17,000+ rows) because it was taking a long time.
I've since decided to turn this into a VBA macro because we now want to see the counts of triplets instead of pairs.
With the 2 columns you start with, it is as good as impossible... You would need to check every ExceptionID to have 2 different specific AllergenID. Better use a helper-table with ExceptionID as rows and AllergenID as columns (or the opposite... whatever you like). The helper table needs a formula like:
=COUNTIFS($A:$A,$D2,$B:$B,E$1)
Which then can be auto-filled. (The ranges are from my example, you need to change them to your needs).
With this helper-matrix you can easily go for your bigger matrix like this:
=COUNTIFS(E:E,1,INDEX($E:$G,,MATCH($I2,$E$1:$G$1,0)),1)
Again, you can auto-fill with this formula, but you need to change it, so it fits your needs.
Because the columns have the same ID2 (would be your AllergenID), there is no need to lookup them because E:E changes automatically with the auto-fill.
Most important part of the formulas are the $ which should not be messed up, or you can not auto-fill it.
Picture of my self-made example (formulas are from the upper left cell in each table):
If you still have any questions, just ask :)
It can be done straight from your original set-up with array formulas:
Please note that array formulas MUST be entered with Ctrl-Shift-Enter, before copying across and down:
In the example pic, I have NAMED the data ranges $A$2:$A$21 as 'People' and $B$2:$B$21 as 'Allergens' to make it a nicer set-up. You can see in the formula bar how that looks as a formula. However you could use the standard references like this in your first matrix cell:
EDIT: silly me, N function is not needed to turn the booleans into 1's and 0's, since multiplying booleans will do the trick. Below formula works...
SUM(IF(MATCH($A$2:$A$21,$A$2:$A$21,0)=ROW($A$2:$A$21)-1, NOT(ISERROR(MATCH($A$2:$A$21&$E2,$A$2:$A$21&$B$2:$B$21,0)))*NOT(ISERROR(MATCH($A$2:$A$21&F$1, $A$2:$A$21&$B$2:$B$21,0))), 0))
Then copy from F2 across and down. It can be perhaps improved in technique with sumproduct or whatever, but it's just a rough example of the technique....
I would like to have part of an excel formula be dynamic, other than a cell reference.
For instance, suppose that in column A (cells A1:A99) I have a bunch of numbers, and I want to know how many of those numbers are greater than 50.
If I wanted this calculation to be static, I could simply use one of the following:
=COUNTIF($A$1:$A$99,">50")
=SUM(IF($A$1:$A$99>50,1,0))
=SUM(($A$1:$A$99>50)*1)
I mention all three because my actual formula is hairy and a bit of a mix of the second and the third. (After all, perhaps something will work with COUNTIF but not with the others.)
Now, I want to be able to type my condition in another cell (say C1). So if I type ">50" in C1, my calculation will be as above, but if I type "<100" I will count how many entries of column A are less than 100.
Is this possible? (I am using Excel 2003 on Windows XP.)
There may be something that I'm missing.
If you give
=COUNTIF($A$1:$A$99,C1)
in any cell, and then in cell C1 you type >50 or <100
don't you get what you want?
Use INDIRECT
=INDIRECT(COUNTIF($A$1:$A$99,">50"))
is same as
=COUNTIF($A$1:$A$99,">50")
But, as you identified, the former, you can generate within the excel cells! I do it all the time, for such things.
I usually solve this by adding another column carrying the result of a complex logical expression, like
=AND(OR(C3<D3;E3>=100);A3=VLOOKUP(B3;Sheet2!$A$2:$B$212;2;FALSE))
this formula is in all rows of -say- column F - note: no IF needed here!
then I calculate a complex conditional sum across column E using =SUMIF() like
=SUMIF(F2:F57;TRUE;E2:E57)
I know that some users say "I do not want to change my design. That's ok; my argument is that I have better control over the condition, I can work on the condition seperately from summing up or other functions that rely on that condition, and I can filter records for TRUE or FALSE to look at the subsets and have a rapid overview if the formula makes sense
hope that helps Good luck MikeD