Knitting standalone child documents

509 views
Skip to first unread message

Helder Correia

unread,
Feb 14, 2012, 3:03:23 PM2/14/12
to kn...@googlegroups.com
The input of child files into the main document is great for organization, but sometimes it's desirable to have standalone child documents, for when you're working on a piece and it's isolated from the rest of a big main document.

I know this is why you have the eval flag to turn ON and OFF certain pieces from the main document, but is there a way to make Knitr work with the standalone or subfiles packages?

It would greatly improve workflow.

In fact, what I need could be achieved without those packages. Let me suggest a simple solution.

We could have an option for a parent in the child's \SweaveOpts, or as a comment.

-------- child-doc.Rnw --------
\SweaveOpts{parent=../main.Rnw}
% your typical child content
-------------------------------

or

-------- child-doc.Rnw --------
% knitr.parent ../main.Rnw
% your typical child content
-------------------------------


What Knitr would do is if this file is being compiled directly through knit(input), the file would be decorated with the parent's preamble (including \begin{document} and \end{document}), before compiling. However if the file is being compiled through knit_child(..., eval = TRUE), the parent option would be ignored and nothing else changed from what you have now.

I use TeXShop and made a Knitr.engine (based off of Sweave.sh), that allows me to work on the document and press Cmd+T to typeset and show the resulting PDF while cleaning aux files in one go. The way you have it now I need to switch to the main.Rnw to compile and manage the toggles for eval.

The document I'm working on will get pretty big, with over 100 child documents and this gets hard to manage.

Related:

Thank you for your excellent work!

Yihui Xie

unread,
Feb 14, 2012, 3:12:12 PM2/14/12
to Helder Correia, kn...@googlegroups.com
Thanks for the suggestion! I appreciate this idea, and it does not
seem to be too difficult, so I will implement it.

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 14, 2012, 4:00:10 PM2/14/12
to kn...@googlegroups.com, Helder Correia
Good news then! :)

And if you have nested child documents, you can just follow the parents until you reach the master document to extract the preamble.

Thanks!

Yihui Xie

unread,
Feb 14, 2012, 5:03:17 PM2/14/12
to Helder Correia, kn...@googlegroups.com
Ahh... recursion will be gory. I believe you only have one master
document, right? So the concept of "parent" in knitr does not
necessarily have to be the same as LaTeX; what we really need is just
the preamble of the master document, so the nested structure does not
really matter.

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 14, 2012, 5:10:27 PM2/14/12
to kn...@googlegroups.com, Helder Correia
Yup, I only have one master document with a preamble. All others are content only documents, used in \input.

Helder Correia

unread,
Feb 14, 2012, 5:53:43 PM2/14/12
to kn...@googlegroups.com
There's a problem in running standalone child files, tucked in a subdirectory, because the relative paths of related files (produced graphics, .dat files for R.scan(), etc) won't match with the main document.

The standalone package gives an \ifstandalone conditional macro but in this case it would be great if you could solve this problem in a smarter way. A much simpler solution in our case would be through some sort of base dir prefix (which can be automatically extracted from <<child=[base_dir_for_this_child]/child.Rnw>>=), which can be accessed in our child documents (including in R code?), or through parsing and replacing some string before knitting.

This way that path could be used in case of knitting from the main file or set to ./ (or just ignored) in case of running standalone, allowing child documents to have related files all tucked in dedicated subdirectories.

My project will have a lot of files and I'm trying to keep it all organized.

Thanks!
Helder

Yihui Xie

unread,
Feb 15, 2012, 5:24:42 PM2/15/12
to Helder Correia, kn...@googlegroups.com
I think I have sorted all these issues out now. See the last section
in http://yihui.name/knitr/demo/child/. The latest version is on
GitHub.

This feature request brought much sanity to me on the file management.
In the past, my brain was a mess but now things are clearer: all input
(data, child documents) paths are relative to the Rnw file, and all
output files (tex files, figures, cache) are relative to the current
working directory. In your case, you can create a directory to store
the output, e.g.

./input/
- main.Rnw (contains knit_child('child.Rnw') and read.csv('data.csv'))
- child.Rnw
- data.csv
./output/

You can setwd() to ./output/ first, then call knit('../main.Rnw'), and
you get output like this:

./output/
- cache/
- figure/
- main.tex
- child.tex

For child.Rnw, you can call set_parent('main.Rnw') so it borrows
preamble from main.Rnw; not set_parent() is aware of whether the
current child document is compiled as a child document or a standalone
document, so you can use it freely.

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 16, 2012, 6:19:05 AM2/16/12
to kn...@googlegroups.com
Cool, I can run standalone files now :)

I actually had the following structure in mind for my project:

main.Rnw
main.pdf
  - chap1/
    - ex1/
      - ex1.Rnw
      - ex1.dat
      - ex1.pdf
    - ex2/
      - ex2.Rnw
      - ex2.pdf
  - chap2/
    ...

