Excel average rows to array formula - arrays

I want to take the average of rows which would result in a column (array). Example input:
3 4
4 4
4 6
With an array formula I want to create:
3.5
4
5

The average is the sum of numbers divided by the count of that numbers.
So first add them (A1:A3+B1:B3)
3+4 = 7
4+4 = 8
4+6 = 10
Then divide by the number of numbers(/2):
7/2 = 3.5
8/2 = 4
10/2 = 5
{=(A1:A3+B1:B3)/2}
edit after comment from op:
formula for addition without adding column manually from https://productforums.google.com/forum/#!topic/docs/Q9x44sclzfY
{=mmult(A1:B3,sign(transpose(column(A1:B3))))/Columns(A1:B3)}

This is one way to do that in Excel
=SUBTOTAL(1,OFFSET(A1:B3,ROW(A1:B3)-MIN(ROW(A1:B3)),0,1))
OFFSET supplies an "array of ranges", each range being a single row, and SUBTOTAL with 1 as first argument, averages each of those ranges. You can use this in another formula or function or entered in a range on the worksheet.
The advantage over Siphor's suggestion with MMULT is that this will still work even with blanks or text values in the range (those will be ignored)

If first column is A and the second is B, then enter this formuls in column C:
=AVERAGE(A1,B1)
and extend it to the last row
Also you can use a range if you have more than 2 columns (this function allows for some cells to be empty):
=AVERAGE(A1:F1)

Related

How to take the median of the following a 4D array (31x6x2x3)?

I am trying to get the median of each row of the same columns of the following 4D array:
df = randn(31,6,2,3)
What I basically have is 31 rows (i) of 6 variables (j) for two shocks (k), all this repeated 3 times (n). Now, focus on the first shock and get a 31x6x3 array:
eg1 = squeeze(df(:,:,1,:)) %31x6x3
What I want to get is the median of every row of the same column: e.g. the first row of the first column of the 3 repetitions, then the second row of the first column of the 3 repetitions, etc. Easier to see like this:
% median of every row of the first column in the 3 repetitions
median(eg1(1,1,:))
median(eg1(2,1,:))
median(eg1(3,1,:))
...
median(eg1(31,1,:))
% median of every row of the second column in the 3 repetitions
median(eg1(1,2,:))
median(eg1(2,2,:))
median(eg1(3,2,:))
...
median(eg1(31,2,:))
% basically the median of every row of the same column for every column
This shall be done for either shocks 1 and 2.
Can anyone help me with this?
What you want is the median of the last dimension. median accepts desired dimension as input.
out=median(eg1,3)
out will be a 31x6 matrix.
If you want that from all of the egx, you just want the median of the last dimension
out=median(df,4)

Countif the Result of Subtracting Two Arrays Exceeds a Certain Value in Excel

