Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Randomize 3 groups within a panel

    I have a panel dataset that has 18 observations per spgrid_id (months). I want to within 3 blocks randomize. Its easy to do if I collapse, but I figured there has to be a simple way to do this within STATA. The code I wrote below randomizes within block, but I want to assign treatment based on three groups.

    How can I created 3 groups within each block that I could then randomize within the block?

    * Block 1: ranks 1–10, Block 2: 11–20, Block 3: 21–30
    gen block = ceil(rank / 10)

    * Set seed for reproducibility
    set seed 123456

    * One random draw per unit
    bysort spgrid_id: gen double rand = runiform() if _n == 1
    bysort spgrid_id: replace rand = rand[1]

    * Sort within block by random draw
    sort block rand spgrid_id

    * Sequence within each block (1–10) and month
    bysort block spgrid_id (ym): gen month = _n

    * Generate treatment indicator based on randomized treatment start times
    gen treatment = 0
    replace treatment = 1 if (block == 1 & month >= 6)
    replace treatment = 1 if (block == 2 & month >= 8)
    replace treatment = 1 if (block == 3 & month >= 12)




  • #2
    could use egen cut to create blocks.
    maybe shuffle var to shuffle the treatment (cluster option traps it in the groups).

    Comment


    • #3
      I don't find your description very clear and can't offer specific guidance; however, I believe that at least one of the following 3 user-written commands can do what you want; use the search command to find and install: ralloc, randomize, randtreat

      Comment


      • #4
        Originally posted by John MacDonald View Post
        I have a panel dataset that has 18 observations per spgrid_id (months). . . . How can I created 3 groups within each block that I could then randomize within the block?
        Why don't you just use Stata's frame feature to conduct randomization of your panels stratified by range of rank? I'm with Rich in that your description isn't very clear, but if I understand what you're trying to do, then the approach illustrated below ought to do the trick—start at the "Begin here" comment.

        Actually the core code begins at the frame copy line and is in blue; the first part creates a toy dataset for illustration that I think resembles yours, and then there's some preliminary data-assumption verification and I make the variable names more consistent in length.
        Code:
        version 19
        
        clear *
        
        // seedem
        set seed 2021261323
        
        quietly set obs 90
        generate byte spgrid_id = _n
        
        * Rank the spgrids
        generate double sco = runiform()
        sort sco
        generate byte rank = mod(_n, 30) + 1
        drop sco
        
        * Initial year and month
        generate int ym = runiform(480, 773) // 2000-01 to 2024-06
        quietly expand 18
        quietly bysort spgrid_id: replace ym = ym[1] + _n - 1 if _n > 1
        format ym %tmCCYY-NN
        
        *
        * Begin here
        *
        // A couple of preliminary data-managment tasks
        rename (spgrid_id rank ym) (sid rnk tim)
        isid sid tim, sort
        by sid: assert rnk == rnk[1]
        
        frame copy default Sids
        frame Sids {
        
            contract sid rnk, freq(cou)
        
            generate byte blk = ceil(rnk / 10)
            label variable blk Block
        
            generate double randu = runiform()
            isid blk randu, sort
        
            by blk: generate byte grp = mod(_n, 3) + 1
            label variable grp "Treatment Group"
        }
        frlink m:1 sid, frame(Sids)
        frget grp, from(Sids)
        
        // "Generate treatment indicator based on randomized treatment start times"
        by sid: generate byte mon = _n
        generate byte trt = cond(grp == 1, mo >= 6 , cond(grp == 2, mo >= 8, mo >= 12))
        
        list if inlist(sid, 1, 3, 5), noobs sepby(sid)
        
        frame Sids: tabulate blk grp
        
        exit
        The last two lines of code confirm that I get what I think you're after with respect to stratified randomization of month of treatment start, and that the stratified randomization is balanced.

        Complete do-file and log file are attached.
        Attached Files

        Comment


        • #5
          hard to tell what you're up to. If you want to randomize month within a block, then:

          shufflevar month , cluster(block)
          gen treatment = 0
          replace treatment = 1 if (block == 1 & month_shuffled >= 6)
          replace treatment = 1 if (block == 2 & month_shuffled >= 8)
          replace treatment = 1 if (block == 3 & month_shuffled >= 12)

          Comment

          Working...
          X