Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: problems with global macros in mata


From   wgould@stata.com (William Gould, StataCorp LP)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: problems with global macros in mata
Date   Mon, 28 Jul 2008 12:44:50 -0500

Benjamin Klaus <ben_klaus@gmx.de> writes, 

> I want to export the (changing) content of a matrix "x" from mata into
> textfiles named "mi.txt", where "i" is a global macro. This should work in
> the following way, but it seems that the value of the global macro is not
> changed correctly at each stage of the loop...
>
>
>       mata
>       x = (76, 53, 48 \ 53, 88, 46 \ 48, 46, 63)
>       i=0
>       while (i<=5) {
>       
>               i = i + 1
>               st_global("i",strofreal(i))
>               stata("display($i)")        // just to check the value 
>                                           // (it doesn't work)
>               mm_outsheet("D:\m$i.txt", strofreal(x), "replace")
>       }
>       end

First let me address the problem asked about, and then let me give a better
way to proceed.  Let's simplify the above to read 

        mata
        i = 0 
        while (i<=5) { 
                i = i + 1 
                st_global("i", strofreal(i))
                stata("display $i")
       }

As Benjamin notes, it does not work:  It displays nothing.  What will work is 
changing 

                stata("display $i")

to

                stata("display $" + "i")

What was happening is that, at compile time -- at the time the lines were 
entered into Mata, the contents of $i were substituted, so -stata("display $i")-
became -stata("display ")-.  The way I just coded it, $ and i do not appear 
adjacent yet, at execution time, the string "display $i" is assembled and 
then that is substituted when it goes to Stata.

Now let's talk about mm_outsheet("D:\m$i.txt", strofreal(x), "replace").
Obviously, there is the issue of $i, and so the line could be replaced 
with 

        mm_outsheet("D:\m$"+"i.txt", strofreal(x), "replace")

There still may be aproblem, however, depending on what mm_outsheet()
does with its first argument.  I am not familiar with the function 
-mm_outsheet()-, but understand, Mata at execution time does NOT substitute
macros.  "$i" just means "$i".  The reason -stata(display $" + "i")- worked 
is that -display $i- was passed to Stata, and Stata expanded the macro $i.

Mata expands macros at compile time, but not at execution time.  

One solution would be to use -st_macroexpand()-, the Mata function that 
expands macros:

        mm_outsheet(st_macroexpand("D:\m$"+"i.txt"), strofreal(x), "replace")

That would work, but it is not the solution I am recommending.

At this point, Benjamin must be thinking that working with macros in Mata is
mighty inconvenient.  He would be right.  Macros, so natural in Stata, are 
not natural in Mata and in fact are not necessary.  The better way to 
code the problem would be, 

        i = 0 
        while (i<=5) { 
                i = i + 1 
                mm_outsheet("D:\m"+strofreal(i)+".txt", strofreal(x), "replace")
       }

We might also use -for- rather than while, 

       for (i=1; i<=5; i++) { 
                mm_outsheet("D:\m"+strofreal(i)+".txt", strofreal(x), "replace")
       }

and perhaps the code would be more easily read if we coded, 

       for (i=1; i<=5; i++) { 
                fn = "D:\m" + strofreal(i) + ".txt"
                mm_outsheet(fn, strofreal(x), "replace")
       }

or 

       for (i=1; i<=5; i++) { 
                fn = sprintf("D:\m%g.txt", i)
                mm_outsheet(fn, strofreal(x), "replace")
       }

-- Bill
wgould@stata.com
*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index