But what you suggest is simpler and also solves another problem for me which is cleaning up after the deed. Nice :)

I got it to work automatically in TeXShop for the main.Rnw, but I have a problem in standalone files.

I have this now:

main.Rnw
child1.Rnw
child2.Rnw
output/

With this parent in child1.Rnw...

<<setup-child1>>=
set_parent("main.Rnw")
@

Running...

> library(knitr); setwd('output'); knit('../child1.Rnw')

Which outputs...

main.Rnw
child1.Rnw
child2.Rnw
output/
  - child1.tex
  - figure/

Running child1.tex gives the following error...

! LaTeX Error: \usepackage before \documentclass.

In fact when I inspect child1.texthe preamble from main.Rnw isn't being copied.


As an aside, is it possible to have the child doc run chunks from the main doc, as well as inherit global chunk options from \SweaveOpts? The reason is that I now have a few duplicates for setting knit_hooks$set(crop=hook_pdfcrop) and library(xtable), for example, in every child. It would be great to have this duplication removed.

Thanks!
Helder

Yihui Xie

unread,
Feb 16, 2012, 1:12:43 PM2/16/12
to Helder Correia, kn...@googlegroups.com
Sorry that is a bug. I did not have enough sanity for organizing all
kinds of paths. It should be fixed now. I tested with a clean R
session and it worked.

For the second point, that is certainly possible, as long as these
chunks are in the preamble as well. I can find them out and evaluate
them in set_parent(). I will do it later:
https://github.com/yihui/knitr/issues/139

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Yihui Xie

unread,
Feb 18, 2012, 3:18:06 AM2/18/12
to Helder Correia, kn...@googlegroups.com
Child documents can inherit the complete preamble from the parent
document now; whatever is there will be used as if it were in the
preamble of the child document.

I plan to do a new release to CRAN this weekend, so please let me know
if there are any problems (it worked when I tested it, though).

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 18, 2012, 6:19:05 AM2/18/12
to kn...@googlegroups.com, Helder Correia
Works for me, but what about \SweaveOpts?

Is it possible to have many \SweaveOpts where a call to it takes effect from that point onwards?

For example have in child1 \SweaveOpts{fig.path=figure/child1-, dev=pdf}, in child2 \SweaveOpts{fig.path=figure/child2-, dev=tikz} and yet in main, a global \SweaveOpts{echo=FALSE}?

Yihui Xie

unread,
Feb 18, 2012, 7:26:49 PM2/18/12
to Helder Correia, kn...@googlegroups.com
\SweaveOpts{} in the preamble of the parent document is also parsed
when knitting a child document in the standalone mode. And
\SweaveOpts{} just acts like you described: it takes effect from the
point where it is called, so the order matters; set_parent() parses it
in the parent preamble, so the \SweaveOpts{} in the parent preamble is
used when set_parent() is called. It is similar to the function
options(): whenever it is called, the options are changed globally and
permanently in this R session.

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 18, 2012, 8:50:50 PM2/18/12
to Yihui Xie, kn...@googlegroups.com
Knowing that \SweaveOpts{} from the parent runs when calling set_parent() helped. Didn't think of that.

Now I have one last problem, I don't know if it's something I'm doing wrong.

knit_hooks$set(crop=hook_pdfcrop) isn't being recognized in my child documents, when running from parent. It works when running standalone, though. That's my only hook by the way.

Helder Correia
http://heldercorreia.com/

Yihui Xie

unread,
Feb 18, 2012, 10:11:26 PM2/18/12
to Helder Correia, kn...@googlegroups.com
This is a bug. I carelessly restored all hooks before knitting a file;
I should not do it to child documents. Will be fixed soon. Thanks!

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA

Helder Correia

unread,
Feb 19, 2012, 5:20:48 AM2/19/12
to Yihui Xie, kn...@googlegroups.com
Everything looks sunny now :)

Thanks, Yihui!

Helder Correia

Yihui Xie

unread,
Jul 19, 2012, 9:37:05 PM7/19/12
to Fabian, kn...@googlegroups.com, Helder Correia
The OP may not be able to see your email sent to the mailing list, so CC'ed him.

Regards,
Yihui
--
Yihui Xie <xiey...@gmail.com>
Phone: 515-294-2465 Web: http://yihui.name
Department of Statistics, Iowa State University
2215 Snedecor Hall, Ames, IA


On Thu, Jul 19, 2012 at 6:22 PM, Fabian <fab...@gmail.com> wrote:
> Hi!
>
> Could you possibly share the knitr.engine for TeXShop?
>
> This would be very helpful! I only getting started with R, LaTeX and
> programming in general ...
>
> Thanks a lot!
Reply all
Reply to author
Forward
0 new messages