program define flower
* sunflower plots
*! 2.0.0 01nov1999  TJS & NJC
*  1.0.0 27sep1997  NJC
*  syntax: flower yvar xvar [fw] [if] [in] [, {yround(#)|ybins(#)}
*         {xround(#)|xbins(#)} psize(size) petals(maxnum) graph_options]
   version 6
   syntax varlist(numeric min=2 max=2) [fw] [if] [in]       /*
       */ [ , YRound(real -1) XRound(real -1) YBins(int -1) /*
       */     XBins(int -1) PSize(real 100) PEtals(int 10)  /*
       */     Symbol(str) SAving(str) * ]
   marksample touse
   tokenize `varlist'

   if "`symbol'" != "" {
      di in bl "symbol() not allowed; ignored"
   }

   if `ybins' == 0 | `xbins' == 0 {
      di in re "number of bins must be a positive integer"
      exit 411
   }

   if "`saving'" != "" {
      local c  = index("`saving'",",")
      local cs " "
      if index("`saving'",", ") { local cs "" }
      if `c' {
         local saving = substr("`saving'",1,`c' - 1) /*
         */  + "`cs'" + substr("`saving'",`c' + 1, .)
      }
      local savfile : word 1 of `saving'
      local replace : word 2 of `saving'
      if "`replace'" == "replace" { capture erase "`savfile'.gph" }
      capture confirm new file "`savfile'.gph"
      if _rc == 0 { local saving ", saving(`savfile')" }
      else {
         local rc = _rc
         di in re "  file `savfile'.gph exists."
         di in bl "use another filename or add ', replace' qualifier."
         exit `rc'
      }
   }

   local ybin = (`yround' != -1) + (`ybins' != -1)
   if `ybin' == 2 {
      di in re "choose between yround( ) and ybin( )"
      exit 198
   }

   local xbin = (`xround' != -1) + (`xbins' != -1)
   if `xbin' == 2 {
      di in re "choose between xround( ) and xbin( )"
      exit 198
   }

   tempvar y x wt freq tag
   qui {
      if `ybin' {
         if `yround' == -1  {
            summ `1' if `touse', meanonly
            local yround = (r(max) - r(min))/`ybins'
         }
         gen `y' = round(`1',`yround') if `touse'
      }
      else gen `y' = `1' if `touse'

      if `xbin' {
         if `xround' == -1 {
            summ `2' if `touse', meanonly
            local xround = (r(max) - r(min))/`xbins'
         }
         gen `x' = round(`2',`xround') if `touse'
      }
      else gen `x' = `2' if `touse'

      if "`exp'" == "" { local exp "= 1" }
      gen `wt' `exp'

      sort `touse' `x' `y'
      by `touse' `x' `y': gen `freq' = sum(`wt')
      by `touse' `x' `y': replace `freq' = `freq'[_N]
      by `touse' `x' `y': gen byte `tag' = _n == 1
      replace `freq' = min(`freq',`petals')
      replace `tag' = `touse' * `tag'
      sort `tag' `freq'

      Copydesc `1' `y'
      Copydesc `2' `x'
   }

   tempname ysca yloc xsca xloc f ang

   local size  = abs(4   * `psize')
   local csize = abs(0.7 * `psize')

   qui gph open `saving'
   graph `y' `x', sy(.) `options'
   scalar `ysca'  = r(ay)
   scalar `yloc'  = r(by)
   scalar `xsca'  = r(ax)
   scalar `xloc'  = r(bx)

   qui count if `tag' == 0
   local i = 1 + r(N)
   while `i' <= _N {
      local r = `y'[`i'] * `ysca' + `yloc'
      local c = `x'[`i'] * `xsca' + `xloc'

      gph arc `r' `c' `csize' 0 32767 0

      scalar `f' = `freq'[`i']
      local j 1
      while `j' <= `f' & `f' > 1 {
         scalar `ang' = _pi  * (2 * `j' / `f' - 0.5)
         local r1 = `r' + `size' * sin(`ang')
         local c1 = `c' + `size' * cos(`ang')
         gph line `r' `c' `r1' `c1'
         local j = `j' + 1
      }
      local i = `i' + 1
   }
   gph close
end

program def Copydesc
*  copy description from source variable to destination variable
*  1.0.0 29Oct99 NJC
*  syntax: Copydesc src dst
   version 6.0
   syntax varlist(min=2 max=2)
   tokenize `varlist'
   args src dst
   local w : variable label `src'
   if `"`w'"' == "" { local w "`src'" }
   label variable `dst' `"`w'"'
   local srclab : value label `src'
   label val `dst' `srclab'
   local srcfmt : format `src'
   format `dst' `srcfmt'
end