Unexpected kable behavior when called from an application or from a function with a print statement

I am trying to understand the following two unexpected behavior of the kable function when knitting HTML using the knitr package (in RStudio 0.98.977 on Ubuntu 14.04):

  • When two kable calls are made internally, only the first call invokes a nice display in the final HTML.
  • When two kable calls are made from a function that also uses print statements, only the last call invokes a nice display in the final HTML.

The following is sample code:

Load library:

```{r init}
library("knitr")
```

Define dataframe:

```{r define_dataframe}
df <- data.frame(letters=c("a", "b", "c"), numbers=c(1, 2, 3))
rownames(df) <- c("x", "y", "z")
```

### Example 1: pretty display with simple call

The dataframe is displayed nicely twice when knitting HTML with the following code:

```{r pretty_display1, results="asis"}
kable(df)
kable(df)
```

### Example 2: unexpected display with lapply

The dataframe is displayed nicely only the first time when knitting HTML with the following code:

```{r unexpected_display1, results="asis"}
lst <- list(df, df)
lapply(lst, kable)
```

### Example 3: pretty display with function

The dataframe is displayed nicely twice when knitting HTML with the following code:

```{r pretty_display2, results="asis"}
foo1 <- function (df) {
  kable(df)
}
foo2 <- function (df) {
  foo1(df)
  foo1(df)
}
foo2(df)
```

### Example 4: unexpected display with function containing print statements

The dataframe is displayed nicely only the second time when knitting HTML with the following code:

```{r unexpected_display2, results="asis"}
foo1 <- function (df) {
  kable(df)
}
foo2 <- function (df) {
  print("first display")
  foo1(df)
  print("second display")
  foo1(df)
}
foo2(df)
```

Do you have an explanation for this strange behavior and how to get around them?

+4
source share
2 answers

kable ; , kable - . kable(df), , , .

lapply(lst, kable) , . :

lst <- list(df, df)
lapply(lst, kable)

:

|   |letters | numbers|
|:--|:-------|-------:|
|x  |a       |       1|
|y  |b       |       2|
|z  |c       |       3|


|   |letters | numbers|
|:--|:-------|-------:|
|x  |a       |       1|
|y  |b       |       2|
|z  |c       |       3|
[[1]]
[1] "|   |letters | numbers|" "|:--|:-------|-------:|"
[3] "|x  |a       |       1|" "|y  |b       |       2|"
[5] "|z  |c       |       3|"

[[2]]
[1] "|   |letters | numbers|" "|:--|:-------|-------:|"
[3] "|x  |a       |       1|" "|y  |b       |       2|"
[5] "|z  |c       |       3|"

, , . .

, . kable, output FALSE, for list, . , .

```{r nograpes1, results="asis"}
lst <- list(df, df)
for(x in lst) kable(x) # Don't create a list, just run the function over each element
```

```{r nograpes2, results="asis"}
lst <- list(df, df)
invisible(lapply(lst, kable)) # prevent the displaying of the result list.
```

```{r nograpes3, results="asis"}
lst <- list(df, df)
l <- lapply(lst, kable) # Store the list and do nothing with it.
```

, , for R, , , .

+4

nograpes lapply. .

print , . print kable, RMarkdown. RMarkdown , print kable. , kable .

RMarkdown, results="asis" , :

## [1] "first display"
## 
## 
## |   |letters | numbers|
## |:--|:-------|-------:|
## |x  |a       |       1|
## |y  |b       |       2|
## |z  |c       |       3|
## [1] "second display"  # <- here is the culprit! 
## 
## 
## |   |letters | numbers|
## |:--|:-------|-------:|
## |x  |a       |       1|
## |y  |b       |       2|
## |z  |c       |       3|

, second display , Markdown.

/ , cat. , RMarkdown .

```{r unexpected_display2, results="asis"}
foo1 <- function (df) {
  kable(df)
}
foo2 <- function (df) {
  cat("\n\nfirst display")
  foo1(df)
  cat("\n\nsecond display")
  foo1(df)
}
foo2(df)
```
+4

All Articles