从lapply或带print语句的函数中调用kable时,其行为异常 [英] Unexpected behavior of kable when called from lapply or from function with print statement

查看:86
本文介绍了从lapply或带print语句的函数中调用kable时,其行为异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试使用knitr软件包编织HTML时(在Ubuntu 14.04上的RStudio 0.98.977中),我试图了解kable函数的以下两个意外行为:

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

  1. 从lapply内两次调用kable时,只有第一个调用会在最终的HTML中产生漂亮的显示.
  2. 当在同样使用print语句的函数中进行两次kable调用时,只有最后一次调用会在最终HTML中产生漂亮的显示.

下面是一个示例代码:

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 to these strange behaviors and how to circumvent them?

推荐答案

kable的输出是副作用.您可以将输出的值存储在变量中,但是仅运行kable就会将某些内容输出到控制台.两次运行kable(df)时,这不是问题,您什么也不存储,该函数两次将输出转储到控制台.

The output of kable is a side-effect; you can store the value of the output in a variable, but just running kable will output something to console. When you run kable(df) twice, this isn't a problem, you aren't storing anything, and the function dumps the output to the console twice.

但是,当您运行lapply(lst, kable)时,该函数将输出转储到控制台,然后显示列表的值.尝试仅在控制台中运行它:

However, when you run lapply(lst, kable), the function dumps the output to the console and then the value of the list is displayed. Try running this just in your console:

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

您应该完全明白这一点:

You should get exactly this:

|   |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|"

注意如何输出正确的减价,然后显示您创建的列表的实际值.这就是造成不良输出的原因.

Notice how the correct markdown is output, and then the actual value of the list you created is displayed. This is what creates the bad output.

功能范式在副作用方面效果不佳,因此有两种选择.您可以通过将output参数设置为FALSE来存储kable的结果,或者可以仅使用for浏览list,或者可以防止显示结果列表.这是一些可行的示例.

The functional paradigm doesn't work particularly well with side-effects, so you have a couple of options. You can store the results of kable by setting the output parameter to FALSE, or you can just use a for to go through your list, or you could prevent the displaying of the result list. here are some examples that will work.

```{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.
```

我认为,这是在R中应使用for 的一个很好的例子,因为它最清楚地表达了您要如何使用基于副作用的函数.

In my opinion, this is a nice example of when for should be used in R, as it most cleanly expresses how you want to use a side-effect based function.

这篇关于从lapply或带print语句的函数中调用kable时,其行为异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