Macro, Matrix and Loop, Commands **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ I ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ *▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ I ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Display ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ display "Hi" /* display text */ display 4*5 /* display numbers or expressions */ dis bw /* display 1. observatiopn of variable bw */ dis bw[2] /* display 2. observatiopn of variable bw */ * Display using SMCL (Stata Markup and Command Language) dis "{break} {break}" /// "{col 10}{txt:A= } {col 20}{res}" %3.1f 1.567 "{break}" /// "{col 10}{txt:B= } {col 20}{res}" %3.1f 4.234 "{break}" /// "{col 10}{err:Note:} {col 20}{inp:B is larger than A}" help display /* help */ **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Returned Results ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * In Stata we have ordinary commands (sum, mean, ...) and estimation commands (regress, logistic,...) *▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ Ordinary Commands ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ sum bw // ordinary command return list // return list display `r(mean)' // display the returned value (`:shift-\) (': not-shift *), works also without the single quotes count if bw>=4000 // count the number with high bw return list // return list dis `r(N)' // show the returned value * Ordinary commands (summary, count, mean, ...) store their results in "r" (like r(mean) or r(N)) * You can see the list of returned result by running "return list" after the command. * Estimation commands (regress, logistic, ...) store their results in "e" (like e(N) ) * You can see the list of returned result by running "ereturn list" after the command. * In addition, most estimation commands also return "r(table)", a standard matrix of coefficients and CI-s * Do "matrix list r(table)" after the command *▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ Estimation commands ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ * Linear regression regress bw gest sex // estimation command ereturn list // e-return list dis e(N) // display the number of observations * 3 ways of getting coefficients after regressions matrix list e(b) /* Alternative 1) list the returned matrix of coefficients */ dis _b[gest] " " _b[sex] " " _b[_cons] /* Alternative 2) method of showing coefficients */ mat list r(table) /* Alternative 3) perhaps best method of getting coeffs+CI, r(table) is returned by most estimation commands */ mat R=r(table)' // store (transposed) table of results in a matrix R mat list R // list matrix * Logistic regression logistic lbw gest sex // OR-s logit lbw gest sex // coefs eret list // e-return list mat R=r(table) // store standard table of results in a matrix R mat list R // list matrix (OR-s) * Estimation commands (regress, logistic, ...) store their resulst in "e" (like e(b) or e(N)) * Most estimation programs also store the standard matrix r(table) local OBS "Go back to Examples" **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Macros ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Macros can store expressions or strings. * Two types: local and global. Global has a longer life and is more visible, local is used in loops and can be (easier) nested. * Global macros are refered to by $a. * Local macros are referred to by quotes `a', first quote is shift-\, seqond quote is on the * button. Use a space after first quote for names starting with i or a. * Local Macro local a=2 /* define a to contain number by using "=" */ display `a' /* display content */ * Show the local macros are short lived local a Hello there /* define a to contain the string. Do not use "=" for strings */ display "`a'" /* display content as text */ local a 2+2 /* 2+2 as text */ dis "`a'" /* show as text */ dis `a' /* show evaluated */ local OBS "Go back to Examples" local b=2+2 /* define b to contain the evaluated expression. Use "=" to force evaluation first */ dis "`b'" /* display content */ dis `b'*2 dis "Number`b'" local v bw /* variable name */ dis `v' /* value of 1. obs of bw */ dis "`v'" /* variable name bw as text */ * Global Macro global a=2 /* define */ display $a /* display content */ gen x=runiformint(0,4) /* integer numbers from 0-4 */ gen x$a=x^2 /* x2=x^2 */ list x x2 in 1/4 help macro * Extended macro functions help macro /* click extended_fcn */ global x: variable label bw /* ":" assign extended function, variable label */ global x: label (educ) 1 /* label 1 of the variable educ */ global x: label educ 1 /* label for label value 1 */ display "$x" /* show content as text */ global x :display %4.1f 0.123456 /* formating */ dis "$x" local st "aa bbb c" gettoken w rest: st dis "`w', `rest' " * Examples of macros in a loop (do not run) local str "aa bbb c" forvalues i=1(1)3 { // loop over i from 1 to 3 `m'`i' // local macro m1, m2, m3 word `i' of `str' // word 1, 2 and 3 of the macro str M[`i',1] // element 1,1 2,1 and 3,1 of matrix M } // end i **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Matrices ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Matrix (rectangular list of numbers, text not allowed) matrix A=J(2,3,0) /* define 2*3 matrix of 0’s */ matrix list A /* display content */ matrix A[2,1]=2 /* change element */ mat B=(1,2,3,4\5,6,7,8\9,10,11,12) /* 3*4 matrix of given numbers */ mat colnames B= a b c d /* set column names */ mat rownames B=low med high /* set row names */ mat list B local OBS "Go back to Examples" * Submatrix extraction mat C=B[1..2,2..4] /* rows 1-2, colums 2-4 */ mat C=B[1...,2..4] /* rows 1-end, colums 2-4 */ mat C=B[....,2..4] /* rows beginning-end, colums 2-4 */ mat C=B[....,"b"] /* rows beginning-end, colum named "b" */ mat C=B[....,"b".."d"] /* rows beginning-end, colum named "b" to "d" */ mat list C * Join mat A= B \ C /* add rows of C below rows of B (row join) */ mat A= B , C /* add columns of C to the right of B (column join) */ mat A=(1,2,3) /* first line */ mat A=A\(4,5,6) /* add second line below first */ mat list A * Save matrix as data svmat B, names(col) // save matrix B in the present data, use colnames as variable names **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Loops ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Stata has six loop types, we show three below, type help foreach to see all forvalues i=1(1)5 { /* loop over i=1 in steps of 1 to 5 */ display `i' // the index i is a local macro } // end i foreach v of varlist bw gest age { /* loop over variable list */ sum `v' } // end v global txt "Peter Eve Jamal" foreach g of global txt { /* loop over values in a global macro */ dis "Hello `g'" } //end g * ------------------ Examples of loops ----------------------------------------------------------------------- * Loop over variable list and a counter i local i=0 foreach v of varlist gest educ sex { /* loop over variable list */ local ++i /* increment i */ dis "`i' `v'" } // end v * Loop over variable list and build up a string macro foreach v of varlist gest educ sex { /* loop over variable list */ local vars="`vars' `v'" /* add each variable to the macro "vars", the macro is empty at start */ dis "`vars'" } // end v * Build up matrix of results foreach v of varlist gest educ sex { /* loop over variable list */ local vars="`vars' `v'" /* add each variable to the macro "vars", the macro is empty at start */ regress bw `vars' // regression with increasing number of variables mat R=r(table)' // table of results transposed mat G=`d'R["gest",....] // The first time, the macro `d' does not exist and is ignored. Later `d' equals G\, and a line is added to G. local d G\ // define d to contain the text G\ mat list G, format(%5.1f) } // end v local OBS "Go back to Examples" **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Frames ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Stata, up to version 15, can only open one datafile at a time * Stata 16 uses frames to handle several datafiles * The current datafile is called "default" * Commands frame create f1 v1 v2 v3 // create new datafile called f1 with 3 (empty) variables: v1, v2 and v3 frame post f1 (10 ) (20 ) (30 ) // add one line of data to f1 frame post f1 (100) (200) (300) // add one line of data to f1 frame change f1 // change to f1, or "cwf f1" edit frame change default // change back to default frames edit local OBS "Go back to Examples" frame f1: stata_command // run command in another datafile frame copy frame_from frame_to // copy variables to a new file **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ #delimit ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Stata (up to version 15) syntax does not a end of command sign (like ".") Commands longer than a line therfore need a continuation sign (///), like this tw (kdensity bw if sex==1, col(blue)) /// (kdensity bw if sex==2, col(red )) /// , legend(off) * We can change this by the commands #delimit #delimit ; // change the command delimiter from "cr" (=carriage return=enter) to ";" tw (kdensity bw if sex==1, col(blue)) (kdensity bw if sex==2, col(red )) , legend(off) ; // notice the ";" to end the command #delimit cr // change the command delimiter back to the normal "cr" (=carriage return=enter) * Using #delimit also allows many commands per line #delimit ; // change the command delimiter from "cr" (=carriage return=enter) to ";" sum bw; gen bwZ=(bw-`r(mean)')/`r(sd)'; sum bwZ; // many commands per line local OBS "Go back to Examples" **#◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ Postfile ◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘◘ * Stata, up to version 15, can only open one file at a time * But a postfile is an extra file that we can write results to without having to close the datafile. * We define a postfile by giving it a local name ("ppp") and a real name ("Res_temp") and then give a list of variables * The variable list may contain datatypes (str30 or byte or double,...), the default is "float" (numeric) * Define the postfile * Defining a resultfile with local name "ppp" and real file name "Results" * The variable list contains 3 variables, a string of 30 called "heading" and two (default numeric) variables called "mean" and "pval" postfile ppp str30 heading mean pval using "Results", replace * Write to the postfile * "heading" mean pval post ppp ("Gestational age") (3600) (0.001) // write first line of data to the postfile post ppp ("Education") (3200) (0.05) // write next line of data to the postfile * Close the postfile postclose ppp * Peak at results preserve // preserve (store) the present data file use "Results", clear // open the Results (postfile) list, sep(100) // list the postfile restore // restore the present datafile