Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am looking for a way to iteratively select all sublists with the same ID (my 1st column, residual columns are AbsoluteTime entries). First, I obtained the list of unique IDs with Union. Then I want to use this list for the selection task. I assume that it must work with Sequence and ReplaceAll, but could not make it work. Here's what I have so far:

ticketList = Union[dataList[[1 ;;, 1]]];
tempList = Select[dataList, #1[[1]] == x &] /. x ->  Sequence[ticketList];

My ultimate goal is to build up a TemporalData array with all items which each belong to the same ID.

My data is has dimensions n x m. The ticket list has dimension t. The resulting table should have dimensions t x i x m, where i is the cardinality of items with the same ID, and the i's sum to n. I assumed, that I can then map TemporalData on every t-th item in order to build the temporal list.

I searched the site but didn't find a previous question that seem to address my problem. Maybe I misunderstood the use cases of similiar questions.

share|improve this question
4  
Can you give us a small size example of the dataList that you have and of the output you desire? –  bill s Mar 10 '13 at 14:32
1  
GatherBy will possibly be of use: reference.wolfram.com/mathematica/ref/GatherBy.html –  David Carraher Mar 10 '13 at 14:45
add comment

2 Answers

up vote 4 down vote accepted

Here's an attempt to address your question based on the sort of data I imagine you have in mind. First, some data. Note: the integers are understood to be ID's.

times = RandomReal[{0, 100}, {20, 5}];
ids = RandomInteger[4, 20];
data = Transpose[Prepend[Transpose[times], ids]]

{{1, 95.2049, 98.1609, 35.1946, 32.636, 81.2383}, {3, 92.8072, 36.0249, 68.3793, 54.1311, 95.1051}, {3, 4.26078, 47.9919, 31.627, 53.0064, 96.8995}, {4, 18.2792, 94.4752, 5.66575, 5.62435, 35.8945}, {4, 67.4149, 68.1577, 25.281, 17.8322, 15.3123}, {2, 77.6343, 35.3486, 81.3541, 73.6091, 51.4884}, {0, 28.5346, 29.2705, 78.9446, 32.2112, 7.05296}, {4, 91.9405, 79.4176, 75.6947, 72.1069, 5.94247}, {2, 11.0662, 24.4381, 79.5328, 20.2195, 79.4703}, {0, 61.6779, 73.8532, 61.5861, 7.79641, 38.3836}, {4, 52.3064, 95.9954, 62.3701, 34.7654, 99.8931}, {2, 92.6636, 57.8744, 23.4167, 76.3724, 44.8631}, {2, 73.7149, 84.6716, 36.1234, 89.5432, 39.8183}, {3, 50.4444, 7.98911, 69.4092, 96.3191, 79.6566}, {3, 41.2261, 58.5009, 57.7989, 58.9187, 8.87187}, {4, 53.5552, 11.3278, 8.24034, 67.3065, 19.4648}, {2, 19.9501, 30.5649, 73.9395, 13.3722, 36.5546}, {3, 96.5631, 19.1948, 23.226, 92.8776, 64.4002}, {0, 65.9084, 10.2902, 8.83754, 93.0831, 36.464}, {1, 18.2795, 12.4673, 42.0253, 39.8816, 50.8252}}

Now to gather the records that have the same id:

GatherBy[data, First]//TableForm

Mathematica graphics

share|improve this answer
    
That's exactly what I was aiming for and the absolute elegant solution. I am sorry that I did not find GatherBy in the manual. Sometimes the power of MM is really amazing / overwhelming. –  Frank Mar 10 '13 at 19:57
    
Thanks. Yes, Mathematica knows many useful ways to manipulate lists. BTW, if you wanted the id's to appear in standard order, you might do a SortBy[data,First] before GatherBy. –  David Carraher Mar 10 '13 at 20:37
    
Actually, Sort[data] is sufficient if it's inside the GatherBy. –  David Carraher Mar 10 '13 at 22:18
add comment

Using @David's example data

 times = RandomReal[{0, 100}, {20, 5}]; 
 ids =   RandomInteger[4, 20]; 
 data = Transpose[Prepend[Transpose[times], ids]];

"few" more alternatives (none as elegant as David's answer):

 dt1 = Select[data, (#1[[1]] == x) & /. x -> #] & /@  Union[data[[All, 1]]];
 dt2 = Function[{xx}, Select[data, #[[1]] == xx &]] /@ Union@data[[All, 1]];
 dt3 = Cases[data, {#, __}] & /@ Union[data[[All, 1]]];
 dt4 = DeleteCases[data, Except[{#, __}]] & /@ Union[data[[All, 1]]];
 dt5 = Pick[data, data[[All, 1]], #] & /@ Union@data[[All, 1]];
 dt6 = Pick[data, data[[All, 1]] - #, 0] & /@ Union@data[[All, 1]];
 dt7 = SplitBy[SortBy[data, {First}], First];
 dt8 = SortBy[GatherBy[data, First], First];
 dt9 = GatherBy[SortBy[data, {First}], First];
 dt10 = Extract[data, #] & /@ Position[data, {#, __}] & /@ Union[data[[All, 1]]];
 dt11 = data[[#]] & /@ Join @@ Position[data, {#, __}] & /@ Union[data[[All, 1]]];
 dt12 = Reap[Sow[#, First[#]] & /@ SortBy[data, {First}]][[2]];
 dt1 == dt2 == dt3 == dt4 == dt5 == dt6 == dt7 == dt8 == dt9 == dt10 == dt11 == dt12
 (* True *)

Note: If the ordering of the elements in the sublists does not matter, Last@Reap[Sow[#, First[#]] & /@ data] gives the same result as GatherBy[data,First]:

 GatherBy[data,First]==Last@Reap[Sow[#, First[#]] & /@ data]
 (* True *)
share|improve this answer
    
Whatever I had you've plainly caught. Get well soon! xD –  Mr.Wizard Mar 11 '13 at 0:20
    
Also, where the devil is Sow & Reap? –  Mr.Wizard Mar 11 '13 at 0:20
    
@Mr.Wizard, added Reap[Sow[...]...]:) –  kguler Mar 11 '13 at 0:45
    
Another one for your list: Reap[{##} ~Sow~ # & @@@ data, Union[First /@ data]][[2, All, 1]] -- no claims of efficiency. –  Mr.Wizard Mar 11 '13 at 0:59
    
I think in many cases, SortBy[data,{First}] may be simplified to Sort[data]. –  David Carraher Mar 11 '13 at 1:18
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.