3
$\begingroup$

I have some data in the form:

 data = {{{d, 0.68}, {g, 0.88}, {h, 0.23}, {e, 0.15}, {b, 0.46}, {a, 0.07}}, 
         {{d, 0.86}, {c, 0.99}, {b, 0.21}}, 
         {{c,0.83}, {h, 0.63}, {f, 0.11}}, 
         {{d, 0.31}, {g, 0.65}, {e, 0.88}, {a, 0.70}}, 
         {{d, 0.58}, {g, 0.09}, {c, 0.66}, {b, 0.18}, {a, 0.15}}}

These data are essentially related to each other in the following way:

{{{d, d1}, {g, g1}, {h, h1}, {e, e1}, {b, b1}, {a, a1}}, 
 {{d, d2}, {c, c2}, {b, b2}}, 
 {{c, c3}, {h, h3}, {f, f3}}, 
 {{d, d4}, {g, g4}, {e, e4}, {a, a4}}, 
 {{d, d5}, {g, g5}, {c, c5}, {b, b5}, {a, a5}}}

The ordering of elements within each second level list is:

order1 = {d, g, c, h, e, f, b, a}

I want to collect the second term of each third level pair and rearrange the elements according to a different order:

order2 = {b, h, d, a, e, f, c, g}

so that I end up with something like:

{{b1, h1, d1, a1, e1, f1, c1, g1},
 {b2, h2, d2, a2, e2, f2, c2, g2},
 {b3, h3, d3, a3, e3, f3, c3, g3},
 {b4, h4, d4, a4, e4, f4, c4, g4},
 {b5, h5, d5, a5, e5, f5, c5, g5}}

Where an element is missing I want to replace it with a zero to obtain rows of equal length. Using numbers it would look like:

  {{0.46, 0.23, 0.68, 0.07, 0.15, 0, 0, 0.88}, 
   {0.21, 0, 0.86, 0, 0, 0, 0.99, 0}, 
   {0, 0.63, 0, 0, 0, 0.11, 0.83, 0}, 
   {0, 0, 0.31, 0.7, 0.88, 0, 0, 0.65}, 
   {0.18, 0, 0.58, 0.15, 0, 0, 0.66, 0.09}}

I am currently using

 (row = #; 
   Map[(ordi = #; k = Flatten[Position[row, _?((ordi == #) &)]];
             If[Length[k] == 0, 0, row[[k[[1]], 2]]]) & , order2]) &/@ data

Edit

The code in the original question is now working... (thanks @partial81 for trying it - and sorry for the confusion).

However, I am still interested in discovering different ways to get the result. Any alternative suggestions would be appreciated.

$\endgroup$
2
  • $\begingroup$ If I use your data and in your approach order1 (instead of order, I get back your shown result ({{0.68,0.88,...}}). Also if I use {{{d, d1}, {g, g1},...} and order2 in your approach, I get back something like {{b1, h1, d1, a1, e1, 0, 0, g1},...}. So I would say, your solution works. Or aren`t this the results you want to have? $\endgroup$
    – partial81
    Commented Jun 25, 2013 at 6:29
  • $\begingroup$ @partial81 indeed. the code seems to be working. see my edit. $\endgroup$
    – geordie
    Commented Jun 25, 2013 at 7:18

2 Answers 2

3
$\begingroup$

Another version which involves converting the data into a list of rules:

order2 /. Apply[Rule, data, {2}] /. Alternatives @@ order2 -> 0.
$\endgroup$
1
  • $\begingroup$ Bravo. AbsoluteTiming -> 0.000134 . Many thanks! $\endgroup$
    – geordie
    Commented Jun 25, 2013 at 12:13
2
$\begingroup$

Your can do it by converting your data into a list of rules.

data = 
{
  {{d, 0.68}, {g, 0.88}, {h, 0.23}, {e, 0.15}, {b, 0.46}, {a, 0.07}}, 
  {{d, 0.86}, {c, 0.99}, {b, 0.21}}, {{c, 0.83}, 
  {h, 0.63}, {f, 0.11}}, {{d, 0.31}, {g, 0.65}, {e, 0.88}, 
  {a, 0.70}}, {{d, 0.58}, {g, 0.09}, {c, 0.66}, {b, 0.18}, {a, 0.15}}
};

default = {#, 0.} & /@ {b, h, d, a, e, f, c, g};

rules = Map[({#[[1]], 0.} -> {#[[1]], #[[2]]}) &, data, {2}]
{{{d, 0.} -> {d, 0.68}, {g, 0.} -> {g, 0.88}, {h, 0.} -> {h, 0.23},  
   {e, 0.} -> {e, 0.15}, {b, 0.} -> {b, 0.46}, {a, 0.} -> {a, 0.07}},  
  {{d, 0.} -> {d, 0.86}, {c, 0.} -> {c, 0.99}, {b, 0.} -> {b, 0.21}},  
   {{c, 0.} -> {c, 0.83}, {h, 0.} -> {h, 0.63}, {f, 0.} -> {f, 0.11}},  
  {{d, 0.} -> {d, 0.31}, {g, 0.} -> {g, 0.65}, {e, 0.} -> {e, 0.88},  
   {a, 0.} -> {a, 0.7}}, 
  {{d, 0.} -> {d, 0.58}, {g, 0.} -> {g, 0.09}, {c, 0.} -> {c, 0.66},  
   {b, 0.} -> {b, 0.18}, {a, 0.} -> {a, 0.15}}}
Map[Last, Table[default /. r, {r, rules}], {-2}]
{{0.46, 0.23, 0.68, 0.07, 0.15, 0., 0., 0.88},  
  {0.21, 0., 0.86, 0., 0., 0., 0.99, 0.},  
  {0., 0.63, 0., 0., 0., 0.11, 0.83, 0.},  
  {0., 0., 0.31, 0.7, 0.88, 0., 0., 0.65},  
  {0.18, 0., 0.58, 0.15, 0., 0., 0.66, 0.09}}
$\endgroup$
1
  • $\begingroup$ nice answer. thanks! $\endgroup$
    – geordie
    Commented Jun 25, 2013 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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