Rmarkdown: написание встроенного кода dplyr, если в именах столбцов заданы пробелы

проблема

Мой встроенный код ломается, когда я 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 ответ

Я не уверен, как вы работаете вещи - здесь я даю ответ относительно knitr,

Для этого случая не существует простого решения, и обходной путь перемещения некоторого кода внутри чанков (как предлагается в одном из комментариев), вероятно, является подходящим способом.

Для дальнейшего использования и дальнейшего понимания я все же поделюсь основной проблемой и альтернативным решением.

Обратите внимание, что knitr использует следующий шаблон для inline.code (если вы используете формат Rmarkdown):

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

Теперь функция knitr:::parse_inline соответствует этому через вызов stringr::str_match_all, который будет обнаруживать паттерны одного или нескольких не-backticks ([^`]+), за которым следует ноль или несколько элементов класса пространства (\\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")

Найти общее правило для этого шаблона, которое работает для всех, кажется невозможным.

Другие вопросы по тегам