• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Finding the maximum value in an array containing one or more rows

Sajan

Excel Ninja
Hi,

I am attempting to find a way to identify the maximum value in an array that contains one or more rows.

My sample dataset is as follows:

0,1,2,0;1,2,0,0;0,0,0,3;0,4,5,0;0,0,0,0


Just for illustration, the above dataset can be represented in rows as follows:

[pre]
Code:
A   B   C   D
0   1   2   0
1   2   0   0
0   0   0   3
0   4   5   0
0   0   0   0
[/pre]
The result I am expecting is

2;2;3;5;0

(where each value is the max value in each row)


I am generating the original array through formulas. As such, I am hoping for a formula based solution that does not involve helper columns. (I need to be able to apply additional operations on the result set. Hence the constraint.)


The Excel functions like MAX() only operate on the full array (ignoring any "rows" inside the array).


Thanks for reading this post, and appreciate any help or pointers you can offer.


Thanks,

Sajan.
 
Hi, sthomas!


I know that it'd sound as silly but in your example placing this formula in cell E2 and copying down it works:

=MAX(A2:D2)


But having read you before I guess you knew it yet... so where's the catch?


A blind shoot:

{=K.ESIMO.MAYOR(A2:D6;FILA(A2:A6)-1)} -----> in english: {=LARGE(A2:D6,ROW(A2:A6)-1)}

Array formula, so input it with Ctrl-Shift-Enter

Even if it displays a unique cell, press F2, edit, select whole formula and press F9 to evaluate it: the whole 5-element array will appear.


Hope it helps.


Regards!


EDIT: found the catch (was just reading carefully) but please discard the suggestion, 5 elements but not the desired ones.


EDIT 2: needless to entered as array formula and even displaying the 5-element array.
 
Hi SirJB7,

As you pointed out, the functions such as MAX() and LARGE() return a value based on the whole array, ignoring any "rows" within the array. However, I am looking for a way to obtain the MAX values from each row.


I do appreciate your willingness to help.


Thanks,

Sajan.
 
Hi, sthomas!

And what about a short, little, harmful, sweet, no-other-idea, UDF?

Regards!
 
Hi SirJB7,

I am hoping that there is a formula based solution for my problem. (i.e. without using helper columns or UDFs.)


Having seen a lot of the clever solutions posted on this forum, I am very hopeful!!


Regards,

Sajan.
 
Hello Sajan,


Assuming numbers are in A1:D5, so this should do it.


=SUBTOTAL(4,OFFSET(A1:D1,ROW(A1:A5)-ROW(A1),0))


Adjust the range
 
Hi Haseeb,

Thanks for the suggestion.

My dataset is actually a long array, with embedded rows. (I had used the A1:D5 for illustration only. In hindsight, that was probably misleading.)

My sample dataset is as follows:0,1,2,0;1,2,0,0;0,0,0,3;0,4,5,0;0,0,0,0

The result I am expecting is2;2;3;5;0


(The result array is used in additional operations.)


Any formula ideas to turn the source array into the above result array would be greatly appreciated.


Thanks,

Sajan.
 
Haseeb


Can you adjust the range to suit?


What range is your data in?
 
Hi Hui,

The source array is dynamically generated by a formula. (It is an intermediate result that I am hoping to use in additional calculations, with final results feeding a single cell value.)


Thanks,

Sajan.
 
Hi, sthomas!

Hopelessly I stick with my previous suggestion:

http://chandoo.org/forums/topic/finding-the-maximum-value-in-an-array-containing-one-or-more-rows#post-32960

Regards!
 
Hi Sajan ,


I am not very sure this will do the job , but have you tried this :


=MAX(INDEX(Sample_Dataset,ROW(A1),0))


where Sample_Dataset is the matrix of values {0,1,2,0;1,2,0,0;0,0,0,3;0,4,5,0;0,0,0,0}


Copy the above formula downwards.


Narayan
 
Hi Narayan,

Thanks for the suggestion with INDEX() function.

Howvever, the function does not allow one to iterate through the whole array as part of a single calculation. i.e. The "row" parameter does not accept arrays. (Well, it actually does, but then it just takes the first value from that array!)

Ideally, if there was a way to have a formula such as =MAX(INDEX(Sample_Dataset,{1,2,3,4,5},0)) that would have worked out. But I have not found a way to trick Excel to iterate through the row parameter within a single function. I am hoping that someone can point me to such a trick!


Thanks,

Sajan.
 
Hi Sajan ,


I don't understand your problem.


When I try the formula , at different rows , it gives the following :


MAX(0,1,2,0)

MAX(1,2,0,0)

MAX(0,0,0,3)

MAX(0,4,5,0)

