Tell me more ×
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 at 14:32
1  
GatherBy will possibly be of use: reference.wolfram.com/mathematica/ref/GatherBy.html – David Carraher Mar 10 at 14:45

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 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 at 20:37
Actually, Sort[data] is sufficient if it's inside the GatherBy. – David Carraher Mar 10 at 22:18

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 at 0:20
Also, where the devil is Sow & Reap? – Mr.Wizard Mar 11 at 0:20
@Mr.Wizard, added Reap[Sow[...]...]:) – kguler Mar 11 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 at 0:59
I think in many cases, SortBy[data,{First}] may be simplified to Sort[data]. – David Carraher Mar 11 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.