4
$\begingroup$

I have two lists (value and label). With the function Permute, I can permute the positions of the elements of value according to the permutation label.

Namely, the letters "a", "b", "c", "d", "e", "f" correspond to position numbers 1, 2, 3, 4, 5, 6 , and I want to arrange the number of value in the position described by label.

As a simple example:

value= {0, 1, 2, 0, 0, 2}; 
label = {"a", "b", "d", "f", "c", "e"}; 
Permute[value, LetterNumber[label]]

give the result:{0, 1, 0, 2, 2, 0}

When the two listed are both nested lists, I wonder whether one can directly use Permute as following:

value= {{0, 1, 2, 0, 0, 1}, {0, 1, 2, 0, 0, 2}, {0, 1, 2, 0, 1, 0}, {0, 1, 2, 0, 1, 1}};
label = {{"a", "b", "c", "d", "e", "f"}, {"a", "b", "d", "e", "c", "f"}, {"a", "b", "d", "f", "c", "e"}};

ii=2;
Permute[value, LetterNumber[label[[ii]]]] 

It gives some errors and doesn't work. However, when I make ii=1, there is no error. It seems one cannot use Permute directly in nested lists.

One way is to use for-loop. However the calaulation will slow down when the two lists get larger and larger.

AllVC= {};
For[ii = 1, ii <= Length[label], ii++,  
   For[jj = 1, jj <= Length[value], jj++,  
       CurrVC = Permute[value[[jj]], LetterNumber[label[[ii]]]];
       AppendTo[AllVC, CurrVC];
     ];
  ];

Is it possiable to use Permute for nested lists without using loops? Is there any simple and quike way to do the above task when lists get large? Thank you in advance!

$\endgroup$
2
  • $\begingroup$ try Map[Permute[#, LetterNumber[label[[ii]]]] &]@value $\endgroup$ – kglr May 25 at 9:54
  • $\begingroup$ thank you!@kglr $\endgroup$ – Xuemei May 25 at 15:57
3
$\begingroup$

1. Table

Table[Permute[i, j], {j, LetterNumber@label}, {i, value}]

enter image description here

2. Outer

Outer[Permute[#2, #] &, LetterNumber[label], value, 1]

enter image description here

3. Array

Array[Permute[value[[#2]], LetterNumber@label[[#]]] &, Length /@ {label, value}]

enter image description here

4. Part + Map:

value[[All, LetterNumber @ #]] & /@ label

{{{0, 1, 2, 0, 0, 1}, {0, 1, 2, 0, 0, 2}, {0, 1, 2, 0, 1, 0}, {0, 1,
2, 0, 1, 1}}, {{0, 1, 0, 0, 2, 1}, {0, 1, 0, 0, 2, 2}, {0, 1, 0, 1,
2, 0}, {0, 1, 0, 1, 2, 1}}, {{0, 1, 0, 1, 2, 0}, {0, 1, 0, 2, 2,
0}, {0, 1, 0, 0, 2, 1}, {0, 1, 0, 1, 2, 1}}}

5. You can also use Ordering instead of LetterNumber:

value[[All, Ordering @ #]] & /@ label

enter image description here

$\endgroup$
2
  • $\begingroup$ wow, amazing! thank you so much! $\endgroup$ – Xuemei May 25 at 10:34
  • $\begingroup$ I have another question in the link, could you help to have a look? @kglr $\endgroup$ – Xuemei May 25 at 16:04
2
$\begingroup$

In your example the lengths of "value" and "label" are different. I added to "label":

value = {{0, 1, 2, 0, 0, 1}, {0, 1, 2, 0, 0, 2}, {0, 1, 2, 0, 1, 
    0}, {0, 1, 2, 0, 1, 1}};
label = {{"a", "b", "c", "d", "e", "f"}, {"a", "b", "d", "e", "c", 
    "f"}, {"a", "b", "d", "f", "c", "e"}, {"a", "b", "d", "f", "c", 
    "e"}};
MapThread[Permute, {value, LetterNumber /@ label}]

(* {{0, 1, 2, 0, 0, 1}, {0, 1, 0, 2, 0, 2}, {0, 1, 1, 2, 0, 0}, {0, 1, 1,
   2, 1, 0}} *)
$\endgroup$
1
  • $\begingroup$ ha, I somehow don't want the lists have the same length. But also good way to extend to same length. Thank you! $\endgroup$ – Xuemei May 25 at 10:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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