6

I have a bookdown rmd looking like...

Further introductory materials are offered when the package is loaded:

```{r dt-startup, echo=-1, message=TRUE, verbose=TRUE, hide=FALSE}
if ("data.table" %in% .packages()) detach("package:data.table")
library(data.table)
```

My intention was to show the reader the package's startup messages. However, they don't print. Is there some other chunk option to use here?

As you can see, I just threw several maybe-relevant chunk options at it to no good result. I'm not terribly familiar with management of output streams, so that's as far as I knew to go. I also tried calling directly with data.table:::.onAttach(), but no dice.

I'm not sure what else would be relevant here, but ...

  • Currently the package has not been loaded before this chunk. I just added the first line for robustness in case I rearrange the document.
  • My before_chapter_script contains nothing but knitr::opts_chunk$set(comment="#").
  • My knit header value is bookdown::render_book and the output is bookdown::html_book.
Frank
  • 66,179
  • 8
  • 96
  • 180
  • Also, I really don't know if there's a relevant distinction between knitr and rmarkdown here. Feel free to edit title, tags, whatever if I'm wrong about it. – Frank Mar 16 '17 at 17:41
  • 1
    Strangely `msg <- capture.output(library(data.table), type = "message"); print(msg)` will capture the startup message as a text string when run from an interactive section, but returns an empty result when run from a knitr document. – nrussell Mar 16 '17 at 18:15
  • 1
    @nrussell Yeah it definitely seems like something is going on under the hood to suppress the packageStartupMessages and I don't see an option to prevent that behavior – Dason Mar 16 '17 at 18:16
  • 2
    I'm assuming that this line is part of the issue: https://github.com/yihui/knitr/blob/master/R/cache.R#L86 because it's the only place I could find `suppressPackageStartupMessages` in knitr – Dason Mar 16 '17 at 18:19
  • 2
    And I'm not going to pretend to understand all of the internals of knitr but I believe this is the line that calls that code in cache.R that I referenced. https://github.com/yihui/knitr/blob/4f4431b7d5e672db4a8fb45c4e56cd3c285d3faf/R/block.R#L79 and you'll see it uses save=FALSE which puts the code down the path to use suppressPackageStartupMessages. It seems like overkill but for the time being maybe you could fork the repo and patch that out and submit an issue with knitr. I don't know how long it would take Yihui to work out but there probably should be a chunk option for this. – Dason Mar 16 '17 at 18:22
  • 3
    Look at `data.table:::.onAttach`: If `interactive()` is not `TRUE`, it issues no startup message. I see two workarounds, both rather dirty: Force `interactive` to return true when knitting (along the lines of [this](http://r.789695.n4.nabble.com/Modify-base-R-functions-in-Rprofile-site-td905121.html), but I couldn't make this work yet) or extract the desired strings directly from `data.table:::.onAttach`, using `deparse(data.table:::.onAttach)[25:27]` as a starting point. – CL. Mar 17 '17 at 08:19
  • CL's comment seems like it might be the issue. Are you attached (hah) to using data.table to illustrate the packageStartupMessages? – Dason Mar 17 '17 at 12:47
  • @Dason Yeah, it's specifically about that, so I've added the tag. – Frank Mar 17 '17 at 12:50
  • I suppose you're against just copying the code for the packageStartupMessage section and running that in your document directly? – Dason Mar 17 '17 at 12:58
  • @Dason Yeah, I might do that. I can just include a comment like # startup messages as of version 1.10.4 and verbatim copy the text (not just the code to make it). – Frank Mar 17 '17 at 13:11
  • @CL Great, thanks! What I have so far is `my_attach = data.table:::.onAttach; body(my_attach) <- body(my_attach)[[2]][[3]]; my_attach()` which works, but there must be some more automated way to get rid of the `interactive()` condition, like `rapply` to replace it with TRUE (or alternately to select the `packageStartupMessage` lines).... I haven't figured it out, though. – Frank Mar 17 '17 at 14:51
  • @Frank: Yes, it works, but it's not nice … I think the cleanest (but still very dirty) solution is something like [this](https://gist.github.com/ClaudiusL/8aa3cff48d9d02f31452ba6c22d6011c#file-gistfile1-txt) but this crashes, claiming the binding of `interactive` was locked (although I unlock it the line before and running this in an interactive session works just fine). – CL. Mar 17 '17 at 14:59
  • @CL Ah, yup. I saw that here too (in the question, not the answer) http://stackoverflow.com/questions/17328172/forcing-interactive-r-session Maybe knitr can add a chunk option that mimics what Dirk did with littler options (in the answer). I'll post a feature request. – Frank Mar 17 '17 at 16:56
  • 1
    Just for the record, the feature request to knitr was posted to https://github.com/yihui/knitr/issues/1380 – Yihui Xie Mar 17 '17 at 19:57
  • @CL Fyi, I posted the issue and Yihui replied (linked in his comment above). He makes a good case for simply not doing it, which I've summarized in my own words as an answer. Let me know if you have further thoughts and feel free to edit the question or answer. Thanks again for the help. – Frank Mar 17 '17 at 20:35

1 Answers1

2

Don't. Anything hacked in for this would be fragile and arguably not terribly useful.

Yihui Xie (knitr's author) makes a good case. My synopsis:

  • This is not useful. You're writing a tutorial, so why include dynamic content (that may change when the package changes)? Moreover, why not point to resources directly rather than to the list of resources printed there?
  • This is very hard. It is not just a matter of output streams. The messages don't print because they are walled behind an interactive() check. It's not obvious how this should be overridden and, supposing it could be done, what weird side effects that might introduce.
Frank
  • 66,179
  • 8
  • 96
  • 180