R 如何在评估内容后有条件地排除块?
我正在Rmarkdown中创建一个参数化的报告,而有些区块不应该根据区块内内容的特征进行评估(包括在报告中) 该报告对约120个设施进行了大规模调查,计算了各个设施的汇总,这些设施中有不同数量的单元。此外,单元大小和体积在很大程度上是可变的,因此,如果每个单元的有效答案数小于10,我们将排除单元分析(这已在dataframe对象中重新编码为NA)。因此,我需要编写一个语句,其中一个对象中的NA的数量是按单位计算的,如果每个单位只有NA,我希望在块上执行include=FALSE。这将需要重复约50个区块,因此我尝试使用eval.after Martin Schmelzer的评论让我意识到我有两个不同的问题: 1) 我需要使用正则表达式在区块内的自写函数中检测对象的名称 2) 我需要设置一个函数,用于在块中有条件地计算eval.after 对于问题1):需要检查eval.after的R区块如下所示:R 如何在评估内容后有条件地排除块?,r,r-markdown,knitr,R,R Markdown,Knitr,我正在Rmarkdown中创建一个参数化的报告,而有些区块不应该根据区块内内容的特征进行评估(包括在报告中) 该报告对约120个设施进行了大规模调查,计算了各个设施的汇总,这些设施中有不同数量的单元。此外,单元大小和体积在很大程度上是可变的,因此,如果每个单元的有效答案数小于10,我们将排除单元分析(这已在dataframe对象中重新编码为NA)。因此,我需要编写一个语句,其中一个对象中的NA的数量是按单位计算的,如果每个单位只有NA,我希望在块上执行include=FALSE。这将需要重复约5
```{r leadership unit, eval=exclude_ifnot_unitC }
kable.unit.tblc(unitblc_leadership, caption = "Führung")
```
```{r leadership unit, eval.after=include_if_valid }
kable.unit.tblc(unitblc_leadership, caption = "Führung")
```
kable.unit.tblc(df,caption)
是一个自行编写的函数,它实现kableExtra()函数来设置表的样式,第一个输入是一个数据帧(预先在R文件中创建)。我现在应该使用正则表达式从数据块中提取数据帧的名称,这意味着从kable.unit.tblc(
到,caption
的所有内容
到目前为止,我在正则表达式的第一步中尝试了这一点,但我无法获得介于这两个表达式之间的对象:
x <- 'kable.unit.tblc(unitblc_leadership, caption = "Führung")'
stringr::str_extract(x, "^kable.unit.tblc\\(")
stringr::str_extract(x, ", caption")
正如您所看到的,我需要test\u对象
,该对象应该在之前使用函数派生出来,但我不确定我的意图是否可行
然后,该块应该如下所示:
```{r leadership unit, eval=exclude_ifnot_unitC }
kable.unit.tblc(unitblc_leadership, caption = "Führung")
```
```{r leadership unit, eval.after=include_if_valid }
kable.unit.tblc(unitblc_leadership, caption = "Führung")
```
编辑:我觉得太复杂了-Martin的这个解决方案效果很好:
include_if_valid <- function(df) {
if (df %>%
select_if(is.numeric) %>%
summarise_all(.funs = list(~n.valid)) %>%
gather(key = "Unit", value = "nvalid") %>%
pull() %>% sum() > 0) {TRUE} else {FALSE}
}
您可以将区块选项
results
更改为“hide”
,但这必须在开始评估区块之前进行(因为eval.after
应用于哪些选项受到限制)。因此,要获得所需的内容,您需要两个区块:
x
:
```{r include=FALSE}
# compute x as a random value between 9 and 11, but don't display anything
x <- runif(1, 9, 11)
```
```{r include = x > 10}
# display x conditional on its value being > 10
x
```
`{r include=FALSE}
#将x计算为9到11之间的随机值,但不显示任何内容
x10}
#显示x的条件是其值大于10
x
```
这里有一种方法可以将数据作为块选项注入,检查其有效性,并根据结果打印一个kable条件。很好的一点是,我们可以引用第一个通用块,并使用不同的数据帧调用它
使用knit\u hooks$set
我们创建了一个新的名为df
。如果(之前)中的所有内容都将在计算块本身之前进行计算。参数options
包含为当前块设置的所有块选项,而envir
就是块环境
---
title: "Conditional Evaluation"
output: html_document
---
```{r setup, include = F}
library(dplyr)
library(knitr)
A <- data.frame(A = LETTERS[1:4])
B <- data.frame(B = rep(NA, 4))
C <- data.frame(C = letters[1:4])
include_if_valid <- function(df) {
return(all(!is.na(df)))
}
knit_hooks$set(df = function(before, options, envir) {
if (before) {
assign("valid", include_if_valid(options$df), envir = envir)
}
})
```
```{r generic, df = A, echo = F}
if(valid) kable(opts_current$get("df"))
```
```{r ref.label="generic", df = B, echo = F}
```
```{r ref.label="generic", df = C, echo = F}
```
---
标题:“条件评估”
输出:html\u文档
---
```{r设置,include=F}
图书馆(dplyr)
图书馆(knitr)
A你能整理一下你的例子吗?第二部分是函数定义?kable.unit.tblc的定义?eval.after='include'
和include=!unitblc_leadership
应该可以。@MartinSchmelzer谢谢你,我编辑了这个例子-我想找到一种自动化的方法,否则我就得如果我想在每个报告中包括或排除(约120x50次),请选中每个单元慢一点,我无法理解。为什么要排除数据帧的名称?您还可以将数据帧作为块选项输入,在对块进行评估之前对其进行评估和处理。我花了这么多时间,解决方案非常简单-是的,只需将数据帧的名称放在包含函数中就可以了!-破解代码,但@MartinSchmelzer谢谢你!谢谢你的工作reprex-我不确定我是否能遵循代码:什么是knit_hooks$set(df=function(before,options,envir){…}
确切的evluate?以及envir
的角色是什么?我添加了一些行。