Announcement

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

  • Random day within range AND specific day of week

    I have a dataset with individual prison spells, e.g.:
    Start End
    12may2010 30jan2011
    10jun2008 15jul2010
    I want to create a variable that takes on a random day within the prison spell, but this random day also has to be either a saturday or a sunday.
    So far I have written:

    Code:
    ge rdate = start - round(runiform() * (end-start))
    which satisfies the first condition (it gives me a random date within start-end).
    Is there a way to restrict the random date to be either a saturday or sunday?

  • #2
    First, your rdate is not giving you random days between the start and end date, the rdates fall outside of (before) that interval. I think you might have wanted:

    Code:
    g rdate  = start+int((end-start+1)*runiform())
    For choosing a random Sat/Sun, I wonder if you could somehow use -bcal- to create a calendar of only weekends and then randomly select dates (I dont know much about -bcal- but it seems like it might have this capability; hopefully someone here has some insights on this).

    The way I'd (quickly) solve this is by iterating the rdate selection until the date was a sat/sun as indicated by the dow() function. A toy example of this is below, but note that this isnt really a random selection (sampled in a uniform way for all observations) but more of a brute force method of redrawing numbers until they fall into the range of interest. I am sure there are better ways to do this, but this is the first thing that came to mind.


    Code:
    clear
    input str15 (Start    End)
    "12may2010"    "30jan2011"
    "10jun2008"    "15jul2010"
    "12jun2008"    "15jul2013"
    "9jun2008"    "1jul2011"
    "8jun2008"    "1jul2012"
    "1jun2007"    "1jul2009"
    end
    g start = date(Start, "DMY")
    g end = date(End, "DMY")
    format start end %td
     
    ge rdate = start - round(runiform() * (end-start))
    
    **maybe instead you want 
    g rdate_between = start+int((end-start+1)*runiform())
            format rdate* %td
        **inside interval?
        assert rdate_between - start>=0 & rdate_between-end<=0 
    
    g dow = dow(rdate)
    l
    
    g firstrunweekend = 1 if inlist(dow, 0, 6)
    
    forval n = 1/100 { //would need to increase this until you got all the replacements you needed
        replace rdate = start - round(runiform() * (end-start)) if !inlist(dow, 0, 6)
        replace dow = dow(rdate) 
        }
        
        format rdate %td
        lab def dow 0 "Sun" 6 "Sat" , modify
        lab val dow dow
        
     list


    Eric A. Booth | Senior Director of Research | Far Harbor | Austin TX

    Comment


    • #3
      Here another approach using rangejoin (from SSC) to pick-up all weekend dates that fall within the time-span of each prison spell.

      Code:
      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input long id str9(Start End)
      1 "12may2010" "30jan2011"
      2 "10jun2008" "15jul2010"
      3 "12jun2008" "15jul2013"
      4 "9jun2008"  "1jul2011" 
      5 "8jun2008"  "1jul2012" 
      6 "1jun2007"  "1jul2009" 
      end
      gen day1 = daily(Start, "DMY")
      gen dayN = daily(End,   "DMY")
      format %td day1 dayN
      save "dataex.dta", replace
      
      * create a dataset of weekend days within the span of dates
      sum day1
      local low = r(min)
      sum dayN
      local high = r(max)
      local days = `high' - `low' + 1
      clear
      set obs `days'
      gen pickdate = `low' + _n - 1
      format %tdDayDDmonCCYY pickdate
      keep if inlist(dow(pickdate), 0, 6)
      save "weekend_days.dta", replace
      
      * load spell data and match each spell to all weekend dates within the spell
      use "dataex.dta"
      rangejoin pickdate day1 dayN using "weekend_days.dta"
      
      * select a random weekend date
      set seed 312
      gen u = runiform()
      bysort id (u): keep if _n == 1

      Comment

      Working...
      X