2017-01-18 13 views
6

обратных кавычками Проблема

Моего внутреннего код кусок ломается, когда я filter() или select() имя столбца, который имеет белое пространство, которое я обычно определить с обратными кавычками в dplyr.Rmarkdown: написание встроенного кода 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

Можете ли вы использовать оператор-побег для обратных тиков? –

+3

Можете ли вы использовать одиночные или двойные тики? 'df%>% select ('a a' = a, 'b b' = b)' работает одинаково для меня (по крайней мере, на консоли). Единственный раз, когда я нахожу, что я * нуждаюсь * для использования обратных ссылок, ссылается (не использует) «СПЕЦИАЛЬНЫЕ» функции, такие как '' '% in%' ''. – r2evans

+2

Или, конечно, вы могли бы просто не делать причудливых вычислений inline. Определите фильтр 'res = df%>% (\' aa \ '== 1)%>% select (\' aa \ ')%>% as.numeric()' в вашем блоке/блоке, а затем '\' r res \ '' it inline. – Frank

ответ

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") 

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