I am new to array formulae and am having trouble with the following scenario:
I have the following matrix:
F G H I J ... R S T U V
1 0 0 1 1
0 1 1 1 2 3 1 2
2 0 2 3 1 2 0 1 0 0
2 1 0 0 1 0 0 3 0 0
My goal is to count the number of rows within which the difference between the sum of columns F:J and the sum of columns R:V is greater than a threshold. Critically, only rows with full data should be included: row 1 (where there are only values for columns F1:J1) and row 2 (where there are only some values for columns F2:J2) should be ignored.
If the threshold = 2.5, then the solution is 1. That is, row 3 is the only row with complete data where the difference between the sum of F3:J3 (8) and the sum of R3:V3 (3) is greater than 2.5 (e.g., 5 > 2.5).
I have tried to put together the following formula, rather pathetically, based on the teachings of #Tom Sharpe and #QHarr:
=COUNT(IF(SUBTOTAL(9,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))-SUBTOTAL(9,OFFSET(R1,ROW(R1:R4)-ROW(R1),0,1,COLUMNS(R1:V1)))>2.5,IF(AND(SUBTOTAL(2,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))=COLUMNS(F1:J1),SUBTOTAL(2,OFFSET(R1,ROW(R1:R4)-ROW(R1),0,1,COLUMNS(R1:V1)))=COLUMNS(R1:V1)),SUBTOTAL(9,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))),IF(AND(SUBTOTAL(2,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))=COLUMNS(F1:J1),SUBTOTAL(2,OFFSET(R1,ROW(R1:R4)-ROW(R1),0,1,COLUMNS(R1:V1)))=COLUMNS(R1:V1)),SUBTOTAL(9,OFFSET(R1,ROW(R1:V1)-ROW(R1),0,1,COLUMNS(R1:V1))))))
But it seems to always produce a value of 1, even if I edit the matrix such that the difference between the sum of F4:J4 and R4:v4 also exceeds 2.5. Sadly I am struggling to understand why and would appreciate any guidance on the matter.
As an array formula in one cell without volatile functions:
=SUM((MMULT(--(LEN(F2:J5)*LEN(R2:V5)>0),--TRANSPOSE(COLUMN(F2:J2)>0))=5)*(MMULT(F2:J5-R2:V5,TRANSPOSE(--(COLUMN(F2:J2)>0)))>2.5))
should do the trick :D
Maybe, in say X1 (assuming you have labelled your columns):
=COUNTIF(Y:Y,TRUE)
In Y1 whatever your chosen cutoff (eg 2.5) and in Y2:
=((COUNTBLANK(F2:J2)+COUNTBLANK(R2:V2)=0)*SUM(F2:J2)-SUM(R2:V2))>Y$1
copied down to suit.
Try this:
=SUMPRODUCT((MMULT(F1:J4-R1:V4,--(ROW(INDIRECT("1:"&COLUMNS(F1:J4)))>0))>2.5)*(MMULT((LEN(F1:J4)>0)+(LEN(R1:V4)>0),--(ROW(INDIRECT("1:"&COLUMNS(F1:J4)))>0))=(COLUMNS(F1:J4)+COLUMNS(R1:V4))))
I think this will do it, replacing your AND's by multiplies (*):
=SUMPRODUCT(--((SUBTOTAL(9,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))-SUBTOTAL(9,OFFSET(R1,ROW(R1:R4)-ROW(R1),0,1,COLUMNS(R1:V1)))>2.5)*(SUBTOTAL(2,OFFSET(F1,ROW(F1:F4)-ROW(F1),0,1,COLUMNS(F1:J1)))=COLUMNS(F1:J1))*(SUBTOTAL(2,OFFSET(R1,ROW(R1:R4)-ROW(R1),0,1,COLUMNS(R1:V1)))=COLUMNS(R1:V1))>0))
It could be simplified a bit more but a bit short of time.
Just another option...
=IF(NOT(OR(IFERROR(MATCH(TRUE,ISBLANK(F1:J1),0),FALSE),IFERROR(MATCH(TRUE,ISBLANK(R1:V1),0),FALSE))), SUBTOTAL(9,F1:J1)-SUBTOTAL(9,R1:V1), "Missing Value(s)")
My approach was a little different from what you tried to adapt from #TomSharp in that I'm validating the cells have data (not blank) and then perform the calculation, othewise return an error message. This is still an array function call, so when you enter the formulas, press ctrl+shft+enter.
The condition part of the opening if() checks to see that each range's cells are not blank: if a match( true= isblank(cell))
means a cell is blank (bad), if no match ... ie no blank cells, Match will return an #NA "error" (good). False is good = Errors found ? No. ((ie no blank cells))
Then the threshold condition becomes:
=COUNTIF(X1:X4,">"&Threshold)' Note: no Array formula here
I gave the threshold (Cell W6) a named range for read ablity.

Using an Array to get the average of a selection of numbers

