nbstata
nbstata copied to clipboard
Inline Stata code in Quarto
Now if we could get the option of inline Stata…
Originally posted by @friosavila in https://github.com/hugetim/nbstata/issues/37#issuecomment-2394444814
The Quarto docs state "This syntax works for any Jupyter kernel..." so I don't understand why it doesn't work, but it indeed doesn't. Have you tried submitting a Quarto issue about it?
I went ahead and reported this here: https://github.com/quarto-dev/quarto-cli/issues/10979
Update: I think the issue is due to missing kernel functionality in 'nbstata' that should be straightforward to implement. I hope to release it by the end of the month.
See: https://github.com/quarto-dev/quarto-cli/issues/10979#issuecomment-2398043525
The plan is to pass any inline expressions to sfi.SFIToolkit.macroExpand, making use of the '= exp' local expansion operator.
So, given the following line in a .qmd file, assuming that the Stata scalars x and y have already been defined
Testing inline `{stata} x + y`.
I'll get the output to replace the inline code expression with from this Python:
output = sfi.SFIToolkit.macroExpand("""`=x + y'""")
Unfortunately, it seems we won't be able to use locals in inline Stata code, due to the backtick syntax clash. But we should be able to use scalars, globals, and also "return" macros.
That is awesome!
May I suggest to also allow for display and globals?
And perhaps mata ‘Stata mata x’ Allowing to show the content of x?
On Mon, Oct 7, 2024 at 7:12 PM Tim Huegerich @.***> wrote:
The plan is to pass any inline expressions to sfi.SFIToolkit.macroExpand https://www.stata.com/python/api18/SFIToolkit.html#sfi.SFIToolkit.macroExpand, making use of the '= exp' local expansion operator.
So, given the following line in a .qmd file, assuming that the Stata scalars x and y have already been defined
Testing inline
{stata} x + y.I'll get the output to replace the inline code expression with from this Python:
output = sfi.SFIToolkit.macroExpand("""`=x + y'""")
Unfortunately, it seems we won't be able to use locals in inline Stata code, due to the backtick syntax clash. But we should be able to use scalars, globals, and also "return" macros https://www.stata.com/python/api18/Macro.html#sfi.Macro.getGlobal.
— Reply to this email directly, view it on GitHub https://github.com/hugetim/nbstata/issues/50#issuecomment-2398107872, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASZKKFSXHJVJTWITBK3MTIDZ2MIM7AVCNFSM6AAAAABPMW5UYWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJYGEYDOOBXGI . You are receiving this because you were mentioned.Message ID: @.***>
May I suggest to also allow for display and globals? And perhaps mata ‘Stata mata x’ Allowing to show the content of x?
Globals should already be covered by my current plan. Likewise for Mata if you pass the relevant information to Stata first (such as with st_numscalar or 'st_matrix').
What do you have in mind using display for? If it's something like formatting a number, you should be able to save a number in the correct format to a string scalar (using strofreal(n,s)).
But the idea is that you can use any Stata expression in the inline code (except that locals are not allowed). I think that will read better than having Stata commands like "display" and "mata" in there (and it would also be much more complicated to allow those, I think).
On second thought, maybe we should try to match MarkStat's features for inline code:
You can quote results by including inline code as part of your narrative, using the syntax `s [fmt] expression`, where fmt is an optional format, followed by an expression. The markstat command will generate code to evaluate the expression using Stata’s display command, and will splice the output inline with the text. For example after running a regression you can cite R-squared by coding `s e(r2)`. If you prefer to display the value with 2 decimal places only, use `s %5.2f e(r2)`. Consistent with our treatment of Mata as a first class citizen, you can also include inline Mata code using the same syntax, but with an m instead of an s. The markstat command will generate a printf() function call to display the expression with the given format. If the format is omitted it defaults to %s, so the expression should yield a string.
(We could use mata's sprintf, saving to a scalar which we can then retrieve via Python.)
Decided to keep it simple for now and just support the Stata display syntax (with no special mata support).
Good news: we're able to directly use Stata's display (so that you "can use all the features of display that make sense," as Stata's docs put it) like this: https://github.com/hugetim/nbstata/blob/12fc23f00fcb14df59d6d12ea910ea45259a8ecb/nbstata/stata_more.py#L181
For future consideration:
For Mata, my current thought on the syntax is to make the sprintf function explicit (but make the 'mata' implicit, to save typing). So it would look like this:
The first coefficient is `{stata} sprintf("%10.0g", coef[1])`.
Thoughts? This provides flexibility to include multiple variables in a single inline code statement, similar to display.
Alternatively, the syntax could more closely mimic MarkStat, like {stata} mata %10.0g coef[1] (or just {stata} mata coef[1]). Is that better? Less flexibility (and also error messages will be more difficult to interpret) but also less typing.
Either way, this plan will provide inline code feature parity with MarkStat, except that we won't be able to support SMCL.
Thank you. This is awesome Any chance of one other request? I know with quarto we can set environmental variables then feed them into python or R Do you think that could be done for nbstata too?
On Sat, Oct 12, 2024 at 1:40 AM Tim Huegerich @.***> wrote:
Closed #50 https://github.com/hugetim/nbstata/issues/50 as completed.
— Reply to this email directly, view it on GitHub https://github.com/hugetim/nbstata/issues/50#event-14615910355, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASZKKFQI6TJWXZE33WHEV7DZ3CY5HAVCNFSM6AAAAABPMW5UYWVHI2DSMVQWIX3LMV45UABCJFZXG5LFIV3GK3TUJZXXI2LGNFRWC5DJN5XDWMJUGYYTKOJRGAZTKNI . You are receiving this because you were mentioned.Message ID: @.***>