Got it, finally. I missed that egen rank() can do it by().
. clear
. set obs 40
obs was 0, now 40
. gen index = _n
. egen period = seq(), from(1) to(4) block(10)
. egen order = seq(), from(1) to(5) block(2)
. gen rand = uniform()
. egen rank = rank(rand), by(period)
. list
+------------------------------------------+
| index period order rand rank |
|------------------------------------------|
1. | 1 1 1 .4481307 6 |
2. | 2 1 1 .2635594 5 |
3. | 3 1 2 .7811205 10 |
4. | 4 1 2 .033332 2 |
5. | 5 1 3 .1485784 3 |
|------------------------------------------|
6. | 6 1 3 .0275981 1 |
7. | 7 1 4 .2213698 4 |
8. | 8 1 4 .7073388 8 |
9. | 9 1 5 .727761 9 |
10. | 10 1 5 .5738866 7 |
|------------------------------------------|
11. | 11 2 1 .9036617 10 |
12. | 12 2 1 .2007026 1 |
13. | 13 2 2 .3221595 2 |
14. | 14 2 2 .8862541 7 |
15. | 15 2 3 .8474928 6 |
|------------------------------------------|
16. | 16 2 3 .398986 4 |
17. | 17 2 4 .8991827 8 |
18. | 18 2 4 .4249812 5 |
19. | 19 2 5 .3851897 3 |
20. | 20 2 5 .9032691 9 |
|------------------------------------------|
21. | 21 3 1 .7743317 8 |
22. | 22 3 1 .7679698 7 |
23. | 23 3 2 .5425138 5 |
24. | 24 3 2 .8719242 9 |
25. | 25 3 3 .5227695 4 |
|------------------------------------------|
26. | 26 3 3 .2102229 1 |
27. | 27 3 4 .5534564 6 |
28. | 28 3 4 .9088587 10 |
29. | 29 3 5 .2769888 2 |
30. | 30 3 5 .3915251 3 |
|------------------------------------------|
31. | 31 4 1 .0396565 1 |
32. | 32 4 1 .4235426 3 |
33. | 33 4 2 .6125947 6 |
34. | 34 4 2 .5015944 5 |
35. | 35 4 3 .4720692 4 |
|------------------------------------------|
36. | 36 4 3 .8197762 7 |
37. | 37 4 4 .0960781 2 |
38. | 38 4 4 .9636718 10 |
39. | 39 4 5 .8774827 8 |
40. | 40 4 5 .9396089 9 |
+------------------------------------------+
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/