Search code examples
rknitrr-markdown

RMarkdown document - How to delay knitr evaluation of an inline code piece until later chunks have processed?


I've created an rmarkdown report, with a bunch of code chunks. I'm now creating a summary front page for it, and would like to include an inline calculation like

Blah blah blah summary stuff.... We found the mean to be `r mean(some_object_from_the_report)`. Blah blah blah more summary stuff.

Being at the start of the RMD file, some_object_from_the_report doesn't exist yet. Is there any way to tell knitr to hold off evaluating that code snippet until after the later items have all been computed?

Thanks for any tips!

EDIT:

Suggestion as comment is to set echo=false in knitr options. Either I'm doing it wrong, or it doesn't help my situation. The following short example illustrates this.

---
title: "Minimal test of delayed evaluation"
author: "sff"
date: "December 13, 2017"
output: html_document
---

```{r setup, include=TRUE}
knitr::opts_chunk$set(echo = FALSE)
```

## Summary

Summary of blahblahblah. Also here's a mean from the report: `r mean(testobj)`.


## Report

```{r report_stuff}
testobj <- c(1, 2, 3)
```

Knitr throws an object not found error. Am I implementing the suggestion wrongly, or does the suggestion not achieve what I'm looking for?


Solution

  • Here is a simple working example, you set a first chunk before the abstract, it can be set at the very beginning of the document if you need to adjust other thigs like \graphicspath{}.

    In this chunk you create a list if the Rdata file containing the list does not exist. You need to populate it with the values called in the text.

    When first running the example you get first run

    On the second run you get

    second run

    Note that this way, you can avoid running long calculation and simply save their results.

    \documentclass{article}    
    \title{Testing how to save results for the abstract}
    \author{}
    \begin{document}
    % this chunk comes just after begin{document}
    << init, echo=FALSE, eval=TRUE,results="hide" >>=
    require(knitr)
    summary_list_path <-paste0(getwd(),"/data/summary_list.Rdata")
    if (!file.exists(summary_list_path)){
      summary_list<-list()
      summary_list[["A"]]<-list()
      summary_list[["B"]]<-list()
      summary_list[["A"]][["N"]]<-NA
      summary_list[["A"]][["p"]]<-NA
      summary_list[["B"]][["text"]]<-"extremely sad"
    } else {
      load(summary_list_path)
    }
    @
    \maketitle
    \begin{abstract}
    My population is \Sexpr{summary_list[["A"]][["N"]]} and the p value was \Sexpr{summary_list[["A"]][["p"]]} as a result I am \Sexpr{summary_list[["B"]][["text"]]}
    \end{abstract}
    
    <<chunk_1, echo=FALSE, eval=TRUE,results="hide" >>=
    summary_list[["A"]][["N"]]<-20
    summary_list[["A"]][["p"]]<-0.05
    # save your list at the end of each chunk, that was you can also avoid 
    # processing everyting.
    save(summary_list,file=summary_list_path)
    @
    
    <<chunk_2, echo=FALSE, eval=TRUE,results="hide" >>=
    summary_list[["B"]][["text"]]<-"happy"
    save(summary_list,file=summary_list_path)
    @
    
    \end{document}