I have a 2-D array: dates on a horizontal axis and identification numbers on a vertical axis.
I want the sums conditioned on a particular date and ID, and I want to know how to do this using SUMIFS.
For some reason, it seems like I cannot since the array is 2-D while the criteria ranges are 1-D. Can anyone give me any advice on other formulas I can use?
In other words, I would like to add the values that satisfy the ID and date I select; there is one or more data point that satisfies the conditions. This is why the SUMIF function is relevant.
With this data you will not be able to use a SUMIF forumula. Here's a formula you can use:
=SUM(IF($B$2:$B$6=C9,IF($F$1:$K$1=B9,$F$2:$K$6)))
Change the addresses where appropriate and be sure and enter it by pressing CTRL + SHIFT + ENTER. You can also use the below formula to avoid pressing CTRL + SHIFT + ENTER:
=SUMPRODUCT(($B$2:$B$6=C9)*($F$1:$K$1=B9)*$F$2:$K$6)
Assuming that you're looking for an intersection of an ID and a Date, you can use the following:
=INDIRECT(ADDRESS(MATCH([ID Number],A:A,0),MATCH([Date],1:1,0)))
INDIRECT allows you to type in an address as plain text and returns the value
ADDRESS turns the numbers for rows and columns into a regular address
MATCH finds where in a row or column a given value is located.
I just wanted to add that the array version of the 2D summation in the answer above
=SUM(IF($B$2:$B$6=C9,IF($F$1:$K$1=B9,$F$2:$K$6)))
will work better if your data table $F$2:$K$6 has blanks (or other non-numeric values) because it will sum only the values that match criteria specified by $B$2:$B$6=C9 $F$1:$K$1=B9 and ignore all others.
Generally, you probably will not have blanks or other non-numeric values in your data table but I just wanted to throw this out there in case it helps someone. It certainly helped me, and I had fun playing with both 2D summation examples above. :)
Related
I want to calculate the sumproduct as pictured in the table in the "Revenue" column. However, the dataset is fairly big, I'm limited to excel and the standard functions.
It should find all variables with the keyword "weightl" and "sell" in it and multiply and sum them accordingly per row. In Row 3 for example:
2*3+3*6+2*3 = 30
I thought of using a kind of a dictionary to alter the search terms and go through each column. But I have no clue on how to put it all together.
I used this
{=+isnumber(search("weightl";F2:N2))+isnumber(search("sell";F2:N2))}
to create the 1/0 table of the original one in the hope this could lead me somewhere
and
=SUM(IF(IFERROR(SEARCH("weight";G2:M2);0)>0;IF(G3:M8<>8888;G3:M8)))
to calculate the total sum of the weight values but this doesn't help much here
Can this even be realized with normal functions? if not, how could a solution in VBA look like?
If your "weight" and "sell" columns are always two columns apart, then you can use this array formula which looks for the "weight" column and then multiplies it by the column 2 cells to the right:
hdrs refers to the range $A$1:$I$1 which contains the headers. But it could refer to the entire row, or a much large portion of Row 1
=SUM(IFERROR(SEARCH("*weight*",hdrs)*A2:G2,0) * IFERROR(SEARCH("*weight*",hdrs)*C2:I2,0))
If there might be a variable number of columns between "weight" and "sell", then you can try this array formula which looks for the "weight" and "sell" columns separately:
=SUM(INDEX(A2:I2,1,N(IF(1,AGGREGATE(15,6,SEARCH("*weight*",hdrs)*COLUMN(hdrs),ROW(INDIRECT("1:"&COUNTIF(hdrs,"*weight*")))))))*INDEX(A2:I2,1,N(IF(1,AGGREGATE(15,6,SEARCH("*sell*",hdrs)*COLUMN(hdrs),ROW(INDIRECT("1:"&COUNTIF(hdrs,"*weight*"))))))))
Since this is an array formula, you need to "confirm" it by holding down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula as observed in the formula bar
Note I just noticed you want to match "weight1", so just make the obvious change in the above formulas.
Here is a formula that should do the matching in the way that you're thinking:
=SUM(A2:I2*ISNUMBER(FIND("weight",A1:I1))*IFERROR(INDEX(A2:I2,N(IF({1},MATCH("*sell"&RIGHT(A1:I1,LEN(A1:I1)-FIND("weightl",A1:I1)-6),A1:I1,0)))),0))
Must be entered as an array formula using CtrlShiftEnter
Note I'm finding the 'sell' header which matches the 'weightl' header, so weightl1_1_4 will match with sell1_1_4 etc., but I'm now wondering if this is necessary - maybe the weight just matches with the next sell, which would be easier.
What I'm attempting to do is count the number of blank cells across a dataset where the header of the row matches an array.
=countifs(D1:AZ,D2:AZ,D1:1,A2)
However, it appears that since the array sizes are different, it can't use it as a lookup.
Ideally, I'd be able to get an array formula to count the number of non-blank cells that correspond to each date in A2:A, like this:
Looking at the documentation for COUNTIFS, I don't see anything about it not being able to handle vertical and horizontal matching.
Also, I need to avoid using =query(), since there may be instances in D1:1 where a date is missing. I will be handling that with an iferror().
Any help/advice you all could provide would be greatly appreciated!
I have made an editable copy of the dataset here for reference.
Thanks
Try this. It is a matrix multiplication formula that sums up the nonblank cells for each column. It should work for you.
=arrayformula(mmult(transpose(if(D1:1="",0,if(isblank(D2:BG),0,1))),sign(ROW(D2:BG))))
I can explain it if you are interested.
EDIT: How about this? It adds a vlookup.
=arrayformula(iferror(vlookup(A2:A,{transpose(D1:1),mmult(transpose(if(D1:1="",0,if(isblank(D2:BF),0,1))),sign(ROW(D2:BF)))},2,false)))
This may be a way to do it, on B2:
=COUNTIFS(OFFSET($D$2:$D,,MATCH(A2,$D$1:$AZ$1,0)-1),">0")
Then you auto fill down, the idea is:
MATCH(A2,$D$1:$AZ$1,0) Will match each date on column A to the date on row 1 and return an index (from 1 to N).
OFFSET($D$2:$D,,N) Will take the range D2:D and offset N columns (In this case the output of MATCH).
Finally COUNTIFS will look for >0 values in the column which header matches the date on the left.
I hope it helps
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)
Looking to find the max value in a column based on two sets of criteria
So the logic would be: Find the minimum value in column M, where the value in column A matches column N, and the value in Column Y is less than 318.
I've tried using an array formula like this but it doesn't seem to be working/is to memory heavy to run:
=MIN(IF(AND(N:N=A2,Y:Y<=318),M:M))
is there a simpler way? or perhaps a UDF that could work?
Thank you for your help!
You can't use AND in these type of formulas because it only returns a single value rather than the required array.
Here are three possible working versions:
1.) Use * to simulate AND
=MIN(IF((N:N=A2)*(Y:Y<=318),M:M))
confirmed with CTRL+SHIFT+ENTER
2.) Use multiple nested IFs
=MIN(IF(N:N=A2,IF(Y:Y<=318,M:M)))
confirmed with CTRL+SHIFT+ENTER
3.) Use AGGREGATE function
=AGGREGATE(15,6,M:M/(N:N=A2)/(Y:Y<=318),1)
The advantages of this approach are that you don't need "array entry", and it can ignore any errors in the data
Either way it's best to reduce the ranges sizes if you can because it might be slow with whole columns
Give this a try and adjust ranges to suit. Try not to use whole column references:
=SMALL(INDEX(($N$2:$N$101=A2)*($Y$2:$Y$101<=318)*$M$2:$M$101,),1+ROWS($M$2:$M$101)-COUNTIFS($N$2:$N$101,A2,$Y$2:$Y$101,"<=318"))
If you are using the whole column to pick up new data as it is added, consider using Dynamic Named Ranges instead
When things get this complex, I'll usually break it down and setup smaller/simpler formulas in seperate columns.
In other words, you have data in columns A through Y ?
So let's create a formula in column AA:
1) identify when value in Col A matches col N, and value in col Y < 318
=and(A1=N1,Y1<318)
2) copy AA1 to all the rows of your data.
3) now we have a condition to work off .. since there is a SUMIF and COUNTIF, but no MINIF .. we'll have to build that ourselves. first the IF:
in column AB1:
=if(AA1,M1,"")
copy that down to all your data.
finally, do your min:
=MIN(AB:AB)
Should give you your answer.
You could probably splice the first two together, but again, building a complex formula like this, build it simply, first, ;)
I have two excel sheets where I need to match three values to return a fourth. The similar columns are month, agent, and subdomain. The fourth column is called difference.
Concatenate would work, as per #MakeCents suggestion, but if you don't want a helper column, SUMPRODUCT would work.
example:
=SUMPRODUCT(--(A2:A12="d"),--(B2:B12="S"),--(C2:C12="Apr"),D2:D12)
would search range A2:A12 for "d", B2:B12 for "S" and C2:C12 for "Apr", and return the value fom D2:D12 that corresponds to where all 3 are true. If multiple lines match, it will add the value in D2:D12 for all matching rows.
The -- is used to change the True/False results into 0 and 1 for use in multiplication
Limitations of SUMPRODUCT
Recommended to specify the range explicitly; it will be slower with just
column references
(A1:A4000 is ok, A:A is not)
It will return an error if any of the values are errors
It will return numeric results only - text is evaluated as Zero
Although I believe #MakeCents comment / suggestion on how to do this is the way I would go since it is the simplest, you could accomplish this a different way (MUCH more processor-intensive, though) using the Index() and Match() functions and Array formulas.
For example, suppose your 3 columns of data you're looking to match against are columns A-C and you're looking to return the matching value from column D in Sheet1
Now, the 3 values you're looking to have matched are in cells A1, B1 & C1 of Sheet2, you could use the following formula:
=INDEX(Sheet1!D:D,MATCH(1,(Sheet1!A:A=A1)*(Sheet1!B:B=B1)*(Sheet1!C:C=C1),0))
And ENTER IT AS AN ARRAY FORMULA by pressing Ctrl + Shift + Enter
Hope this helps!
You are looking for a Lookup with multiple criteria.
One of the most robust options is
=INDEX(D:D,SUMPRODUCT(--(A:A="d"),--(B:B="S"),--(C:C="Apr"),ROW(D:D)),0)
It does not need to be entered as an array formula.
Taken from [1] (blogs.office.com).
See also this very complete answer, which summarizes this and other options for performing a lookup with multiple criteria.
PS1: Note that I used references to full columns, as per this.
PS2: This can be considered an enhancement to the solution by Sean for the case when the output column does not contain numbers.
References
[1] This post is written by JP Pinto, the winner of the Great White Shark Award given for the best article written about VLOOKUP during VLOOKUP Week.
Try this
=IF(A4=Data!$A$4:$A$741,IF(B4=Data!$B$4:$B$741,"Hai"))