Search code examples
rknitrsweave

Extracting arguments of an R function to use in knitr


Arguments of lm function can be obtained by using:

args(lm)

Output

function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 
NULL

Questions

How to get:

lm (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 

with the description (Not complete help) of each Argument to be used in Sweave or knitr. Thanks

Edited

Using funExtract function provided by @Ananda, I'm very close to my desired result. Here is code of my Rnw file with output.

\documentclass{article}
\usepackage[T1]{fontenc}

\begin{document}

Arguments for lm

<< label = funExtract, echo = TRUE, results = "hide", tidy = FALSE >>=
funExtract <- function(Function, section = "Usage") {
  A <- deparse(substitute(Function))
  x <- capture.output(tools:::Rd2txt(utils:::.getHelpFile(help(A))))
  B <- grep("^_", x)                    ## section start lines
  x <- gsub("_\b", "", x, fixed = TRUE) ## remove "_\b"
  X <- rep(FALSE, length(x))
  X[B] <- 1
  out <- split(x, cumsum(X))
  out <- out[[which(sapply(out, function(x) 
    grepl(section, x[1], fixed = TRUE)))]]
  cat(out, sep = "\n")
  invisible(out)
}
@

\vspace{0.5cm}\\
funExtract function output
\vspace{0.25cm}\\
<< label = lm-usage, echo = FALSE, results = "asis" >>=
funExtract(lm, section="Usage:")
@

\vspace{0.5cm}\\
args function output
\vspace{0.25cm}\\
<< label = lm-args, echo = FALSE, results = "asis" >>=
args(lm)
@


\end{document}

Output

enter image description here

Issues with funExtract function output

  1. How to get highlighted output from funExtract function as other code?
  2. How to remove section title form funExtract function output?

Solution

  • I had written a function and posted it as an answer earlier (as noted in the question itself), but wasn't entirely happy with the inconsistencies or the requirement that it had to be used with "markdown" to be used successfully. After a little bit more work, this is the function that I came up with:

    helpExtract <- function(Function, section = "Usage", type = "m_code", ...) {
      A <- deparse(substitute(Function))
      x <- capture.output(tools:::Rd2txt(utils:::.getHelpFile(help(A, ...)),
                                         options = list(sectionIndent = 0)))
      B <- grep("^_", x)                    ## section start lines
      x <- gsub("_\b", "", x, fixed = TRUE) ## remove "_\b"
      X <- rep(FALSE, length(x))
      X[B] <- 1
      out <- split(x, cumsum(X))
      out <- out[[which(sapply(out, function(x) 
        grepl(section, x[1], fixed = TRUE)))]][-c(1, 2)]
      while(TRUE) {
        out <- out[-length(out)]
        if (out[length(out)] != "") { break }
      } 
    
      switch(
        type,
        m_code = c("```r", out, "```"),
        s_code = c("<<>>=", out, "@"),
        m_text = paste("    ", out, collapse = "\n"),
        s_text = c("\\begin{verbatim}", out, "\\end{verbatim}"),
        stop("`type` must be either `m_code`, `s_code`, `m_text`, or `s_text`")
      )
    }
    

    Quite a mouthful, and it's not entirely DRY... but I wanted to capture four scenarios and this was the quickest idea that came to mind. The four scenarios I anticipate are:

    1. Document type is markdown and user is extracting a code block (type = "m_code")
    2. Document type is markdown and user is extracting a non-code section (type = "m_text")
    3. Document type is Sweave and user is extracting a code block (type = "s_code")
    4. Document type is Sweave and user is extracting a non-code section (type = "s_text")

    The function extracts the output of Rd2txt. I picked that over the other formats (HTML, LaTeX) to allow me to use a single function to get what I was after and not have to create multiple functions.


    Usage

    Usage is different depending on if you're creating a "Sweave" (.Rnw) or a "markdown" (.Rmd) document.

    1. Markdown

      Insert your code in a code chunk that looks something like this (maybe one day I'll add different methods, but not now):

      ```{r, echo=FALSE, results='asis'}
      cat(helpExtract(cor), sep = "\n")
      ```
      
    2. Sweave

      Pretend you are inserting a "child" document that should be included in the main document using Sexpr{knit_child(.)}

      \Sexpr{knit_child(textConnection(helpExtract(cor, type = "s_code")), 
      options = list(tidy = FALSE, eval = FALSE))}
      

    I've created a Gist that includes the function, a sample Rmd file and an sample Rnw file. Feel free to leave comments and suggestions here on Stack Overflow (since Gist comments are pretty much meaningless since they don't notify the user when a comment is posted).


    If you're trying to refer to a function from a package that is not currently loaded, the usage of helpExtract should be something like:

    helpExtract(gls, package = "nlme")