从lappy或从带有print语句的函数调用时,kable的意外行为
我试图理解使用knitr包编织HTML时kable函数的以下两个意外行为(在Ubuntu 14.04上的RStudio 0.98.977中):从lappy或从带有print语句的函数调用时,kable的意外行为,r,knitr,rstudio,lapply,R,Knitr,Rstudio,Lapply,我试图理解使用knitr包编织HTML时kable函数的以下两个意外行为(在Ubuntu 14.04上的RStudio 0.98.977中): 当从lappy中调用两个kable时,只有第一个调用在最终的HTML中生成一个漂亮的显示 当在一个也使用print语句的函数中进行两次kable调用时,只有最后一次调用在最终的HTML中生成一个漂亮的显示 下面编写了一个示例代码: Load library: ```{r init} library("knitr") ``` Define datafr
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)
```
加载库:
```{r init}
图书馆(“knitr”)
```
定义数据帧:
```{r define_dataframe}
dfkable的输出是副作用;您可以将输出值存储在变量中,但只需运行kable
即可将某些内容输出到控制台。当您运行两次kable(df)
时,这不是问题,您没有存储任何内容,并且函数将输出转储到控制台两次
但是,当您运行lappy(lst,kable)
时,该函数将输出转储到控制台,然后显示列表的值。请尝试在控制台中运行此命令:
lst <- list(df, df)
lapply(lst, kable)
请注意如何输出正确的标记,然后显示您创建的列表的实际值。这就是造成不良输出的原因
功能范式对副作用的作用不是特别好,所以你有两种选择。通过将output
参数设置为FALSE
,您可以存储kable
的结果,或者您可以使用for
来浏览列表
,或者您可以阻止显示结果列表。下面是一些有用的例子
```{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=1,results=“asis”}
lstnograps为您关于lappy
的问题提供了一个很好的答案。在这里,我试图回答你问题的另一部分
print
函数的副作用是将字符串打印到输出中。第一个print
函数在kable
调用后立即调用,该调用在RMarkdown表语法后追加一行。由于RMarkdown语法要求在表格前后都有换行符,因此print
函数会污染kable
输出。因此,第一个kable
输出未正确解析到表中
如果从区块中删除results=“asis”
部分,可以打印原始RMarkdown输出,以便查看打印:
## [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|
@nog油菜:)。你在第一部分也打败了我。谢谢你们两位的详细回答!谢谢你的回答!这很有道理。然而,在lappy(lst,kable)
情况下(应该避免,因为您提供了很好的替代方案),我仍然对控制台和HTML显示之间的差异感到困惑。在控制台中,通过副作用打印的两张表是相同的。在HTML输出中,仅正确显示通过副作用生成的第一个表。你知道为什么会发生这种情况吗?@sebastien_vigneau这是因为lappy
(这是一个列表)的返回值被转换成字符串,并立即附加到第二个kable
调用的输出中,造成与您在print
调用中遇到的问题相同的问题。@XinYin现在一切都有意义:)再次感谢您!当您将kable
放入for
循环中时,您不应该按照kable
帮助的建议使用print(kable(…)
?否则就没有任何输出。
## [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|
```{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)
```