Google Sheets: Average of every other column - arrays

I’ve looked at similar questions and I think I’m close to a working solution, but it’s giving me the wrong answer. I have a spreadsheet in Google Sheets with data in all columns, but every other cell contains a dollar value and I need only the average of those cells. They start (in this version) on cell G3 and continue through most of row 3, then I intend to copy the formula to other rows with the same cells in those rows needing to be averaged as well, so if it’ll adjust as I copy that’ll be best. Here’s what I’ve worked up so far:
=AVERAGEIF(ArrayFormula(mod(column(G3:3),2)),”>0”)
It’s returning 1 as the result, when it should be about 1500. If I change the 2 to another number, the result increases with it, so I think something in mod or column is being done wrong, but I don’t have enough practice to know where I messed up.

avg of every 2nd column it's done like:
=AVERAGE(FILTER(G3:3, MOD(COLUMN(G3:3)-1, 2)=0))

TIL about the FILTER function. Thanks guys.
There is a way with ArrayFormula. I think you almost got it. I would prefer to add one more argument for AVERAGEIF to specify the range to average. I don't know if it defaults to the range in the condition.
And I would do the modulo on the difference between a column and the first column. I guess for your question it isn't needed as all column numbers are either odd or even. But using the difference is a general purpose way to apply the concept to say every nth column.
The modulo 2 of any column number with be 0 or 1. So instead of using an inequality just use 0 or 1. From your formula it looks like your dollar values must be in odd columns so the result of the modulo should be 1. But I think if you are starting at G3 then taking the column difference before applying Mod 2 changes the desired result to 0. But of course to switch to the other column change the 0 to a 1.
=AVERAGEIF(ArrayFormula(mod((COLUMN(G3:3)-COLUMN(G3)),2)),0,G3:3)

Related

Extract Data From Table Based on Multiple Criteria within ranges

I have a problem that I would like someone to help me with.
I need to cross data from a table, the table is the following below:
Literally I want to put in the "Yellow" line the amount I want, it can be any one from 0 to 3000. If in "Yellow" put for example 190, which is up to 200, then it will select column F. If you put 1000, then will already select column H.
Then I need to cross data with the lines, which will be up to x m2. That is, if in the line where it says "Green" select for example 0.3. Then it will select line 15. The Result of the 2 questions would be 1000 in this example.
However, I've already made a few attempts, and there I arrived at a formula killer:
=IFS(AND($E$20<=$F$14;$E$21<=$E$15);$F$15;AND($E$20<=$F$14;$E$21<=$E$16);$F$16;AND($E$20<=$F$14;$E$21<=$E$17);$F$17;AND($E$20<=$F$14;$E$21<=$E$18);$F$18;AND($E$20<=$G$14;$E$21<=$E$15);$G$15)
And this formula continues until the end. It's effective, it does its job, but in addition to being huge, it also makes it difficult to edit one day. I would like to try to improve it.
Any idea?
I apologize to everyone who was confused by my earlier attempt to explain my problem. Thank you all.
Per my understanding you are looking for two match criteria. For yellow criteria you look for exact match and for green criteria, the exact match or the next upper value.
You can use INDEX/XMATCH for that as follow using LET function in cell J3:
=LET(rng, B2:G5, upper, 1*TEXTAFTER(TEXTBEFORE(A2:A5, " m2"), " ", -1),
INDEX(rng, XMATCH(J2, upper, 1), XMATCH(J1, B1:G1))
)
or without LET function:
=INDEX(B2:G5, XMATCH(J2, 1*TEXTAFTER(TEXTBEFORE(A2:A5, " m2"), " ", -1), 1),
XMATCH(J1, B1:G1))
Note: The above approach doesn't require a helper column with the upper values, if such information is provided like in the updated version of the question (column E), then use the corresponding range instead.
Here is the output:
It assumes there is a space between m2 and the number in the green column. You need to standardize it in your input. For example the last green row doesn't have a space. If that is not the case you need to cleanup it first, via SUBSTITUTE function for example or manually it seems to be a typo.
The name upper contains the number associated to m2 in the green column using TEXTBEFORE and TEXTAFTER. The first XMATCH uses the third input argument (1) to ensure if the value doesn't exist, then it finds the next upper value. The second XMATCH look for an exact match for the yellow column.
This is a well known use case: Two dimensional lookup or two way lookup. For example you can check: INDEX XMATCH XMATCH to perform 2-dimentional lookup and just to adapt it to your specific case. You can also use XLOOKUP function for similar situations.
I'm trying to do it the way you showed me. However, I don't use excel and therefore I don't have this "LET" formula.
I had to improvise.
Followed this way:
I made a new column with the intended values.
All these values would be approximate, for example, if I put 150 in quantity and say that they are 5m2, it would give me the result of 1400. This is because it is below 200 units and below 5m2. Another example, if you put 499 units and put 13m2, then the result would be 360,
Currently, with this formula, I have already achieved approximations. However, the values are not matching up and when I pass 1500 units then it gives me this error: The value of Parameter 2 of the INDEX function, 5, is out of range.
Have a good year David.

