/* _gtvor.ado 11-21-2000 By David Kantor, Institute for Policy Studies, Johns Hopkins University. This is a user-added feature for Stata's egen command. As such, it goes in c:\ado rather than c:\stata\ado\_. This provides a three-valued logic OR operation in an egen context. This is the column-wise version. See _rgtvor for the row-wise version. This is part of a suite of three-valued logic egen utilities: tvnot, rtvor, rtvand, tvor, tvand. (There are also tvlnot, tvlor, & tvland. Those are earlier, less complete versions, which stand as separate programs; they are not egen utilities. These egen utilities are to be preferred.) The binary operation utilities (rtvor, rtvand) actually take an arbitrary number of arguments. The column-wise "binary" operations (tvor, tvand) also do the same, with the understanding that the arguments are the values from one or more observations. This borrows ideas from c:\stata\ado\_\_gmax.ado and _gcount.ado. 2-28-2001: I am adding the "liberal" option. This allows a different version of the operation; it takes the OR of all non-missing elements, and only yields missing if all arguments are missing. */ program define _gtvor *! version 1.1.0 2-28-2001 version 5.0 if "`1'" == " " { local typ1 "byte" } else { local typ1 "" } /* We use typ1 to force a type of byte as a default. egen sends a value of one single space if the type was not specified. */ local varlist "req new max(1)" local exp "req nopre" local if "opt" local in "opt" local options "by(string) LIBeral" parse "`typ1' `*'" tempvar touse x numfals numtrue nummis /* Note that here, "true" is nonzero & nonmissing. */ quietly { gen byte `touse'=1 `if' `in' gen double `x'=`exp' sort `touse' `by' by `touse' `by': gen long `numfals' = sum((`x')==0) if `touse'==1 by `touse' `by': replace `numfals' = `numfals'[_N] by `touse' `by': gen long `numtrue' = sum((`x')~=0 & (`x')~=.) if `touse'==1 by `touse' `by': replace `numtrue' = `numtrue'[_N] by `touse' `by': gen long `nummis' = sum((`x')==.) if `touse'==1 by `touse' `by': replace `nummis' = `nummis'[_N] /* assert `numfals' >=0 & `numfals' ~=. if `touse'==1 assert `numtrue' >=0 & `numtrue' ~=. if `touse'==1 assert `nummis' >=0 & `nummis' ~=. if `touse'==1 */ #delimit ; if "`liberal'" =="liberal" {; by `touse' `by': replace `varlist'= cond(`numtrue'==0 & `numfals'== 0, ., `numtrue' >0) if `touse'==1; }; else {; by `touse' `by': replace `varlist'= cond(`numtrue' > 0, 1, cond(`nummis' ==0, 0, .) ) if `touse'==1; }; }; end;