MAX(0,0,0,0)


Isn't this what you are looking for ?


Narayan
 
Hi Narayan,

The key phrase in your post is "at different rows". I am trying to iterate through the rows in a single function.


If my examples are not clear, I will post a longer explanation.


Thanks for your help.


Sajan.
 
Hi Sajan ,


Are you trying to make an array of the maximum values within one cell ? This means you will not be copying a formula downwards or across. Is this correct ?


Narayan
 
Hi Narayan,

(Earlier this morning, when I was typing my responses using a handheld device, I was trying to keep my responses brief. It is good to be back at a full keyboard!)


Yes, you are correct. I am trying to make an array of the maximum values within a single cell. I will not be copying a formula downwards or across.


Thanks

Sajan.
 
Sajan,


The SUBTOTAL with OFFSET function in my last post, will give ARRAY of the MAX numbers. You only can see 1st MAX number in a cell, but if you select the whole formula form the formula bar & press F9, then you can see each row's MAX numbers.


You can use this as an Array with other formulas. Adjust the ranges, if the range is dynamically changes, use dynamic range.


If you want to return whole MAX numbers in a cell separated by ';' then VBA only the way.
 
Hi Haseeb,

The OFFSET function expects a reference as its first parameter. My array is constructed through a formula. As such, I would not be able to use the OFFSET function.


My sample dataset is as follows: {0,1,2,0;1,2,0,0;0,0,0,3;0,4,5,0;0,0,0,0}

The result I am expecting is {2;2;3;5;0}, where each value is the max of the corresponding "row" in the above dataset / array.


The above array is the intermediate result of a formula, and the result set is used in additional operations. i.e. all of the manipulations happen in a single cell, in a single formula.


I look forward to hearing about any other ideas (that do not require VBA).


Thanks,

-Sajan.
 
Sajan,


If you don't mind could you please share the formula which getting array, {0,1,2,0;1,2,0,0;0,0,0,3;0,4,5,0;0,0,0,0} ?
 
Hi,

Before I describe the formula, let me start at the beginning!! My apologies in advance for this being a "story" post! (I am hoping that you and others would be able to suggest a different way to achieve the desired end result.)


(Due to firewall restrictions that block data storage sites, I am not in a position to upload a sample doc. However, I would be happy to e-mail it to someone if someone would be kind enough to upload the doc. Perhaps Chandoo can enhance this site to accept file attachments!)


Data requirements:

1.I have a list of items that are assigned to groups. However, the group membership can change over time. (For example, itemA could be in GroupA in January, but GroupB in February.)

2.I track the change in group membership using an effective date of when a new group is valid.

3.For every item, I have values per month.

4.Since an item's group membership may change over time, an item's value for a given month is attributed to the group that that item belongs to, in that particular month.

5.Not every Group may have Items

6.An Item may not have a Group assignment in a particular month.


Desired Outcome:

I am attempting to create a summary view by Group for each month.


Here is a sample Item List:

[pre]
Code:
Item	Jan-12	Feb-12	Mar-12	Apr-12	May-12	Jun-12	Jul-12
Item1.1	10	10	10	10	10	10	10
Item1.2	10	10	10	10	10	10	10
Item1.3	10	10	10	10	10	10	10
Item2.1	10	10	10	10	10	10	10
Item2.2	10	10	10	10	10	10	10
Item2.3	10	10	10	10	10	10	10
Here is a sample Group list:

