Rmarkdown:如果列名用反引号定义了空格,则编写内联dplyr代码

时间:2017-01-18 20:18:29

标签: r dplyr r-markdown backticks inline-code

问题

我的内联代码块在我filter()select()具有空格的列名时断开,我通常会在dplyr中使用反引号定义。

示例数据

    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    library(dplyr)
    library(knitr)
    library(lazyeval)

    df <- structure(list(1:3, 2:4), .Names = c("a", "b"), row.names = c(NA, -3L), class = "data.frame")

    df <- df %>% select(`a a`=a, `b b`=b)
    ```

内联代码块

我正在尝试类似`r df %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`的内容,但我收到以下错误:

    Error in base::parse(text = code, keep.source = FALSE) : <text>:2.0: unexpected end of input 1: df %>% filter( ^ Calls: <Anonymous> ... inline_exec -> withVisible -> eval -> parse_only -> <Anonymous>

...原因很明显(反引号结束了内联代码块)。我可以在进行intext计算之后重命名代码块中的列(我正在为表格格式化它们),但是必须将其分解是令人沮丧的。

费用lazyeval解决方案

这解决了问题r df %>% filter_(interp(~ which_column == 1, which_column = as.name("a a"))) %>% select_(as.name("a a")) %>% as.numeric(),但必须有更好的方法。

1 个答案:

答案 0 :(得分:1)

我不确定你是如何运作的 - 在这里我提供了关于knitr的答案。

对于这种情况没有简单的解决方案,并且在块中移动一些代码(如其中一条评论中所建议的)的解决方法可能是要走的路。

为了将来的参考和进一步的见解,我仍然会分享潜在的问题和替代解决方案。

请注意knitrinline.code使用以下模式(假设您使用的是Rmarkdown格式):

knitr::all_patterns$md$inline.code
[1] "`r[ #]([^`]+)\\s*`"

现在函数knitr:::parse_inline通过调用stringr::str_match_all来匹配它,它将检测一个或多个非反引号([^`]+)的模式,然后是零或多个空格类元素(\\s*),然后是反向标记。

所以它会在`r之后的第一个反推结束时结束,无论如何都会或多或少。这是有道理的,因为输入行在parse_inline中折叠,并且实际上可能有多个内联代码语句和包含结果字符串中的反向标记的纯文本。

如果您限制自己使用某些约定,则可以修改模式以不同方式检测内联代码片段的结尾。下面我假设我总是按照一段内联代码进入一个新行,例如跟随你的setup块我只有以下内容:

Hello there.

`r DF %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`

This should read 1 above here.

然后我可以用以下方式编织,修改模式以获取所有内容,直到后退,然后是换行:

library(knitr)
opts_knit$set('verbose' = TRUE)
knit_patterns$set(all_patterns$md)
inline.code.2 <- "`r[ #](.+)\\s*`\n"
knitr::knit_patterns$set(inline.code = inline.code.2)

knit2html("MyRmarkdownFile.rmd")
browseURL("MyRmarkdownFile.html")

找到适合每个人的这种模式的一般规则似乎是不可能的。

相关问题