4
votes

I'm having a problem similar to the issue raised in 'R, knitr doesn't respect order of chunks and text'. In my code I have a text heading followed by a chunk which uses four knitr::kable function calls to show four tables. Strangely, Tables 1 and Table 2 appear above the heading and Tables 3 and 4 below in output to a PDF. It appears this has to do with knitr allowing objects to float. Can I turn that off preferably in the knitr::kable function or in the chunk options? Here is my code:

---
title: "Reproducible Error"
author: "Rex Macey"
date: "February 14, 2017"
output: pdf_document
header-includes: 
- \usepackage{placeins}
---

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

\newpage  

# Section 1  
```{r CompTables, echo=FALSE, warning=FALSE, results='asis', out.extra='FloatBarrier'}
comptables1<-matrix(rep(c(100,200,300,400,500),3),nrow=5,ncol=3)
colnames(comptables1)<-c("Conservative","Moderate","Aggressive")
row.names(comptables1)<-c("5th %-tile","25th %-tile","50th %-tile","75th %-tile","95th %-tile")
comptables2<-matrix(0,nrow=6,ncol=3)
comptables2[1,]<-comptables1[1,]
for (i in 2:5){
    comptables2[i,]<-comptables1[i,]-comptables1[i-1,]
}
comptables<-list()
comptables[[1]]<-list(comptables1,comptables2)
comptables[[2]]<-list(comptables1,comptables2)
comptables[[3]]<-list(comptables1,comptables2)
comptables[[4]]<-list(comptables1,comptables2)

knitr::kable(comptables[[1]][1],
         caption="Table of Forecast Wealth Values: Suggested One Year",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[2]][1],
         caption="Table of Forecast Wealth Values: Suggested Three Years",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[3]][1],
         caption="Table of Forecast Wealth Values: Suggested Five Years",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[4]][1],
         caption="Table of Forecast Wealth Values: Suggested Ten Years",
        format.args=list(big.mark=",",floating=FALSE))
```


```{r CompChart, echo=FALSE, warning=FALSE, fig.height=4, fig.show='hold', results='asis'}
horizons <- c(1,3,5,10)
par(mfrow=c(1,2))
minv<-min(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
maxv<-max(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
for (h in 1:length(horizons)){
    wealth.pl.comp<-matrix(unlist(comptables[[h]][2],use.names = FALSE),ncol=3,byrow=FALSE)
    colnames(wealth.pl.comp)<-c("Cons.","Mod.","Aggr.")
    barplot(wealth.pl.comp,col=c("white","red","yellow","green","blue"),border=NA,
        main=paste("Forecast A/T Values -",horizons[h],"Years"),
        ylim=c(minv/2,maxv+minv/2))
    abline(h=250,col="darkgray")
}
par(mfrow=c(1,1))
```


\newpage    

#Section 2

I have experimented with the floating = FALSE option in the kable function and the fig.show and results parameters (including results='hold') in the chunk options. The newpage before Section 1 is out of order as well. Note I did check out this seemingly similar question too.

Here is an image of the output. The text from within the single chunk shown is out of order because two of the tables are above the text header "Section 1". The chart between tables is from a subsequent chunk.

Image of Output

2
I usually include \usepackage{placeins} in my header and then place \FloatBarrier before the section heading to prevent floating environments from crossing outside of the section I want them in.Benjamin
I added header-includes: - \usepackage{placeins} and modified the headers of the chunks so they look like this {r, echo=FALSE, warning=FALSE, results='asis', out.extra='FloatBarrier'} per the comment of @Benjamin. I still have the same problem. What should I do differently?rmacey
If you provide a reproducible example, it will be easier to make a specific recommendation.Benjamin
@Benjamin when your[sic] right, you're right. My apologies. I've redone with reproducible code. If it helps, my knitr is v1.15.1, rmarkdown is 1.3, RStudio is 1.0.136, and R is 3.3.2rmacey

2 Answers

3
votes

Based on the documentation, out.extra provides "extra options for figures."

When I place the \FloatBarrier above the chunk instead of using out.extra, I get something more like what I believe you are wanting.

---
title: "Reproducible Error"
author: "Rex Macey"
date: "February 14, 2017"
output: pdf_document
header-includes: 
- \usepackage{placeins}
---

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

\newpage  

\FloatBarrier

# Section 1  
```{r CompTables, echo=FALSE, warning=FALSE, results='asis'}
comptables1<-matrix(rep(c(100,200,300,400,500),3),nrow=5,ncol=3)
colnames(comptables1)<-c("Conservative","Moderate","Aggressive")
row.names(comptables1)<-c("5th %-tile","25th %-tile","50th %-tile","75th %-tile","95th %-tile")
comptables2<-matrix(0,nrow=6,ncol=3)
comptables2[1,]<-comptables1[1,]
for (i in 2:5){
    comptables2[i,]<-comptables1[i,]-comptables1[i-1,]
}
comptables<-list()
comptables[[1]]<-list(comptables1,comptables2)
comptables[[2]]<-list(comptables1,comptables2)
comptables[[3]]<-list(comptables1,comptables2)
comptables[[4]]<-list(comptables1,comptables2)

knitr::kable(comptables[[1]][1],
         caption="Table of Forecast Wealth Values: Suggested One Year",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[2]][1],
         caption="Table of Forecast Wealth Values: Suggested Three Years",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[3]][1],
         caption="Table of Forecast Wealth Values: Suggested Five Years",
        format.args=list(big.mark=",",floating=FALSE))

knitr::kable(comptables[[4]][1],
         caption="Table of Forecast Wealth Values: Suggested Ten Years",
        format.args=list(big.mark=",",floating=FALSE))
```