[pre][code]Item	Group	Eff. Date
Item1.1	Group1	1/1/2012
Item1.1	Group4	3/1/2012
Item1.2	Group2	2/1/2012
Item1.3	Group3	3/1/2012
Item1.3	Group4	4/1/2012
Item2.1	Group3	2/1/2012
Item2.2	Group4	1/1/2012
Item2.3	Group5	8/1/2012
Here is the summary view I am attempting to create (where the XX would get replaced by the sum of the values from the Item List, where the Item's group membership for that month matches the Group identified in the respective row):

Groups	Jan-12	Feb-12	Mar-12	Apr-12	May-12	Jun-12	Jul-12
Group1	XX	XX	XX	XX	XX	XX	XX
Group2	XX	XX	XX	XX	XX	XX	XX
Group3	XX	XX	XX	XX	XX	XX	XX
Group4	XX	XX	XX	XX	XX	XX	XX
Group5	XX	XX	XX	XX	XX	XX	XX
[/pre]
I used the following formula to get the array in my original post, as an intermediate step to calculate the XX above. (The formula calculates the intermediate array for Group1 and Jan-12.)

(The final step would be to multiply with a month's values from the Item list.

In the formula, the name "GroupData" refers to the Grouplist above.

B2:B7 is the range of items in the Items List above.


=TRANSPOSE(TRANSPOSE(((($B$2:$B$7=TRANSPOSE(INDEX(GroupData,0,1))))))*(INDEX(GroupData,0,3)<=$A$1)) * TRANSPOSE(ROW(A1:INDEX(A:A,ROWS(GroupData))))


The above formula returns the following value for Group1 and Jan-12:

{1,2,0,0,0,0,0,0;0,0,3,0,0,0,0,0;0,0,0,4,5,0,0,0;0,0,0,0,0,6,0,0;0,0,0,0,0,0,7,0;0,0,0,0,0,0,0,0}


This value if displayed in rows and cols, would look as follows, with the Groups from the Group list displayed on top:

Items Group1 Group4 Group2 Group3 Group4 Group3 Group4 Group5
Item1.1 1 2 0 0 0 0 0 0
Item1.2 0 0 3 0 0 0 0 0
Item1.3 0 0 0 4 5 0 0 0
Item2.1 0 0 0 0 0 6 0 0
Item2.2 0 0 0 0 0 0 7 0
Item2.3 0 0 0 0 0 0 0 0[/code][/pre]
For example, Item1.1 has been a member of Group1 and Group4, with Group4 being the most recent membership.


I was planning to somehow turn this into a list such as the following, representing each Item in the ItemList:

{"Group4";"Group2";"Group4";"Group3";"Group4",""}

I was then planning to compare this list to the Group name in the Summary view, to get a boolean array.

I was then planning to multiply the boolean array with the values in the ItemList for that month, and sum them, to get the sum of values for that month.


Obviously, I did not get very far! (By the way, I did not attempt to optimize any of my formulas, since I was trying to get things to work.)


Hope this post makes sense.


Any pointers or suggestions would be very much appreciated.


Thanks,

Sajan.
 
Sajan, I hope I am following you correctly.


Firstly consider these.


B2:B7 Item list

C1:I1 each month

C2:I7 values


Some where GroupData with 3 columns.


B16:B20 enter group names, Group1-5

C15:I15 enter first day in each month


In C6, with CTRL+SHIFT+ENTER


=SUM(SUMIF($B$2:$B$7,IF((TEXT(INDEX(GroupData,0,3),"mmmyyyy;;;")=TEXT(C$15,"mmmyyyy;;;"))*(INDEX(GroupData,0,2)=$B16),INDEX(GroupData,0,1)),C$2:C$7))


If you can't simply reference C$2:C$7 for Jan, replace with INDEX/MATCH.


Does this help? or did I misread your post?


Regards,

Haseeb
 
Hi Haseeb,

I appreciate your feedback, and I think it is headed in the correct direction. One thing that may not have been clear in my "story" post above is regarding the use of the effective date in the GroupData.

[pre]
Code:
Item	Group	Eff. Date
Item1.1	Group1	1/1/2012
Item1.1	Group4	3/1/2012
Item1.2	Group2	2/1/2012
Item1.3	Group3	3/1/2012
Item1.3	Group4	4/1/2012
Item2.1	Group3	2/1/2012
Item2.2	Group4	1/1/2012
Item2.3	Group5	8/1/2012
[/pre]
In this sample, Item1.1 was a member of Group1 from 1/1/2012 to 2/29/2012.

Item1.1's membership changed to Group4 as of 3/1/2012.

Since there are no more rows for Item 1.1, it means that Group4 is in effect now (i.e. today).


As such, Group1 should include Item1.1 in Jan and Feb, but not March forward.

Similarly, Group4 should include Item1.1 starting in March (and for all future months), but not in Jan or Feb.


My apologies if this was not clear in my previous post.


This is also the cause for my "chase into the rabbit hole"...!


Thanks again for looking into this. I appreciate it very much.

-Sajan.
 
Hi Sajan ,


I don't wish to butt in , in this dialogue between you and Haseeb , but I think your problem is interesting enough for me to join in !


Your post is great , but I think your use of your formulae comes in the way of a reader getting to know what you want ! You have already decided on a direction you wish to take , and you expect the solution also to be in that direction. This is OK , if you are comfortable with this ; if you ask me , any problem post should have three components viz. the data you are working with , the output you expect , and an explanation of how that output is to be derived , since any output has to be derived from the given input following certain pre-determined rules.


In this case , at least for me , the first 'table' full of 10s is not sample data ; that table might as well have been blank ! The output 'table' full of XXs is similar.


Is it possible for you to take the case of any 1 item , and given its input data , say what value should appear in the output 'table' , and how it is derived ? From my reading of your post , I could not get this ; probably my inadequacy. Sorry if I am dense.


Narayan
 
Back
Top