Can Excel Index-Match or something like it match 1 row but return another?

I have a chart that shows the salaries for various medical specialties by percentile (each row is a specialty and each column is a percentile).
I want to be able to take a separate chart of physicians and their salaries, and automatically fill in what percentile each of their pay is.
https://i.imgur.com/NCtHHAB.jpg
If the physicians were all in one specialty, then I could just use Index-Match like so:
=INDEX('[Percentiles Chart]'!$B$3:$F$4, 1, MATCH(K3,'[Percentile File]'!$B$4:$F$4,1))
This formula works because it's choosing the column based on just the salaries in that one row, and always returning the top row. If I wanted it to choose between different rows, how could I do that without writing an "If" formula for every single row?
In other words, I want excel to look down column A in the example picture to pick the right specialty, then compare the salaries across the row and return what's in row 2.
Thank you!
As you rightly mentioned, there is no easy way to accomplish what you are looking for since the combination of Index/Offset/Match functions will return the data from the row that is matched and not some other row. Here is a formula that I have tried and it works exactly like you want. It is slightly hacky and uses SUMPRODUCT but gets the job done.
In your spreadsheet, if you enter the below formula, you would see that it gets the correct percentile value.
=OFFSET($B$2,0,SUMPRODUCT(($A$3:$A$6=J3)*($B$3:$F$6<K3)),1,1)
Here is how it works. The first part Sumproduct basically matches the name of specialty in range A3 to A6 and returns true for a match. The second part in sumproduct checks how many values in the range B3 to F6 are less than the given value (for example K3). When these two results are multiplied, it gives the number of values less than given value in the row of matching specialty which is equivalent to the offset of the column in the range. So, the OFFSET function simply navigates to that column and returns the value of the percentile. The below screenshot should help you understand it better.
If my explanation confused you :), you may want to play around with this formula to see how exactly it works.
Note the last column that says 100 in the percentiles table. That is simply to show correct value in case salary is greater than 90 percentile value.

Excel, counting positive numbers such that next column is top 10

I am looking to count/sum positive numbers in a column given that we are taking only top 10 in next column. For e.g.
I am using the formula: =SUM(LARGE(IF($E$3:$E$58>0,$F$3:$F$58),ROW(A1:A10)))
But it is summing the top 10 right F column such that E column is positive, which is the other way round. Any help is appreciated.
It doesn't sound as if you need anything more elaborate than a COUNTIFS function and a SUMIFS function. The LARGE function can provide a criteria to govern what is included in the count or sum. You've provided no row numbers so I will just use full column references.
     
The formulas are in the image much as your sample data was. As you can see, I used a greater than zero to determine what is a positive number. These are not array formulas. I was a little confused why you were asking for a count as your description seemed to refer to the Top 10. Maybe you can transcribe this for your own purposes.

Optimization of array function that calculates products