I have 12 different numbers on a row in an excel sheet (repeated few times on different row) and I would like to get the average of the 8 bigger numbers (4 numbers won't be used). I thought to use an array, but how to select the 8 bigger numbers in this array?
I would like to do it in VBA. Do you have any ideas/directions how to proceed, because I am not really sure how to start.
Example: 12,3,5,6,8,11,9,7,5,8,10,1 (Results=8.875), if I didn't make a mistake!
Thanks.
I know you asked for VBA, but here's a formula. If this works, you can quickly throw in VBA (use the macro recorder to see how if you're unsure).
If that's in row 1, you can use:
=AVERAGE(LARGE(A1:L1,{1,2,3,4,5,6,7,8}))
You should be able to change A1:l1 to be the range where your numbers are, i.e.
=AVERAGE(LARGE(A1:F2,{1,2,3,4,5,6,7,8}))
Edit: Per your comment, also no need for VBA. Just use conditional highlighting. Highlight your range of numbers, then go to Conditional Highlighting --> Top/Bottom Rules --> Top 10 Items. Then just change the 10 to 8, and choose a color/format. Then Apply!
(each row in the above is treated as it's own range).
Edt2: bah, my image has duplicate numbers which is why the top 8 rule is highlighting 9 numbers sometimes. If you request I'll try to edit and tweak
You can use a simple Excel function to compute the answer
=AVERAGE(LARGE(A1:L1, {1,2,3,4,5,6,7,8}))
It is a bit more complex in VBA, but here is a function that does the same computation (explicit typing per Mat's Mug):
Public Function AvgTop8(r As Range) As Double
Dim Sum As Double, j1 As Integer
For j1 = 1 To 12
If WorksheetFunction.Rank(r(1, j1), r) <= 8 Then
Sum = Sum + r(1, j1)
End If
Next j1
AvgTop8 = Sum / 8#
End Function
The Excel RANK function returns the rank of a number in a list of numbers, with the largest rank 1 and so on. So you can search through the 12 numbers for the 8 largest, sum them and divide by 8.
You don't need VBA for this. You can use:
=AVERAGE(LARGE(A1:L1,{1;2;3;4;5;6;7;8}))

how to create array of random normalize number?

i want to create a matrix that each row of the matrix have 7 real random number in [0,1] and the sum of number in each rows should be equal to 1.
this matrix have 100 rows and 7 columns. how can i do it?
at first ,i create an array with 1 row and 7 columns. then write the code as bellow. i try normal the number in the rows but sum of each row became more than 1.how can i fix it? thank for taking your time.
a = rand(1,7);
for i=1:7
a(i) = a(i)/sum(a);
end
sum(a)
For 100 by 7, you can use bsxfun:
a = rand(100,7);
a = bsxfun(#rdivide,a.',sum(a.')).';
Here the sum of each row = 1
The problem is that by using a for-loop, you're changing the sum of the vector every loop iteration. You should take advantage of MATLAB's ability to act on whole matrices at once:
a = rand(1,7);
a = a./sum(a);

Find maximum value in each row or column of an Excel array

In Excel I have a named range that contains an array, for example like the array below.
0 0 0 7
0 0 6 5
0 5 3 2
4 3 2 1
I'd like to find the maximum value in each row (or column) of the array. For the columns in the array above I want the result to be:
Array={4,5,6,7}
If it helps, the maximum is always going to be the topmost number for a column and leftmost number for a row.
I would like a worksheet formula rather than a VBA function.
With a named range Rng and values as posted in original post try this formula.
=SUBTOTAL(4,OFFSET(INDEX(Rng,1,1),,COLUMN(Rng)-MIN(COLUMN(Rng)),ROWS(Rng)))
It returns an array of max of each column {4,5,6,7}
This returns a max of each row.
=SUBTOTAL(4,OFFSET(INDEX(Rng,1,1),ROW(Rng)-MIN(ROW(Rng)),,,COLUMNS(Rng)))
and an array {7;6;5;4}.
I have found a solution. If my initial array is named rng then the following array formula can be used to return an array showing the maximum number in each column:
=MAX(INDEX(rng,0,COLUMN(A1:D1)))
Similarly, to return the maximum in each row:
=MAX(INDEX(rng, ROW(A1:A4)))

Resources