forked from matthieugomez/tidy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spread.ado
146 lines (119 loc) · 3.11 KB
/
spread.ado
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
program define spread
version 12.1
syntax varlist, [variable(varname) value(varname) label(string) fast]
if ("`fast'" == "") preserve
tokenize `varlist'
local variable `1'
local value `2'
if "`value'" == ""{
di as error `"The correct syntax is "spread namevariable valuevariable". The valuevariable is missing."'
exit 4
}
qui{
/* take care of label */
if "`label'" == "" & "`:value label `variable''" ~= ""{
tempvar label
decode `variable', gen(`label')
}
/* create variable`i' and label`i' */
sort `variable'
tempvar bylength
bys `variable' : gen double `bylength' = _N
local start = 1
local i = 0
while `start' <= _N {
local i = `i' + 1
local end = `start' + `=`bylength'[`start']' - 1
local variable_levels `"`variable_levels' `"`=`variable'[`start']'"'"'
if "`label'" ~= ""{
local label_levels `"`label_levels' `"`=`label'[`start']'"'"'
}
local start = `end' + 1
}
local n = `i'
ds `variable' `value' `label' `bylength' , not
local ivar `r(varlist)'
if "`ivar'" == ""{
tempvar newivar
gen `newivar' = _N
local ivar `newivar'
}
cap confirm string variable `variable'
if _rc{
local string ""
}
else{
local string string
tempvar temp
gen `temp' = !regexm(`variable',"^[a-zA-Z_]*[a-zA-Z\_0-9]*$")
count if `temp' == 1
if `r(N)' > 0 {
levelsof `variable' if `temp' == 1
display as error `"Some observations for `variable' don't have valid variable names: `=r(levels)'"'
exit 4
}
foreach v in `ivar'{
local i : list posof "`v'" in variable_levels
if `i' ~= 0{
display as error `"The value `v' for the variable "`variable'" conflicts with existing variables"'
exit 4
}
}
}
/* manage when more than 10 id variables */
loca ni `:word count `ivar''
if `ni' > 10{
tempvar id
bys `ivar': gen `id' = 1
qui replace `id' = sum(`id')
local i `id'
}
else{
local i `ivar'
}
/* reshape */
drop `bylength' `label'
cap which greshape
if _rc == 0{
local reshape greshape
}
else{
local reshape reshape
}
qui `reshape' wide `value', i(`i') j(`variable') `string' `fast'
/* check all new variable names are valid new variable name */
if "`string'" == ""{
local change "no"
}
else{
forval i = 1/`n'{
local v : word `i' of `variable_levels'
cap confirm new variable `v'
if _rc{
di as error "`value'`v'"
local change "no"
}
}
}
forval i = 1/`n'{
local v : word `i' of `variable_levels'
if "`change'" != "no"{
rename `value'`v' `v'
local names `names' `v'
if "`label'" ~= ""{
local l : word `i' of `label_levels'
label variable `v' `"`l'"'
}
}
else{
local names `names' `value'`v'
if "`label'" ~= ""{
local l : word `i' of `label_levels'
label variable `value'`v' `"`l'"'
}
}
}
di as result "new variables created: " as text "`=subinstr("`names'", " ", ", ", .)'"
}
if ("`fast'" == "") cap restore, not
end