reshape.ado
来自「是一个经济学管理应用软件 很难找的 但是经济学学生又必须用到」· ADO 代码 · 共 1,461 行 · 第 1/2 页
ADO
1,461 行
*! version 4.1.6 12nov2003
program define reshape
version 5.0, missing
if "`1'"=="clear" {
char _dta[ReS_ver]
char _dta[ReS_i]
char _dta[ReS_j]
char _dta[ReS_jv]
char _dta[ReS_Xij]
char _dta[Res_Xi]
char _dta[ReS_atwl]
char _dta[ReS_str]
exit
}
if "`1'"=="wide" | "`1'"=="long" {
DoNew `*'
exit
}
local syntax : char _dta[ReS_ver]
if "`1'"=="" | "`1'"==substr("query",1,length("`1'")) {
if "`syntax'"=="" | "`syntax'"=="v.2" {
Query
exit
}
local 1 "query"
}
if "`syntax'"=="" {
IfOld `1'
if `s(oldflag)' {
DoOld `*'
char _dta[ReS_ver] "v.1"
}
else {
DoNew `*'
char _dta[ReS_ver] "v.2"
}
exit
}
if "`syntax'"=="v.1" {
DoOld `*'
}
else DoNew `*'
end
program define IfOld, sclass
if "`1'"=="" {
sret local oldflag 0
exit
}
local l = length("`1'")
if "`1'"==substr("groups",1,`l') | /*
*/ "`1'"==substr("vars",1,`l') | /*
*/ "`1'"==substr("cons",1,`l') | /*
*/ "`1'"==substr("query",1,`l') {
sret local oldflag 1
exit
}
sret local oldflag 0
end
program define IfNew, sclass
if "`1'"=="i" | "`1'"=="j" | "`1'"=="xij" | "`1'"=="xi" | /*
*/ "`1'"=="error" {
sret local newflag 1
}
else sret local newflag 0
end
program define DoNew
local c "`1'"
mac shift
if "`c'"=="i" {
if "`*'" == "" { error 198 }
unabbrev `*', max(10) min(1)
char _dta[ReS_i] "`s(varlist)'"
exit
}
if "`c'"=="j" {
J `*'
exit
}
if "`c'"=="xij" {
Xij `*'
exit
}
if "`c'"=="xi" {
sret clear
if "`*'"!="" {
unabbrev `*'
}
char _dta[Res_Xi] "`s(varlist)'"
exit
}
if "`c'"=="" { /* reshape */
Query
exit
}
if "`c'"=="long" { /* reshape long */
if "`1'" != "" {
Simple long `*'
}
capture noisily Long `*'
Macdrop
exit _rc
}
if "`c'"=="wide" { /* reshape wide */
if "`1'" != "" {
Simple wide `*'
}
capture noisily Wide `*'
Macdrop
exit _rc
}
if "`c'"==substr("error",1,max(3,length("`c'"))) {
capture noisily Qerror `*'
Macdrop
exit
}
IfOld `c'
if `s(oldflag)' {
di in red "may not mix old and new syntax;"
di in red "either use new syntax or " /*
*/ _quote "reshape clear" _quote /*
*/ " and start over using old syntax."
exit 198
}
error 198
end
program define Macdrop
mac drop ReS_j ReS_jv ReS_i ReS_Xij rVANS Res_Xi /*
*/ ReS_atwl ReS_str S_1 S_2
end
program define ReportL /* old_obs old_vars */
Report1 `1' `2' wide long
local n : word count $ReS_jv
di in gr "j variable (`n' values)" _col(43) "->" _col(48) /*
*/ in ye "$ReS_j"
di in gr "xij variables:"
parse "$ReS_Xij", parse(" ")
while "`1'"!="" {
RepF "`1'"
local skip = 39 - length("$S_1")
di in ye _skip(`skip') "$S_1" _col(43) in gr "->" /*
*/ in ye _col(48) "$S_2"
mac shift
}
di in smcl in gr "{hline 77}"
end
program define RepF /* element from ReS_Xij */
local v "`1'"
if "$ReS_jv2" != "" {
local n : word count $ReS_jv2
parse "$ReS_jv2", parse(" ")
}
else {
local n : word count $ReS_jv
parse "$ReS_jv", parse(" ")
}
if `n'>=1 {
Subname `v' `1'
local list $S_1
}
if `n'>=2 {
Subname `v' `2'
local list `list' $S_1
}
if `n'==3 {
Subname `v' ``n''
local list `list' $S_1
}
else if `n'>3 {
Subname `v' ``n''
local list `list' ... $S_1
}
Subname `v' $ReS_atwl
global S_2 $S_1
global S_1 `list'
end
program define Report1 /* <#oobs> <#ovars> {wide|long} {long|wide} */
local oobs "`1'"
local ovars "`2'"
local wide "`3'"
local long "`4'"
di in smcl _n in gr /*
*/ "Data" _col(36) "`wide'" _col(43) "->" _col(48) "`long'" /*
*/ _n "{hline 77}"
di in gr "Number of obs." _col(32) in ye %8.0g `oobs' /*
*/ in gr _col(43) "->" in ye %8.0g _N
quietly desc, short
di in gr "Number of variables" _col(32) in ye %8.0g `ovars' /*
*/ in gr _col(43) "->" in ye %8.0g r(k)
end
program define ReportW /* old_obs old_vars */
Report1 `1' `2' long wide
local n : word count $ReS_jv2
local col = 31+(9-length("$ReS_j"))
di in gr "j variable (`n' values)" /*
*/ _col(`col') in ye "$ReS_j" in gr _col(43) "->" /*
*/ _col(48) "(dropped)"
di in gr "xij variables:"
parse "$ReS_Xij", parse(" ")
while "`1'"!="" {
RepF "`1'"
local skip = 39 - length("$S_2")
di in ye _skip(`skip') "$S_2" _col(43) in gr "->" /*
*/ in ye _col(48) "$S_1"
mac shift
}
di in smcl in gr "{hline 77}"
end
program define Simple /* {wide|long} <funnylist>, i(varlist)
[j(varname [values])] */
local cmd "`1'"
mac shift
parse "`*'", parse(" ,")
while "`1'"!="" & "`1'"!="," {
local list `list' `1'
mac shift
}
if "`list'"=="" {
error 198
}
if "`1'" != "," {
di in red "option i() required"
exit 198
}
local options "I(string) J(string) ATwl(string) String"
parse "`*'"
if "`i'"=="" {
di in red "option i() required"
exit 198
}
unabbrev `i'
local i "`s(varlist)'"
if "`j'" != "" {
parse "`j'", parse(" ")
local jvar "`1'"
mac shift
local jvals "`*'"
}
else local jvar "_j"
if "`cmd'"=="wide" {
/* When reshaping wide we can -unab- the variable list */
capture unab list : `list' /* ignore _rc, error caught later */
/* When reshaping wide we can -unab- the j variable */
capture unab jvar : `jvar' /* use -unab- not -ConfVar- here */
/* old code
capture ConfVar `jvar'
*/
if _rc {
if _rc==111 {
di in red "`jvar' not found -- " _c
if "`jvar'"=="_j" {
di in red "specify j() option"
}
else di in red "data already wide"
exit 111
}
ConfVar `jvar'
exit 198 /* just in case */
}
}
else {
capture confirm new var `jvar'
if _rc {
if _rc==110 {
di in red /*
*/ "`jvar' already defined -- data already long"
exit 110
}
confirm new var `jvar'
exit 198 /* just in case */
}
}
if "`atwl'"!="" {
local atwl "atwl(`atwl')"
}
if "`string'" != "" {
local string ", string"
}
reshape clear
reshape i `i'
reshape j `jvar' `jvals' `string'
reshape xij `list' `atwl'
end
program define Xij /* <names-maybe-with-@>[, atwl(string) */
if "`*'"=="" { error 198 }
parse "`*'", parse(" ,")
while "`1'" != "" & "`1'"!="," {
local list "`list' `1'"
mac shift
}
if "`list'"=="" {
error 198
}
local list `list'
if "`1'"=="," {
local options "ATwl(string)"
parse "`*'"
}
char _dta[ReS_Xij] "`list'"
char _dta[ReS_atwl] "`atwl'"
end
program define DoOld
local c "`1'"
local l = length("`c'")
mac shift
if "`c'"==substr("groups",1,`l') {
if "`2'" == "" {
error 198
}
DoNew j `*'
exit
}
if "`c'"==substr("vars",1,`l') {
DoNew xij `*'
exit
}
if "`c'"==substr("cons",1,`l') {
DoNew i `*'
exit
}
if "`c'"==substr("query",1,`l') {
local cons : char _dta[ReS_i]
local grpvar : char _dta[ReS_j]
local values : char _dta[ReS_jv]
local vars : char _dta[ReS_Xij]
local car : char _dta[Res_Xi]
di "group var: `grpvar'"
di "values: `values'"
di "cons: `cons'"
di "vars: `vars'"
exit
}
if "`c'"=="wide" {
DoNew wide `*'
exit
}
if "`c'"=="long" {
DoNew long `*'
exit
}
IfNew `c'
if `s(newflag)' {
di in red "may not mix old and new syntax;"
di in red "either use old syntax or " /*
*/ _quote "reshape clear" _quote /*
*/ " and start over using new syntax."
exit 198
}
error 198
end
program define Query
if "`*'"!="" {
error 198
}
local cons : char _dta[ReS_i]
local grpvar : char _dta[ReS_j]
local values : char _dta[ReS_jv]
local vars : char _dta[ReS_Xij]
local car : char _dta[Res_Xi]
local atwl : char _dta[ReS_atwl]
local isstr : char _dta[ReS_str]
if "`grpvar'"!="" {
capture ConfVar `grpvar'
if _rc {
di _n in ye " (data is wide)"
}
else di _n in ye " (data is long)"
}
else di
if "`cons'"=="" {
local ccons "in gr"
local cons "<varlist>"
}
if "`grpvar'"=="" {
local cgrpvar "in gr"
local grpvar "<varname>"
if "`values'"=="" {
local values "[<#> - <#>]"
}
}
else if `isstr' {
local values "`values', string"
}
if "`vars'"=="" {
local cvars "in gr"
local vars "<varnames-without-#j-suffix>"
}
else {
if "`atwl'" != "" {
local vars "`vars', atwl(`atwl')"
}
}
if "`car'"=="" {
local ccar "in gr"
local car "<varlist>"
}
di in smcl in gr "{c TLC}{hline 30}{c TT}{hline 46}{c TRC}" _n /*
*/ "{c |} Xij" _col(32) "{c |} Command/contents" _col(79) "{c |}" _n /*
*/ in gr "{c LT}{hline 30}{c +}{hline 46}{c RT}"
di in smcl in gr /*
*/ "{c |} Subscript i,j definitions:" _col(32) "{c |}" _col(79) "{c |}"
di in smcl in gr /*
*/ "{c |} group id variable(s)" _col(32) "{c |} reshape i " _c
Qlist 44 "`ccons'" `cons'
di in smcl in gr /*
*/ "{c |} within-group variable" _col(32) "{c |} reshape j " _c
Qlist 44 "`cgrpvar'" `grpvar' `values'
di in smcl in gr /*
*/ "{c |} and its range" _col(32) "{c |}" _col(79) "{c |}"
di in smcl in gr "{c |}" _col(32) "{c |}" _col(79) "{c |}"
di in smcl in gr /*
*/ "{c |} Variable X definitions:" _col(32) "{c |}" _col(79) "{c |}"
di in smcl in gr /*
*/ "{c |} varying within group" _col(32) "{c |} reshape xij " _c
Qlist 46 "`cvars'" `vars'
di in smcl in gr /*
*/ "{c |} constant within group (opt) {c |} reshape xi " _c
Qlist 46 "`ccar'" `car'
di in smcl in gr "{c BLC}{hline 30}{c BT}{hline 46}{c BRC}"
local cons : char _dta[ReS_i]
local grpvar : char _dta[ReS_j]
local values : char _dta[ReS_jv]
local vars : char _dta[ReS_Xij]
local car : char _dta[Res_Xi]
if "`cons'"=="" {
di in gr "First type " _quote in white /*
*/ "reshape i" in gr _quote /*
*/ " to define the i variable."
exit
}
if "`grpvar'"=="" {
di in gr "Type " _quote in wh /*
*/ "reshape j" in gr _quote /*
*/ " to define the j variable and, optionally, values."
exit
}
if "`vars'"=="" {
di in gr "Type " _quote in wh /*
*/ "reshape xij" in gr _quote /*
*/ " to define variables that vary within i."
exit
}
if "`car'"=="" {
di in gr /*
*/ "Optionally type " _quote in wh "reshape xi" in gr _quote /*
*/ " to define variables that are constant within i."
}
capture ConfVar `grpvar'
if _rc {
di in gr "Type " _quote in wh "reshape long" in gr _quote /*
*/ " to convert the data to long form."
exit
}
di in gr "Type " _quote in wh "reshape wide" in gr _quote /*
*/ " to convert the data to wide form."
end
program define Qlist /* col <optcolor> stuff */
local col `1'
local clr "`2'"
mac shift 2
while "`1'" != "" {
local l = length("`1'")
if `col' + `l' + 1 >= 79 {
local skip = 79 - `col'
di in smcl in gr _skip(`skip') "{c |}" _n /*
*/ "{c |}" _col(32) "{c |} " _c
local col 34
}
di in ye `clr' "`1' " _c
local col = `col' + `l' + 1
mac shift
}
local skip = 79 - `col'
di in smcl in gr _skip(`skip') "{c |}"
end
program define Qerror
Macros
Macros2 preserve
capture ConfVar $ReS_j
if _rc==0 {
QerrorW
}
else QerrorL
end
/* ------------------------------------------------------------------------ */
program define Wide /* reshape wide */
local oldobs = _N
quietly describe, short
local oldvars = r(k)
Macros
capture ConfVar $ReS_j
if _rc {
di in blu "(already wide)"
exit
}
ConfVar $ReS_j
confirm var $ReS_j $rVANS $ReS_i $Res_Xi
capture ConfVar _merge
if _rc ==0 {
di in red "cannot convert data containing variable _merge;"
di in red "drop or rename _merge"
exit 110
}
preserve
Macros2
if $S_1 {
restore, preserve
}
ConfVar $ReS_j
confirm var $ReS_j $Res_Xi
Veruniq
/*
Organization:
dataset dscons: (may not exist)
$ReS_i (1 obs per $ReS_i)
$Res_Xi
dataset dsvars:
$ReS_i (many obs per $ReS_i)
$ReS_j
$ReS_Xij
dataset dsnew:
$ReS_i (1 obs per $ReS_i)
<widened $VARS>
<$Res_Xi>
Note, ("`dscons'"!="") == ("$ReS_i"!="")
*/
tempfile dsnew dsvars hold
if "$Res_Xi" != "" {
tempfile dscons
}
quietly {
keep $ReS_j $rVANS $ReS_i $Res_Xi
sort $ReS_i $ReS_j
if "`dscons'"!="" {
save "`dscons'", replace /* temporarily */
drop $Res_Xi
save "`dsvars'", replace
use "`dscons'", clear
}
else save "`dsvars'", replace
by $ReS_i: keep if _n==1
if "`dscons'"!="" {
keep $ReS_i $Res_Xi
save "`dscons'", replace
}
keep $ReS_i
save "`dsnew'", replace
/* datasets initialized, now step through each value: */
globa ReS_jv2
parse "$ReS_jv", parse(" ")
while "`1'" != "" {
use "`dsvars'", clear
if $ReS_str {
keep if $ReS_j=="`1'"
}
else keep if $ReS_j == `1'
if _N==0 {
noi di in bl /*
*/ "(note: no data for $ReS_j == `1')"
capture use "`dsnew'", replace
}
else {
global ReS_jv2 $ReS_jv2 `1'
drop $ReS_j
noisily Widefix `1'
save "`hold'", replace
use "`dsnew'", clear
merge $ReS_i using "`hold'"
drop _merge
sort $ReS_i
save "`dsnew'", replace
}
mac shift
}
if "`dscons'" != "" {
merge $ReS_i using "`dscons'"
drop _merge
}
}
global S_FN
global S_FNDATE
if "`syntax'" != "v.1" {
sort $ReS_i
}
restore, not
local syntax: char _dta[ReS_ver]
if "`syntax'" != "v.1" {
ReportW `oldobs' `oldvars'
}
end
program define Veruniq
sort $ReS_i $ReS_j
capture by $ReS_i $ReS_j: assert _N==1
if _rc {
di in red "$ReS_j not unique within $ReS_i;"
di in red /*
*/ "there are multiple observations at the same $ReS_j" /*
*/ " within $ReS_i."
di in red "Type " _quote "reshape error" _quote /*
*/ " for a listing of the problem observations."
exit 9
}
if "$Res_Xi"=="" {
exit
}
sort $ReS_i $Res_Xi $ReS_j
tempvar cnt1 cnt2
quietly by $ReS_i: gen long `cnt1' = _N
quietly by $ReS_i $Res_Xi: gen long `cnt2' = _N
capture assert `cnt1' == `cnt2'
if _rc==0 {
exit
}
parse "$Res_Xi", parse(" ")
while "`1'"!="" {
capture by $ReS_i: assert `1'==`1'[1]
if _rc {
di in red "`1' not constant within $ReS_i"
}
mac shift
}
di in red "Type " _quote "reshape error" _quote /*
*/ " for a listing of the problem observations."
exit 9
end
program define QerrorW
ConfVar $ReS_j
confirm var $ReS_j $ReS_Xij $ReS_i $Res_Xi
sort $ReS_i $ReS_j
capture by $ReS_i $ReS_j: assert _N==1
if _rc {
Msg1
di in gr /*
*/ "The data are in the long form; j should be unique within i." _n
di in gr /*
*/ "There are multiple observations on the same " /*
*/ in ye "$ReS_j" in gr " within " /*
*/ in ye "$ReS_i" in gr "." _n
tempvar bad
quietly by $ReS_i $ReS_j: gen `bad' = _N!=1
quietly count if `bad'
di in gr /*
*/ "The following " r(N) /*
*/ " out of " _N /*
*/ " observations have repeated $ReS_j values:"
list $ReS_i $ReS_j if `bad'
di in gr _n "(data now sorted by $ReS_i $ReS_j)"
exit
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?