I have the following array formula that calculates the returns on a particular stock in a particular year:
=IF(AND(NOT(E2=E3),H2=H3),PRODUCT(IF($E$2:E2=E1,$O$2:O2,""))-1,"")
But since I have 500,000 row entries as soon as I hit row 50,000 I get an error from Excel stating that my machine does not have enough resources to compute the values.
How shall I optimize the function so that it actually works?
E column refers to a counter to check the years and ticker values of stocks. If year is different from the previous value the function will output 1. It will also output 1 when the name of stock has changed. So for example you may have values for year 1993 and the next value is 1993 too but the name of stock is different, so clearly the return should be calculated anew, and I use 1 as an indication for that.
Then I have another column that runs a cumulative sum of those 1s. When a new 1 in that previous column is encountered I add 1 to the running total and keep printing same number until I observe a new one. This makes possible use of the array function, if the column that contains running total values (E column) has a next value that is different from previous I use my twist on SUMIF but with PRODUCT IF. This will return the product of all the corresponding running total E column values.
The source of the inefficiency, I believe, is in the steady increase with row number of the number of cells that must be examined in order to evaluate each successive array formula. In row 50,000, for example, your formula must examine cells in all the rows above it.
I'm a big fan of array formulas, so it pains me to say this, but I wouldn't do it this way. Instead, use additional columns to compute, in each row, the pieces of your formula that are needed to return the desired result. By taking that approach, you're exploiting Excel's very efficient recalculation engine to compute only what's needed.
As for the final product, compute that from a cumulative running product in an auxiliary column, and that resets to the value now in column O when column P in the row above contains a number. This approach is much more "local" and avoids formulas that depend on large numbers of cells.
I realize that text is not the best language for describing this, and my poor writing skills might be adding to the challenge, so please let me know if more detail is needed.
Interesting problem, thanks.
Could I suggest a really quick and [very] dirty vba? Something like the below. Obviously, have a backup of your file before running this. This assumes you want to start calculating from row 13.
Sub calculateP()
'start on row 13, column P:
Cells(13, 16).Select
'loop through every row as long as column A is populated:
Do
If ActiveCell(1, -14).Value = "" Then Exit Do 'column A not populated so exit loop
'enter formula:
Selection.FormulaR1C1 = _
"=IF(AND(NOT(RC[-11]=R[1]C[-11]),RC[-8]=R[1]C[-8]),PRODUCT(IF(R[-11]C5:RC[-11]=R[-1]C[-11],R2C15:RC[-1],""""))-1,"""")"
'convert cell value to value only (remove formula):
ActiveCell.Value = ActiveCell.Value
'select next row:
ActiveCell(2, 1).Select
Loop
End Sub
Sorry, this is definitely not a great answer for you... in fact, even this method could be achieved more elegantly using range... but, the quick and dirty approach may help you in the interim ??

Sumproduct formula returns a #VALUE! error when the last array refers to a column with formulas in every row. MS Excel 2010

I am trying to find an easy way to calculate commissions off of sales on multiple sheets within a workbook. Each month, I need to find the total net profit for only items sold within the specified month.
The formula I am currently using is:
=SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$M$3:M24)
Column P shows the Sold Date,
Column M includes a formula in each row to calculate the net profit, and
cell G4 is where I would enter the month & year I am currently working with.
I have come to the conclusion that it only gives me the #VALUE! error because of the formula in each row of Column M (example: =IF(OR(F15=0,G15=0)," ",(F15-L15)) ).
When I reference a different column (in place of Column M) that does not contain formulas it works perfectly (example: =SUMPRODUCT((TEXT('Sheet Name'!$P$3:P24,"MY")=TEXT($G$4,"MY"))*'Sheet Name'!$G$3:G24) ). Also, changing the astrisk to a comma causes the formula to calculate incorrectly and add the (--(TEXT double negative does not fix the problem.
How to I get this array to calculate without removing the formulas from Column M?
Thanks for your attention.
I presume it is giving you a #VALUE error because your formula results in text (a space) and it errors when trying to multiply a space by a number (aka True or False). I think you would be better served changing your M column formula to =IF(OR(F15=0,G15=0),0,(F15-L15)). Do you have a specific reason to not make it evaluate to 0? Also is there a reason you are converting to text to do your month/year check?
Try something like this: =SUMPRODUCT(--(MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4)),--(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4)),'Sheet Name'!$M$3:M24). Of course this is dependent on entering the dates as actual dates. The -- is used to change a logical/boolean (true/false) into a 1 or 0. It won't do anything useful to text. For example, it should also work as =SUMPRODUCT((MONTH('Sheet Name'!$P$3:P24)=MONTH($G$4))*(YEAR('Sheet Name'!$P$3:P24)=YEAR($G$4))*'Sheet Name'!$M$3:M24) since the multiplication converts the truthy statements to numbers. The trick is to make sure when everything else evaluates, you have =sumproduct(numbers,numbers,numbers). Your instance is one array of =sumproduct(numbers/text).

Resources