1
votes

Observations in my dataset are players, and binary variables temp1 up are equal to 1 if the player made a move, and equal to zero otherwise. I would like to to calculate the maximum number of consecutive moves per player.

+------------+------------+-------+-------+-------+-------+-------+-------+
| simulation | playerlist | temp1 | temp2 | temp3 | temp4 | temp5 | temp6 |
+------------+------------+-------+-------+-------+-------+-------+-------+
|          1 |          1 |     0 |     1 |     1 |     1 |     0 |     0 |
|          1 |          2 |     1 |     0 |     0 |     0 |     1 |     1 |
+------------+------------+-------+-------+-------+-------+-------+-------+

My idea was to generate auxiliary variables in a loop, which would count consecutive duplicates and then apply egen, rowmax():

+------------+------------+------+------+------+------+------+------+------+
| simulation | playerlist | aux1 | aux2 | aux3 | aux4 | aux5 | aux6 | _max |
+------------+------------+------+------+------+------+------+------+------+
|          1 |          1 |    0 |    1 |    2 |    3 |    0 |    0 |    3 |
|          1 |          2 |    1 |    0 |    0 |    0 |    1 |    2 |    2 |
+------------+------------+------+------+------+------+------+------+------+

I am struggling with introducing a local counter variable that would be incrementally increased by 1 if consecutive move is made, and would be reset to zero otherwise (the code below keeps auxiliary variables fixed..):

    quietly forval i = 1/42 { /*42 is max number of variables temp*/
    local j = 1 
    gen aux`i'=.    
    local j = `j'+1
    replace aux`i'= `j' if temp`i'!=0
} 
1

1 Answers

5
votes

Tactical answer

You can concatenate your move* variables into a single string and look for the longest substring of 1s.

egen history = concat(move*) 

gen max = 0 
quietly forval j = 1/6 { 
    replace max = `j' if strpos(history, substr("111111", 1, `j')) 
} 

If the number is much more than 6, use something like

 local lookfor : di _dup(42) "1" 
 quietly forval j = 1/42 { 
     replace max = `j' if strpos(history, substr("`lookfor'", 1, `j')) 
 } 

Compare also http://www.stata-journal.com/article.html?article=dm0056

Strategic answer

Storing a sequence rowwise is working against the grain so far as Stata is concerned. Much more flexibility is available if you reshape long and tsset your data as panel data. Note that the code here uses tsspell which must be installed from SSC using ssc inst tsspell.

tsspell is dedicated to identifying spells or runs in which some condition remains true. Here the condition is that a variable is 1 and since the only other allowed value is 0 that is equivalent to a variable being positive. tsspell creates three variables, giving spell identifier, sequence within spell and whether the spell is ending. Here the maximum length of spell is just the maximum sequence number for each game.

. input simulation playerlist temp1 temp2 temp3 temp4 temp5 temp6 

 simulat~n  playerl~t      temp1      temp2      temp3      temp4      temp5      temp6
 1.   1   1  0  1  1  1  0  0 
 2.   1   2  1  0  0  0  1  1 
 3. end 

. reshape long temp , i(sim playerlist) j(seq) 
(note: j = 1 2 3 4 5 6)

 Data                               wide   ->   long
 -----------------------------------------------------------------------------
 Number of obs.                        2   ->      12
 Number of variables                   8   ->       4
 j variable (6 values)                     ->   seq
 xij variables:
                   temp1 temp2 ... temp6   ->   temp
 -----------------------------------------------------------------------------

. egen id = group(sim playerlist) 

. tsset id seq 
   panel variable:  id (strongly balanced)
    time variable:  seq, 1 to 6
            delta:  1 unit

. tsspell, p(temp) 

. egen max = max(_seq), by(id) 

. l

      +--------------------------------------------------------------------+
      | simula~n   player~t   seq   temp   id   _seq   _spell   _end   max |
      |--------------------------------------------------------------------|
   1. |        1          1     1      0    1      0        0      0     3 |
   2. |        1          1     2      1    1      1        1      0     3 |
   3. |        1          1     3      1    1      2        1      0     3 |
   4. |        1          1     4      1    1      3        1      1     3 |
   5. |        1          1     5      0    1      0        0      0     3 |
      |--------------------------------------------------------------------|
   6. |        1          1     6      0    1      0        0      0     3 |
   7. |        1          2     1      1    2      1        1      1     2 |
   8. |        1          2     2      0    2      0        0      0     2 |
   9. |        1          2     3      0    2      0        0      0     2 |
  10. |        1          2     4      0    2      0        0      0     2 |
      |--------------------------------------------------------------------|
  11. |        1          2     5      1    2      1        2      0     2 |
  12. |        1          2     6      1    2      2        2      1     2 |
      +--------------------------------------------------------------------+