Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何在评估内容后有条件地排除块?_R_R Markdown_Knitr - Fatal编程技术网

R 如何在评估内容后有条件地排除块?

R 如何在评估内容后有条件地排除块?,r,r-markdown,knitr,R,R Markdown,Knitr,我正在Rmarkdown中创建一个参数化的报告,而有些区块不应该根据区块内内容的特征进行评估(包括在报告中) 该报告对约120个设施进行了大规模调查,计算了各个设施的汇总,这些设施中有不同数量的单元。此外,单元大小和体积在很大程度上是可变的,因此,如果每个单元的有效答案数小于10,我们将排除单元分析(这已在dataframe对象中重新编码为NA)。因此,我需要编写一个语句,其中一个对象中的NA的数量是按单位计算的,如果每个单位只有NA,我希望在块上执行include=FALSE。这将需要重复约5

我正在Rmarkdown中创建一个参数化的报告,而有些区块不应该根据区块内内容的特征进行评估(包括在报告中)

该报告对约120个设施进行了大规模调查,计算了各个设施的汇总,这些设施中有不同数量的单元。此外,单元大小和体积在很大程度上是可变的,因此,如果每个单元的有效答案数小于10,我们将排除单元分析(这已在dataframe对象中重新编码为NA)。因此,我需要编写一个语句,其中一个对象中的NA的数量是按单位计算的,如果每个单位只有NA,我希望在块上执行include=FALSE。这将需要重复约50个区块,因此我尝试使用eval.after

Martin Schmelzer的评论让我意识到我有两个不同的问题:

1) 我需要使用正则表达式在区块内的自写函数中检测对象的名称

2) 我需要设置一个函数,用于在块中有条件地计算eval.after

对于问题1):需要检查eval.after的R区块如下所示:

```{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
应用于哪些选项受到限制)。因此,要获得所需的内容,您需要两个区块:

  • 计算到足以确定是否应计算和显示块。如果不需要显示,请隐藏此块

  • 在下一个区块中,如果要显示计算,请重复计算,并显示结果,所有这些都以先前计算的结果为条件

  • 您的示例不可复制,因此这里有一个简单的示例。假设我只想在其值大于10时显示
    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
    的角色是什么?我添加了一些行。