```{r CompChart, echo=FALSE, warning=FALSE, fig.height=4, fig.show='hold', results='asis'}
horizons <- c(1,3,5,10)
par(mfrow=c(1,2))
minv<-min(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
maxv<-max(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
for (h in 1:length(horizons)){
    wealth.pl.comp<-matrix(unlist(comptables[[h]][2],use.names = FALSE),ncol=3,byrow=FALSE)
    colnames(wealth.pl.comp)<-c("Cons.","Mod.","Aggr.")
    barplot(wealth.pl.comp,col=c("white","red","yellow","green","blue"),border=NA,
        main=paste("Forecast A/T Values -",horizons[h],"Years"),
        ylim=c(minv/2,maxv+minv/2))
    abline(h=250,col="darkgray")
}
par(mfrow=c(1,1))
```


\newpage    

#Section 2
1
votes

Bit of a late response, but I have just been working on this. Loading the kableExtra package and including some restrictions in the kable_styling options seems to do the trick. Particularly latex_options = c("hold_position")

---
title: "Reproducible Error"
author: "Rex Macey"
date: "February 14, 2017"
output: pdf_document
header-includes: 
    - \usepackage{placeins}
---

```{r setup, include=FALSE}
library("knitr")
library("tidyverse")
library("kableExtra")

knitr::opts_chunk$set(echo = TRUE)
```

\newpage  

# Section 1  
```{r CompTables, echo=FALSE, warning=FALSE, results='asis', out.extra='FloatBarrier'}
comptables1<-matrix(rep(c(100,200,300,400,500),3),nrow=5,ncol=3)
colnames(comptables1)<-c("Conservative","Moderate","Aggressive")
row.names(comptables1)<-c("5th %-tile","25th %-tile","50th %-tile","75th %-tile","95th %-tile")
comptables2<-matrix(0,nrow=6,ncol=3)
comptables2[1,]<-comptables1[1,]
for (i in 2:5){
    comptables2[i,]<-comptables1[i,]-comptables1[i-1,]
}
comptables<-list()
comptables[[1]]<-list(comptables1,comptables2)
comptables[[2]]<-list(comptables1,comptables2)
comptables[[3]]<-list(comptables1,comptables2)
comptables[[4]]<-list(comptables1,comptables2)

knitr::kable(comptables[[1]][1],
             caption="Table of Forecast Wealth Values: Suggested One Year",
             format.args=list(big.mark=",",floating=FALSE)) %>%
   kable_styling(c("bordered","condensed"),
                latex_options = c("hold_position"), 
                font_size = 10,
                full_width = F)


knitr::kable(comptables[[2]][1],
             caption="Table of Forecast Wealth Values: Suggested Three Years",
             format.args=list(big.mark=",",floating=FALSE))%>%
   kable_styling(c("bordered","condensed"),
                latex_options = c("hold_position"), 
                font_size = 10,
                full_width = F)

knitr::kable(comptables[[3]][1],
             caption="Table of Forecast Wealth Values: Suggested Five Years",
             format.args=list(big.mark=",",floating=FALSE))%>%
   kable_styling(c("bordered","condensed"),
                latex_options = c("hold_position"), 
                font_size = 10,
                full_width = F)

knitr::kable(comptables[[4]][1],
             caption="Table of Forecast Wealth Values: Suggested Ten Years",
             format.args=list(big.mark=",",floating=FALSE))%>%
   kable_styling(c("bordered","condensed"),
                latex_options = c("hold_position"), 
                font_size = 10,
                full_width = F)
```


```{r CompChart, echo=FALSE, warning=FALSE, fig.height=4, fig.show='hold', results='asis'}
horizons <- c(1,3,5,10)
par(mfrow=c(1,2))
minv<-min(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
maxv<-max(unlist(comptables[[1]][1]),unlist(comptables[[2]][1]),
          unlist(comptables[[3]][1]),unlist(comptables[[4]][1]))
for (h in 1:length(horizons)){
    wealth.pl.comp<-matrix(unlist(comptables[[h]][2],use.names = FALSE),ncol=3,byrow=FALSE)
    colnames(wealth.pl.comp)<-c("Cons.","Mod.","Aggr.")
    barplot(wealth.pl.comp,col=c("white","red","yellow","green","blue"),border=NA,
            main=paste("Forecast A/T Values -",horizons[h],"Years"),
            ylim=c(minv/2,maxv+minv/2))
    abline(h=250,col="darkgray")
}
par(mfrow=c(1,1))
```


\newpage    

#Section 2

This produces the following (screengrab from PDF)

Page 2 after title page

Page 3 after title page