-
Notifications
You must be signed in to change notification settings - Fork 77
/
iebaltab.ado
2884 lines (2091 loc) · 96.2 KB
/
iebaltab.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*! version 5.5 26APR2018 DIME Analytics lcardosodeandrad@worldbank.org
capture program drop iebaltab
program iebaltab
syntax varlist(numeric) [if] [in], ///
///
/*Group variable*/ ///
GRPVar(varname) ///
///
[ ///
/*Columns and order of columns*/ ///
ORder(numlist int min=1) ///
COntrol(numlist int max=1) ///
TOTal ///
///
/*Column and row labels*/ ///
GRPCodes ///
GRPLabels(string) ///
TOTALLabel(string) ///
ROWVarlabels ///
ROWLabels(string) ///
onerow ///
onenrow ///
///
/*Statistics and data manipulation*/ ///
FIXedeffect(varname) ///
COVariates(varlist) ///
COVARMISSOK ///
vce(string) ///
BALMISS(string) ///
BALMISSReg(string) ///
COVMISS(string) ///
COVMISSReg(string) ///
MISSMINmean(numlist min=1 max=1 >0) ///
weight(string) ///
///
/*F-test*/ ///
FTest ///
FMissok ///
FNOOBS ///
///
/*Output display*/ ///
NOTtest ///
NORMDiff ///
PTtest ///
PFtest ///
FEQTest ///
PBoth ///
STDev ///
STARlevels(numlist descending min=3 max=3 >0 <1) ///
STARSNOadd ///
FORMat(string) ///
TBLNote(string) ///
NOTECombine ///
TBLNONote ///
///
/*Export and restore*/ ///
SAVE(string) ///
SAVETex(string) ///
TEXNotewidth(numlist min=1 max=1) ///
TEXCaption(string) ///
TEXLabel(string) ///
TEXDOCument ///
texvspace(string) ///
texcolwidth(string) ///
BROWSE ///
SAVEBRowse ///
REPLACE ///
]
********POTENTIAL UPDATES*********
*1. Implement option for bootstrap
********HELPFILE TODO*********
*1. Explain difference in se between group by itself and the standard errors used in the t-test
preserve
qui {
*Set minimum version for this command
version 11
*Remove observations excluded by if and in
if ("`if'`in'"!="") {
keep `if' `in'
}
if 1 {
/***********************************************
************************************************
Set initial constants
*************************************************
************************************************/
*Create local for balance vars with more descriptive name
local balancevars `varlist'
** Column Options
*Is option control() used:
if "`control'" == "" local CONTROL_USED = 0
if "`control'" != "" local CONTROL_USED = 1
*Is option order() used:
if "`order'" == "" local ORDER_USED = 0
if "`order'" != "" local ORDER_USED = 1
*Is option grpcodes used:
if "`grpcodes'" == "" local NOGRPLABEL_USED = 0
if "`grpcodes'" != "" local NOGRPLABEL_USED = 1
*Is option nolabel used:
if "`grplabels'" == "" local GRPLABEL_USED = 0
if "`grplabels'" != "" local GRPLABEL_USED = 1
*Is option total() used:
if "`total'" == "" local TOTAL_USED = 0
if "`total'" != "" local TOTAL_USED = 1
*Is option totallable() used:
if "`totallabel'" == "" local TOTALLABEL_USED = 0
if "`totallabel'" != "" local TOTALLABEL_USED = 1
** Row Options
*Is option total() used:
if "`rowvarlabels'" == "" local ROWVARLABEL_USED = 0
if "`rowvarlabels'" != "" local ROWVARLABEL_USED = 1
*Is option totallable() used:
if "`rowlabels'" == "" local ROWLABEL_USED = 0
if "`rowlabels'" != "" local ROWLABEL_USED = 1
*Is option totallable() used:
if "`onenrow'" != "" local onerow = "onerow" //Old name still supported for backward compatibility
if "`onerow'" == "" local ONEROW_USED = 0
if "`onerow'" != "" local ONEROW_USED = 1
** Stats Options
*Is option ftest used:
if "`ftest'" == "" local FTEST_USED = 0
if "`ftest'" != "" local FTEST_USED = 1
*Is option fmiss used:
if "`fmissok'" == "" local F_MISS_OK = 0
if "`fmissok'" != "" local F_MISS_OK = 1
*Is option fnoobs used:
if "`fnoobs'" == "" local F_NO_OBS = 0
if "`fnoobs'" != "" local F_NO_OBS = 1
*Is option fixedeffect() used:
if "`fixedeffect'" == "" local FIX_EFFECT_USED = 0
if "`fixedeffect'" != "" local FIX_EFFECT_USED = 1
*Is option covariates() used:
if "`covariates'" == "" local COVARIATES_USED = 0
if "`covariates'" != "" local COVARIATES_USED = 1
*Is option covarmissok used:
if "`covarmissok'" == "" local COVARMISSOK_USED = 0
if "`covarmissok'" != "" local COVARMISSOK_USED = 1
*Is option cluster() used:
if "`vce'" == "" local VCE_USED = 0
if "`vce'" != "" local VCE_USED = 1
*Is option balmiss() used:
if "`balmiss'" == "" local BALMISS_USED = 0
if "`balmiss'" != "" local BALMISS_USED = 1
*Is option missreg() used:
if "`balmissreg'" == "" local BALMISSREG_USED = 0
if "`balmissreg'" != "" local BALMISSREG_USED = 1
*Is option covmiss() used:
if "`covmiss'" == "" local COVMISS_USED = 0
if "`covmiss'" != "" local COVMISS_USED = 1
*Is option covmissreg() used:
if "`covmissreg'" == "" local COVMISSREG_USED = 0
if "`covmissreg'" != "" local COVMISSREG_USED = 1
*Is option missminmean() used:
if "`missminmean'" == "" local MISSMINMEAN_USED = 0
if "`missminmean'" != "" local MISSMINMEAN_USED = 1
*Is option starlevels() used:
if "`starlevels'" == "" local STARLEVEL_USED = 0
if "`starlevels'" != "" local STARLEVEL_USED = 1
*Is option starsnoadd used:
if "`starsnoadd'" == "" local STARSNOADD_USED = 0
if "`starsnoadd'" != "" local STARSNOADD_USED = 1
*Is option nottest used:
if "`nottest'" == "" local TTEST_USED = 1
if "`nottest'" != "" local TTEST_USED = 0
*Is option pttest() used:
if "`pttest'" == "" local PTTEST_USED = 0
if "`pttest'" != "" local PTTEST_USED = 1
*Is option pftest() used:
if "`pftest'" == "" local PFTEST_USED = 0
if "`pftest'" != "" local PFTEST_USED = 1
*Is option pboth() used:
if "`pboth'" == "" local PBOTH_USED = 0
if "`pboth'" != "" local PBOTH_USED = 1
if `PBOTH_USED' == 1 local PTTEST_USED = 1
if `PBOTH_USED' == 1 local PFTEST_USED = 1
*Is option pftest() used:
if "`stdev'" == "" local STDEV_USED = 0
if "`stdev'" != "" local STDEV_USED = 1
*Is option weight() used:
if "`weight'" == "" local WEIGHT_USED = 0
if "`weight'" != "" local WEIGHT_USED = 1
*Is option feqtest() user:
if "`feqtest'" == "" local FEQTEST_USED = 0
if "`feqtest'" != "" local FEQTEST_USED = 1
*Is option normdiff() used:
if "`normdiff'" == "" local NORMDIFF_USED = 0
if "`normdiff'" != "" local NORMDIFF_USED = 1
** Output Options
*Is option format() used:
if "`format'" == "" local FORMAT_USED = 0
if "`format'" != "" local FORMAT_USED = 1
*Is option save() used:
if "`save'" == "" local SAVE_USED = 0
if "`save'" != "" local SAVE_USED = 1
*Is option savetex() used:
if "`savetex'" == "" local SAVE_TEX_USED = 0
if "`savetex'" != "" local SAVE_TEX_USED = 1
*Is option texnotewidth() used:
if "`texnotewidth'" == "" local NOTEWIDTH_USED = 0
if "`texnotewidth'" != "" local NOTEWIDTH_USED = 1
*Is option texnotewidth() used:
if "`texcaption'" == "" local CAPTION_USED = 0
if "`texcaption'" != "" local CAPTION_USED = 1
*Is option texnotewidth() used:
if "`texlabel'" == "" local LABEL_USED = 0
if "`texlabel'" != "" local LABEL_USED = 1
*Is option texdocument() used:
if "`texdocument'" == "" local TEXDOC_USED = 0
if "`texdocument'" != "" local TEXDOC_USED = 1
*Is option texlinespace() used:
if "`texvspace'" == "" local TEXVSPACE_USED = 0
if "`texvspace'" != "" local TEXVSPACE_USED = 1
*Is option texcolwidth() used:
if "`texcolwidth'" == "" local TEXCOLWIDTH_USED = 0
if "`texcolwidth'" != "" local TEXCOLWIDTH_USED = 1
*Is option browse() used:
if "`browse'" == "" local BROWSE_USED = 0
if "`browse'" != "" local BROWSE_USED = 1
*Is option restore() used:
if "`savebrowse'" == "" local SAVE_BROWSE_USED = 0
if "`savebrowse'" != "" local SAVE_BROWSE_USED = 1
*Is option restore() used:
if "`replace'" == "" local REPLACE_USED = 0
if "`replace'" != "" local REPLACE_USED = 1
*Is option tablenote() used:
if "`tblnote'" == "" local NOTE_USED = 0
if "`tblnote'" != "" local NOTE_USED = 1
*Is option notecombine() used:
if "`notecombine'" == "" local NOTECOMBINE_USED = 0
if "`notecombine'" != "" local NOTECOMBINE_USED = 1
*Is option notablenote() used:
if "`tblnonote'" == "" local NONOTE_USED = 0
if "`tblnonote'" != "" local NONOTE_USED = 1
/***********************************************
************************************************
Prepare a list of group variables
*************************************************
************************************************/
cap confirm numeric variable `grpvar'
if _rc != 0 {
*Test for commands not allowed if grpvar is a string variable
if `CONTROL_USED' == 1 {
di as error "{pstd}The option control() can only be used if variable {it:`grpvar'} is a numeric variable. Use {help encode} to generate a numeric version of variable {it:`grpvar'}. It is best practice to store all categorical variables as labeled numeric variables.{p_end}"
error 198
}
if `ORDER_USED' == 1 {
di as error "{pstd}The option order() can only be used if variable {it:`grpvar'} is a numeric variable. Use {help encode} to generate a numeric version of variable {it:`grpvar'}. It is best practice to store all categorical variables as labeled numeric variables.{p_end}"
error 198
}
if `NOGRPLABEL_USED' == 1 {
di as error "{pstd}The option grpcodes can only be used if variable {it:`grpvar'} is a numeric variable. Use {help encode} to generate a numeric version of variable {it:`grpvar'}. It is best practice to store all categorical variables as labeled numeric variables.{p_end}"
error 198
}
if `GRPLABEL_USED' == 1 {
di as error "{pstd}The option grplabels() can only be used if variable {it:`grpvar'} is a numeric variable. Use {help encode} to generate a numeric version of variable {it:`grpvar'}. It is best practice to store all categorical variables as labeled numeric variables.{p_end}"
error 198
}
*Generate a encoded tempvar version of grpvar
tempvar grpvar_code
encode `grpvar' , gen(`grpvar_code')
*replace the grpvar local so that it uses the tempvar instead
local grpvar `grpvar_code'
}
*Remove observations with a missing value in grpvar()
drop if `grpvar' >= .
*Create a local of all codes in group variable
levelsof `grpvar', local(GRP_CODE_LEVELS)
*Saving the name of the value label of the grpvar()
local GRPVAR_VALUE_LABEL : value label `grpvar'
*Counting how many levels there are in groupvar
local GRPVAR_NUM_GROUPS : word count `GRP_CODE_LEVELS'
*Static dummy for grpvar() has no label
if "`GRPVAR_VALUE_LABEL'" == "" local GRPVAR_HAS_VALUE_LABEL = 0
if "`GRPVAR_VALUE_LABEL'" != "" local GRPVAR_HAS_VALUE_LABEL = 1
*Number of columns for Latex
local NUM_COL_GRP_TOT = `GRPVAR_NUM_GROUPS' + `TOTAL_USED'
/***********************************************
************************************************/
*Testing that options to iebaltab is correctly specified and make initial operations based on these commands
/*************************************************
************************************************/
** Group Options
cap confirm numeric variable `grpvar'
if _rc != 0 {
noi display as error "{phang}The variable listed in grpvar(`grpvar') is not a numeric variable. See {help encode} for options on how to make a categorical string variable into a categorical numeric variable{p_end}"
error 108
}
else {
** Testing that groupvar is a categorical variable. Int() rounds to
* integer, and if any values are non-integers then (int(`grpvar') == `grpvar) is
* not true
cap assert ( int(`grpvar') == `grpvar' )
if _rc == 9 {
noi display as error "{phang}The variable in grpvar(`grpvar') is not a categorical variable. The variable may only include integers where each integer indicates which group each observation belongs to. See tabulation of `grpvar' below:{p_end}"
noi tab `grpvar', nol
error 109
}
}
** Column Options
** If control() or order() is used, then the levels specified in those
* options need to exist in the groupvar
local control_correct : list control in GRP_CODE_LEVELS
if `control_correct' == 0 {
noi display as error "{phang}The code listed in control(`control') is not used in grpvar(`grpvar'). See tabulation of `grpvar' below:"
noi tab `grpvar', nol
error 197
}
local order_correct : list order in GRP_CODE_LEVELS
if `order_correct' == 0 {
noi display as error "{phang}One or more codes listed in order(`order') are not used in grpvar(`grpvar'). See tabulation of `grpvar' below:"
noi tab `grpvar', nol
error 197
}
if `GRPLABEL_USED' == 1 {
local col_labels_to_tokenize `grplabels'
while "`col_labels_to_tokenize'" != "" {
*Parsing code and label pair
gettoken codeAndLabel col_labels_to_tokenize : col_labels_to_tokenize, parse("@")
*Splitting code and label
gettoken code label : codeAndLabel
*** Codes
*Checking that code exist in grpvar and store it
local code_correct : list code in GRP_CODE_LEVELS
if `code_correct' == 0 {
noi display as error "{phang}Code [`code'] listed in grplabels(`grplabels') is not used in grpvar(`grpvar'). See tabulation of `grpvar' below:"
noi tab `grpvar', nol
error 198
}
*Storing the code in local to be used later
local grpLabelCodes `"`grpLabelCodes' "`code'" "'
*** Labels
*Removing leadning or trailing spaces
local label = trim("`label'")
*Testing that no label is missing
if "`label'" == "" {
noi display as error "{phang}For code [`code'] listed in grplabels(`grplabels') you have not specified any label. Labels are requried for all codes listed in grplabels(). See tabulation of `grpvar' below:"
noi tab `grpvar', nol
error 198
}
*Storing the label in local to be used later
local grpLabelLables `"`grpLabelLables' "`label'" "'
*Parse char is not removed by gettoken
local col_labels_to_tokenize = subinstr("`col_labels_to_tokenize'" ,"@","",1)
}
}
if `ROWLABEL_USED' {
*** Test the validity for the rowlabel input
*Create a local with the rowlabel input to be tokenized
local row_labels_to_tokenize `rowlabels'
while "`row_labels_to_tokenize'" != "" {
*Parsing name and label pair
gettoken nameAndLabel row_labels_to_tokenize : row_labels_to_tokenize, parse("@")
*Splitting name and label
gettoken name label : nameAndLabel
*** Variable names
*Checking that the variables used in rowlabels() are included in the table
local name_correct : list name in balancevars
if `name_correct' == 0 {
noi display as error "{phang}Variable [`name'] listed in rowlabels(`rowlabels') is not found among the variables included in the balance table."
error 111
}
*Storing the code in local to be used later
local rowLabelNames `"`rowLabelNames' "`name'" "'
*** Variable labels
*Removing leading or trailing spaces
local label = trim("`label'")
*Testing that no label is missing
if "`label'" == "" {
noi display as error "{phang}For variable [`name'] listed in rowlabels(`rowlabels') you have not specified any label. Labels are requried for all variables listed in rowlabels(). The variable name itself will be used for any variables omitted from rowlabels(). See also option {help dmtab:rowvarlabels}"
noi tab `grpvar', nol
error 198
}
*Storing the label in local to be used later
local rowLabelLabels `"`rowLabelLabels' "`label'" "'
*Parse char is not removed by gettoken
local row_labels_to_tokenize = subinstr("`row_labels_to_tokenize'" ,"@","",1)
}
}
if `TOTALLABEL_USED' & !`TOTAL_USED' {
*Error for totallabel() incorrectly applied
noi display as error "{phang}Option totallabel() may only be used together with the option total"
error 197
}
** Stats Options
local SHOW_NCLUSTER 0
if `VCE_USED' == 1 {
local vce_nocomma = subinstr("`vce'", "," , " ", 1)
tokenize "`vce_nocomma'"
local vce_type `1'
if "`vce_type'" == "robust" {
*Robust is allowed and not other tests needed
}
else if "`vce_type'" == "cluster" {
*Create a local for displaying number of clusters
local SHOW_NCLUSTER 1
local cluster_var `2'
cap confirm variable `cluster_var'
if _rc {
*Error for vce(cluster) incorrectly applied
noi display as error "{phang}The cluster variable in vce(`vce') does not exist or is invalid for any other reason. See {help vce_option :help vce_option} for more information. "
error _rc
}
}
else if "`vce_type'" == "bootstrap" {
*bootstrap is allowed and not other tests needed. Error checking is more comlex, add tests here in the future.
}
else {
*Error for vce() incorrectly applied
noi display as error "{phang}The vce type `vce_type' in vce(`vce') is not allowed. Only robust, cluster and bootstrap is allowed. See {help vce_option :help vce_option} for more information."
error 198
}
}
if `STARSNOADD_USED' == 0 {
*Allow user defined p-values for stars or set the default values
if `STARLEVEL_USED' == 1 {
*Tokenize the string with the p-values entered by the user. The value entered are tested in syntax
tokenize "`starlevels'"
*Set user defined levels for 1, 2 and 3 stars
local p1star `1'
local p2star `2'
local p3star `3'
}
else {
*Set default levels for 1, 2 and 3 stars
local p1star .1
local p2star .05
local p3star .01
}
** Create locals with the values expressed
* as percentages for the note to the table
local p1star_percent = `p1star' * 100
local p2star_percent = `p2star' * 100
local p3star_percent = `p3star' * 100
}
else {
*Options starsomitt is used. No stars will be displayed. By setting
*these locals to nothing the loop adding stars will not be iterated
local p1star
local p2star
local p3star
}
*Error for starlevels incorrectly used together with starsnoadd
if `STARSNOADD_USED' & `STARLEVEL_USED' {
*Error for starlevels and starsnoadd incorrectly used together
noi display as error "{phang}Option starlevels() may not be used in combination with option starsnoadd"
error 197
}
*Error for miss incorrectly used together with missreg
if `BALMISS_USED' & `BALMISSREG_USED' {
*Error for balmiss and balmissreg incorrectly used together
noi display as error "{phang}Option balmiss() may not be used in combination with option balmissreg()"
error 197
}
if `COVMISS_USED' & `COVMISSREG_USED' {
*Error for covmiss and covmissreg incorrectly used together
noi display as error "{phang}Option covmiss() may not be used in combination with option covmissreg()"
error 197
}
if !`TTEST_USED' {
if `PTTEST_USED' {
*Error for nottest and pttest incorrectly used together
noi display as error "{phang}Option pttest may not be used in combination with option nottest"
error 197
}
if `PBOTH_USED' {
*Error for nottest and pboth incorrectly used together
noi display as error "{phang}Option pboth may not be used in combination with option nottest"
error 197
}
}
if `FTEST_USED' & !`TTEST_USED' & !`NORMDIFF_USED' {
*Error for F-test used, but not t-test of normalized difference:
*no columns are created for F-test to be displayed
noi di as error "{phang}Option ftest may not only be used if either t-tests or normalized differences are used. F-test for joing significance of balance variables will not be displayed. In order to display it, either use option normdiff or remove option nottest.{p_end}"
local FTEST_USED = 0
}
*Testing input in these for options. See function at the end of this command
if `BALMISS_USED' == 1 iereplacestringtest "balmiss" "`balmiss'"
if `BALMISSREG_USED' == 1 iereplacestringtest "balmissreg" "`balmissreg'"
if `COVMISS_USED' == 1 iereplacestringtest "covmiss" "`covmiss'"
if `COVMISSREG_USED' == 1 iereplacestringtest "covmissreg" "`covmissreg'"
if `FIX_EFFECT_USED' == 1 {
cap assert `fixedeffect' < .
if _rc == 9 {
noi display as error "{phang}The variable in fixedeffect(`fixedeffect') is missing for some observations. This would cause observations to be dropped in the estimation regressions. See tabulation of `fixedeffect' below:{p_end}"
noi tab `fixedeffect', m
error 109
}
}
* test covariate variables
if `COVARIATES_USED' == 1 {
foreach covar of local covariates {
*Create option string
local replaceoptions
*Sopecify differently based on all missing or only regualr missing
if `COVMISS_USED' local replaceoptions `" `replaceoptions' replacetype("`covmiss'") "'
if `COVMISSREG_USED' local replaceoptions `" `replaceoptions' replacetype("`covmissreg'") regonly "'
*Add group variable if the replace type is group mean
if "`covmiss'" == "groupmean" local replaceoptions `" `replaceoptions' groupvar(`grpvar') groupcodes("`GRP_CODE_LEVELS'") "'
if "`covmissreg'" == "groupmean" local replaceoptions `" `replaceoptions' groupvar(`grpvar') groupcodes("`GRP_CODE_LEVELS'") "'
*Set the minimum number of observations to allow means to be set from
if `MISSMINMEAN_USED' == 1 local replaceoptions `" `replaceoptions' minobsmean(`missminmean') "'
if `MISSMINMEAN_USED' == 0 local replaceoptions `" `replaceoptions' minobsmean(10) "'
*Excute the command. Code is found at the bottom of this ado file
if (`COVMISS_USED' | `COVMISSREG_USED') iereplacemiss `covancevar', `replaceoptions'
if `COVARMISSOK_USED' != 1 {
cap assert `covar' < .
if _rc == 9 {
noi display as error "{phang}The variable `covar' specified in covariates() has missing values for one or several observations. This would cause observations to be dropped in the estimation regressions. To allow for observations to be dropped see option covarmissok and to make the command treat missing values as zero see option covmiss() and covmissreg(). Click {stata tab `covar' `if' `in', m} to see the missing values.{p_end}"
error 109
}
}
}
}
if `WEIGHT_USED' == 1 {
* Parsing weight options
gettoken weight_type weight_var : weight, parse("=")
* Parsing keeps the separating character
local weight_var : subinstr local weight_var "=" ""
* Test is weight type specified is valie
local weight_options "fweights pweights aweights iweights fw freq weight pw aw iw"
if `:list weight_type in weight_options' == 0 {
noi display as error "{phang} The option `weight_type' specified in weight() is not a valid weight option. Weight options are: fweights, fw, freq, weight, pweights, pw, aweights, aw, iweights, and iw. {p_end}"
error 198
}
* Test is weight variable specified if valid
capture confirm variable `weight_var'
if _rc {
noi display as error "{phang} The option `weight_var' specified in weight() is not a variable. {p_end}"
error 198
}
}
** Output Options
** If the format option is specified, then test if there is a valid format specified
if `FORMAT_USED' == 1 {
** Creating a numeric mock variable that we attempt to apply the format
* to. This allows us to piggy back on Stata's internal testing to be
* sure that the format specified is at least one of the valid numeric
* formats in Stata
tempvar formattest
gen `formattest' = 1
cap format `formattest' `format'
if _rc == 120 {
di as error "{phang}The format specified in format(`format') is not a valid Stata format. See {help format} for a list of valid Stata formats. This command only accept the f, fc, g, gc and e format.{p_end}"
error 120
}
else if _rc != 0 {
di as error "{phang}Something unexpected happened related to the option format(`format'). Make sure that the format you specified is a valid format. See {help format} for a list of valid Stata formats. If this problem remains, please report this error to kbjarkefur@worldbank.org.{p_end}"
error _rc
}
else {
** We know here that the format is one of the numeric formats that Stata allows
local fomrmatAllowed 0
local charLast = substr("`format'", -1,.)
local char2Last = substr("`format'", -2,.)
if "`charLast'" == "f" | "`charLast'" == "e" {
local fomrmatAllowed 1
}
else if "`charLast'" == "g" {
if "`char2Last'" == "tg" {
*format tg not allowed. all other valid formats ending on g are allowed
local fomrmatAllowed 0
}
else {
*Formats that end in g that is not tg can only be g which is allowed.
local fomrmatAllowed 1
}
}
else if "`charLast'" == "c" {
if "`char2Last'" != "gc" & "`char2Last'" != "fc" {
*format ends on c but is neither fc nor gc
local fomrmatAllowed 0
}
else {
*Formats that end in c that are either fc or gc are allowed.
local fomrmatAllowed 1
}
}
else {
*format is neither f, fc, g, gc nor e
local fomrmatAllowed 0
}
if `fomrmatAllowed' == 0 {
di as error "{phang}The format specified in format(`format') is not allowed. Only format f, fc, g, gc and e are allowed. See {help format} for details on Stata formats.{p_end}"
error 120
}
*If format passed all tests, store it in the local used for display formats
local diformat = "`format'"
}
}
else {
*Default value if fomramt not specified
local diformat = "%9.3f"
}
*Error for tblnonote incorrectly used together with notecombine
if `NOTECOMBINE_USED' & `NONOTE_USED' {
*Error for tblnonote incorrectly used together with notecombine
noi display as error "{phang}Option tblnonote may not be used in combination with option notecombine"
error 197
}
if `SAVE_USED' | `SAVE_TEX_USED' {
if `SAVE_USED' {
**Find the last . in the file path and assume that
* the file extension is what follows. If a file path has a . then
* the file extension must be explicitly specified by the user.
*Copy the full file path to the file suffix local
local file_suffix = "`save'"
** Find index for where the file type suffix start
local dot_index = strpos("`file_suffix'",".")
*If no dot then no file extension
if `dot_index' == 0 local file_suffix ""
**If there is one or many . in the file path than loop over
* the file path until we have found the last one.
while `dot_index' > 0 {
*Extract the file index
local file_suffix = substr("`file_suffix'", `dot_index' + 1, .)
*Find index for where the file type suffix start
local dot_index = strpos("`file_suffix'",".")
}
*If no file format suffix is specified, use the default .xlsx
if "`file_suffix'" == "" {
local save `"`save'.xlsx"'
}
*If a file format suffix is specified make sure that it is one of the two allowed.
else if !("`file_suffix'" == "xls" | "`file_suffix'" == "xlsx") {
noi display as error "{phang}The file format specified in save(`save') is other than .xls or .xlsx. Only those two formats are allowed. If no format is specified .xlsx is the default. If you have a . in your file path, for example in a folder name, then you must specify the file extension .xls or .xlsx.{p_end}"
error 198
}
}
if `SAVE_TEX_USED' {
**Find the last . in the file path and assume that
* the file extension is what follows. If a file path has a . then
* the file extension must be explicitly specified by the user.
*Copy the full file path to the file suffix local
local tex_file_suffix = "`savetex'"
** Find index for where the file type suffix start
local tex_dot_index = strpos("`tex_file_suffix'",".")
*If no dot then no file extension
if `tex_dot_index' == 0 local tex_file_suffix ""
**If there is one or many . in the file path than loop over
* the file path until we have found the last one.
while `tex_dot_index' > 0 {
*Extract the file index
local tex_file_suffix = substr("`tex_file_suffix'", `tex_dot_index' + 1, .)
*Find index for where the file type suffix start
local tex_dot_index = strpos("`tex_file_suffix'",".")
}
*If no file format suffix is specified, use the default .tex
if "`tex_file_suffix'" == "" {
local savetex `"`savetex'.tex"'
}
*If a file format suffix is specified make sure that it is one of the two allowed.
else if !("`tex_file_suffix'" == "tex" | "`tex_file_suffix'" == "txt") {
noi display as error "{phang}The file format specified in savetex(`savetex') is other than .tex or .txt. Only those two formats are allowed. If no format is specified .tex is the default. If you have a . in your file path, for example in a folder name, then you must specify the file extension .tex or .txt.{p_end}"
error 198
}
if `CAPTION_USED' {
* Make sure special characters are displayed correctly
local texcaption : subinstr local texcaption "%" "\%" , all
local texcaption : subinstr local texcaption "_" "\_" , all
local texcaption : subinstr local texcaption "&" "\&" , all
}
}
}
else if `SAVE_BROWSE_USED' {
noi display as error "{phang}Option savepreserve may only be used in combination with option save(){p_end}"
error 198
}
* Check tex options
if `SAVE_TEX_USED' {
* Note width must be positive
if `NOTEWIDTH_USED' {
if `texnotewidth' <= 0 {
noi display as error `"{phang}The value specified in texnotewidth(`texnotewidth') is non-positive. Only positive numbers are allowed. For more information, {net "from http://en.wikibooks.org/wiki/LaTeX/Lengths.smcl":check LaTeX lengths manual}.{p_end}"'
error 198
}
}
* Tex label must be a single word
if `LABEL_USED' {
local label_words : word count `texlabel'
if `label_words' != 1 {
noi display as error `"{phang}The value specified in texlabel(`texlabel') is not allowed. For more information, {browse "https://en.wikibooks.org/wiki/LaTeX/Labels_and_Cross-referencing":check LaTeX labels manual}.{p_end}"'
error 198
}
}
if (`LABEL_USED' | `CAPTION_USED') {
if `TEXDOC_USED' == 0 {
noi display as error "{phang}Options texlabel and texcaption may only be used in combination with option texdocument {p_end}"
error 198
}
}
if `TEXCOLWIDTH_USED' {
* Test if width unit is correctly specified
local texcolwidth_unit = substr("`texcolwidth'",-2,2)
if !inlist("`texcolwidth_unit'","cm","mm","pt","in","ex","em") {
noi display as error `"{phang}Option texcolwidth is incorrectly specified. Column width unit must be one of "cm", "mm", "pt", "in", "ex" or "em". For more information, {browse "https://en.wikibooks.org/wiki/LaTeX/Lengths":check LaTeX lengths manual}.{p_end}"'
error 198
}
* Test if width value is correctly specified
local texcolwidth_value = subinstr("`texcolwidth'","`texcolwidth_unit'","",.)
capture confirm number `texcolwidth_value'
if _rc & inlist("`texcolwidth_unit'","cm","mm","pt","in","ex","em") {
noi display as error "{phang}Option texcolwidth is incorrectly specified. Column width value must be numeric. See {help iebaltab:iebaltab help}. {p_end}"
error 198
}
}
if `TEXVSPACE_USED' {
* Test if width unit is correctly specified
local vspace_unit = substr("`texvspace'",-2,2)
if !inlist("`vspace_unit'","cm","mm","pt","in","ex","em") {
noi display as error `"{phang}Option texvspace is incorrectly specified. Vertical space unit must be one of "cm", "mm", "pt", "in", "ex" or "em". For more information, {browse "https://en.wikibooks.org/wiki/LaTeX/Lengths":check LaTeX lengths manual}.{p_end}"'
error 198
}
* Test if width value is correctly specified
local vspace_value = subinstr("`texvspace'","`vspace_unit'","",.)
capture confirm number `vspace_value'
if _rc & inlist("`vspace_unit'","cm","mm","pt","in","ex","em") {
noi display as error "{phang}Option texvspace is incorrectly specified. Vertical space value must be numeric. See {help iebaltab:iebaltab help}. {p_end}"
error 198
}
}
}
* Error for incorrectly using tex options
else if `NOTEWIDTH_USED' | `LABEL_USED' | `CAPTION_USED' | `TEXDOC_USED' | `TEXVSPACE_USED' | `TEXCOLWIDTH_USED' {
noi display as error "{phang}Options texnotewidth, texdocument, texlabel, texcaption, texvspace and texcolwidth may only be used in combination with option savetex(){p_end}"
error 198
}
*At least one of save and browse may be used
if (`SAVE_USED' + `BROWSE_USED' + `SAVE_TEX_USED' < 1) {
*Error for incorrectly using both save() and browse
noi display as error "{phang}Either option save() or option savetex() or option browse must be used. Note that option browse drops all data in memory and it is not possible to restore it afterwards. Use preserve/restore, tempfiles or save data to disk before using the otion browse."
error
}
/***********************************************
************************************************/
*Manage order in levels of grpvar()
/*************************************************
************************************************/
*Changed to value used in control() if control() is
*specified but order() is not,
if !`ORDER_USED' & `CONTROL_USED' local order `control'