Rmarkdown: write inline dplyr code if column names have spaces defined using backlinks

Problem

My line of inline code breaks when I filter() or select() name of a column that has a space, which I would normally define with return outputs in dplyr.

Data examples

  ```{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(`aa`=a, `bb`=b) ``` 

Inline Code String

I'm trying something like `r df %>% filter(`aa` == 1) %>% select(`aa`) %>% as.numeric()` , but I get the following error:

  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> 

... for pretty obvious reasons (backticks complete a piece of inline code). I could rename the columns in the code block after the intext calculations (I format them for the table), but it would be unpleasant to break it.

Costly lazyeval solution

This solves the problem r df %>% filter_(interp(~ which_column == 1, which_column = as.name("aa"))) %>% select_(as.name("aa")) %>% as.numeric() , but there must be a better way.

+6
source share
1 answer

I'm not sure how you work. Here I give an answer to knitr .

In this case, there is no simple solution, and probably the way to move some code inside the pieces (as suggested in one of the comments) is the way to go.

For future reference and further understanding, I will continue to share the main problem and an alternative solution.

Note that knitr uses the following template for inline.code (if you use the Rmarkdown format):

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

Now the knitr:::parse_inline function corresponds to this call to stringr::str_match_all , which will detect patterns of one or more non-reverse steps ( [^`]+ ), followed by zero or more elements of the space class ( \\s* ), for followed by a backward mark.

Thus, it will end on the first digression after `r , more or less no matter what. This makes sense, since input lines are discarded in parse_inline , and the resulting line may contain several inline code statements and plain text containing back ticks.

However, if you restrict yourself to certain conventions, you can modify the template to define the end of lines of inline code in different ways. Below I assume that I always break on a new line, following a piece of inline code, for example, after your setup block, I have only the following:

 Hello there. `r DF %>% filter(`aa` == 1) %>% select(`aa`) %>% as.numeric()` This should read 1 above here. 

Then I can knit as follows, changing the pattern to take everything until the back side is followed by a newline break:

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

Finding a general rule for this template that works for everyone seems impossible, though.

+1
source

Source: https://habr.com/ru/post/1014193/


All Articles