Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Automating report preparation using filewrite

    Hi there. I wonder if it's possible to write a latex file for a report or a yearbook using file write. To be specific, I have a dataset that currently looks like this:
    Receiver Sender Yearbook Message
    Alan Tina hi
    Alan Mina Bye
    Alan Tom Hi
    Brett Tina Hi
    Brett Alan Hi bye
    We have three variables: receiver's name, sender's name, and sender's yearbook message for the receiver. I want to create multiple PDF files -- one each for each receiver. I wondered if we can use some combination of loops and filewrite to create multiple tex files that we can then use to create multiple PDFs. So if there is a class of 100 students, we'd like to create 100 different tex files where each file would contain yearbook messages for that student. Please let me know if something is not clear! I tried using Rmarkdown and Python, but they cannot read some special characters that Stata seems to be doing a fairly comfortable job with. I really appreciate any help you can provide.

  • #2
    Yes, it's certainly possible because -file- allows for the writing of arbitrary text or binary files. However, this flexibility comes with a lot of additional programming that you would need to do and would not necessarily be the most efficient. Not having used LaTeX recently, I won't offer specific advice here but you might look at Ben Jann's -texdoc- command available from SSC.

    Comment


    • #3
      This can be easily done in Stata 17 or 16 using dyntext. First, let's create a simple dynamic LaTex document yearbook_msg.tex as template.

      Code:
      \documentclass{article}
      
      \title{Year book message}
      \author{Your teacher}
      
      \begin{document}
      \maketitle
      
      From \textbf{<<dd_display: Sender[`1']>>} to \textbf{<<dd_display: Receiver[`1']>>}:
      
      \textit{<<dd_display: Yearbook_Message[`1']>>}
      
      \end{document}
      Now we load our dataset, which looks like:

      Code:
      . list, abb(40)
      
           +--------------------------------------+
           | Receiver   Sender   Yearbook_Message |
           |--------------------------------------|
        1. |     Alan     Tina                 hi |
        2. |     Alan     Mina                Bye |
        3. |     Alan      Tom                 Hi |
        4. |    Brett     Tina                 Hi |
        5. |    Brett     Alan                 Hi |
           +--------------------------------------+
      Note the things like <<dd_display: Sender[`1']>> in the template, those are Stata dynamic tags, if we want to replace them with the contend in the second observation from the dataset, we use dyntext command with the observation number 2 passed in as an argument

      Code:
      dyntext yearbook_msg.tex 2, saving(yearbook_msg_2.tex) replace
      This will produce a yearbook_msg_2.tex, which looks like:

      Code:
      \documentclass{article}
      
      \title{Year book message}
      \author{Your teacher}
      
      \begin{document}
      \maketitle
      
      From \textbf{Mina} to \textbf{Alan}:
      
      \textit{Bye}
      
      \end{document}
      You may use the following do-file to produce one tex file for each observation by filling in the template.

      Code:
      describe
      
      local obs = `r(N)'
      di "`obs'"
      forval i = 1/`obs' {
          dyntext yearbook_msg.tex `i', saving(yearbook_msg_`i'.tex) replace  
      }
      Last edited by Hua Peng (StataCorp); 16 Feb 2022, 09:58.

      Comment


      • #4
        Originally posted by Hua Peng (StataCorp) View Post
        This can be easily done in Stata 17 or 16 using dyntext. First, let's create a simple dynamic LaTex document yearbook_msg.tex as template.

        Code:
        \documentclass{article}
        
        \title{Year book message}
        \author{Your teacher}
        
        <span class="MathJax_Preview" style="color: inherit;"><span class="MJXp-math MJXp-display" id="MJXp-Span-1"><span class="MJXp-merror" id="MJXp-Span-2"><span class="MJXp-mtext" id="MJXp-Span-3">\begin{document}
        \maketitle
        
        From&nbsp;\textbf{&lt;&lt;dd_display:&nbsp;Sender[`1']&gt;&gt;}&nbsp;to&nbsp;\textbf{&lt;&lt;dd_display:&nbsp;Receiver[`1']&gt;&gt;}:
        
        \textit{&lt;&lt;dd_display:&nbsp;Yearbook_Message[`1']&gt;&gt;}
        
        \end{document}</span></span></span></span><script type="math/tex; mode=display" id="MathJax-Element-1">\begin{document}
        \maketitle
        
        From \textbf{<<dd_display: Sender[`1']>>} to \textbf{<<dd_display: Receiver[`1']>>}:
        
        \textit{<<dd_display: Yearbook_Message[`1']>>}
        
        \end{document}</script>
        Now we load our dataset, which looks like:

        Code:
        . list, abb(40)
        
        +--------------------------------------+
        | Receiver Sender Yearbook_Message |
        |--------------------------------------|
        1. | Alan Tina hi |
        2. | Alan Mina Bye |
        3. | Alan Tom Hi |
        4. | Brett Tina Hi |
        5. | Brett Alan Hi |
        +--------------------------------------+
        Note the things like &lt;&lt;dd_display: Sender[`1']&gt;&gt; in the template, those are Stata dynamic tags, if we want to replace them with the contend in the second observation from the dataset, we use dyntext command with the observation number 2 passed in as an argument

        Code:
        dyntext yearbook_msg.tex 2, saving(yearbook_msg_2.tex) replace
        This will produce a yearbook_msg_2.tex, which looks like:

        Code:
        \documentclass{article}
        
        \title{Year book message}
        \author{Your teacher}
        
        <span class="MathJax_Preview" style="color: inherit;"><span class="MJXp-math MJXp-display" id="MJXp-Span-4"><span class="MJXp-merror" id="MJXp-Span-5"><span class="MJXp-mtext" id="MJXp-Span-6">\begin{document}
        \maketitle
        
        From&nbsp;\textbf{Mina}&nbsp;to&nbsp;\textbf{Alan}:
        
        \textit{Bye}
        
        \end{document}</span></span></span></span><script type="math/tex; mode=display" id="MathJax-Element-2">\begin{document}
        \maketitle
        
        From \textbf{Mina} to \textbf{Alan}:
        
        \textit{Bye}
        
        \end{document}</script>
        You may use the following do-file to produce one tex file for each observation by filling in the template.

        Code:
        describe
        
        local obs = `r(N)'
        di "`obs'"
        forval i = 1/`obs' {
        dyntext yearbook_msg.tex `i', saving(yearbook_msg_`i'.tex) replace
        }
        Hello, Hua. Thanks very much for your response! Just one clarification -- we want one tex file for each receiver and not for each observation. Thanks!

        Comment


        • #5
          Then something like this, the template document yearbook_msg.tex now looks like:

          Code:
          \documentclass{article}
          
          \title{Year book message}
          \author{You teacher}
          
          \begin{document}
          \maketitle
          
          
          <<dd_do:quietly>>
          preserve
          keep if Receiver == "`1'"
          describe
          local obs = `r(N)'
          <</dd_do>>
          
          
          
          <<dd_do:nocommands>>
          display `"To \textbf{`=Receiver[1]'} \par"'
          
          forval i = 1/`obs'{
              display `"From \textbf{`=Sender[`i']'}: \textit{`=Yearbook_Message[`i']'} \par"'
          }
          
          restore
          <</dd_do>>
          
          \end{document}
          Note that now we use a <<dd_do>> dynamic tag to execute loop for all senders. In the loop, we use display to construct the LaTex block to be included in the resulted LaTex file. Note the attribute nocommands, which suppress the Stata command itself to be echoed, so only the outcome is included.

          To generate the LaTex file for "Alan",

          Code:
          dyntext yearbook_msg.tex Alan, saving(yearbook_msg_Alan.tex) replace
          The yearbook_msg_Alan.tex looks like:

          Code:
          \documentclass{article}
          
          \title{Year book message}
          \author{You teacher}
          
          \begin{document}
          \maketitle
          
          
          
          
          
          To \textbf{Alan} \par
          
          From \textbf{Mina}: \textit{Bye} \par
          From \textbf{Tina}: \textit{hi bye} \par
          From \textbf{Tom}: \textit{Hi} \par
          
          
          
          \end{document}
          To generate one tex file for each receiver,

          Code:
          levelsof Receiver, local(rec)
          
          foreach p of local rec {
              dyntext yearbook_msg.tex "`p'", saving(yearbook_msg_`p'.tex) replace
          }

          Comment

          Working...
          X