*! version 1.1.0 26 July 1997 F.Wolfe
* Finds duplicate observations. v1.1 corrects errors using `if'
program define finddup
    version 5.0
    local varlist "req ex min(1)"
    local if "opt"
    #delimit ;
    local options "NOMiss NOList Keep *" ;
    #delimit cr
    parse "`*'"
    parse "`varlist'", parse(" ")
    preserve
    confirm new variable dupval
    tempvar touse dupval
    mark `touse' `if'
    sort `varlist' `touse'
    qui by `varlist' `touse': gen dupval = 1  if _N ~= _n & `touse' == 1
    qui by `varlist' `touse': replace dupval = 1  if dupval[_n-1] == 1  /*
    */ & `touse' == 1
    qui by `varlist' `touse': replace dupval = sum(dupval) if dupval ~=.
    if "`nomiss'" ~=""{
       qui for `varlist': replace dupval = . if @1 == .
    }
    if "`nolist'" == ""{
       l `varlist' dupval if dupval ~= .
    }
    if "`keep'" == "" {
       drop dupval
    }
    restore, not
    end