Rmarkdown:如果列名有空格,并使用反引号定义,如何编写内联dplyr代码

11

问题

当我使用 dplyr 中的 filter() 或者 select() 对一个列名包含空格的列进行操作时,我的内联代码块会出现错误。通常我会使用反引号来定义这种情况。

示例数据

    ```{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
你可以使用转义运算符来处理反引号吗? - Ryan Morton
3
您能使用单引号或双引号吗?df %>% select('a a'=a, 'b b'=b)对我来说效果一样(至少在控制台上)。我发现唯一需要使用反引号的情况是引用(而不是使用)“SPECIAL”函数,例如%in% - r2evans
4
当然,你也可以不要在行内进行复杂的计算。在块中定义res = df %>% filter(\a a` == 1) %>% select(`a a`) %>% as.numeric(),然后将`r res``插入行内。 - Frank
@r2evans 谢谢,但是单引号/双引号对我不起作用。我得到错误:所有select()输入必须解析为整数列位置。以下内容不行:*“a a” - sullij
@RyanMorton,转义运算符对我不起作用。 - sullij
@Frank 是的,没错。 - sullij
1个回答

1

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

对于这种情况,没有简单的解决方案,将一些代码移动到块内(如评论中建议的)可能是正确的方法。

为了以后的参考和更深入的了解,我仍然会分享潜在问题和另一种解决方案。

请注意,knitr使用以下模式来处理inline.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")

找到适用于每个人的此模式的通用规则似乎是不可能的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接