Reference variable name containing spaces within text in Rmarkdown [duplicate] - r

How can I include inline R code that refers to a variable name that contains spaces or other unusual characters (actual use-case is Pr(>F))? Backticks are the solution in plain R script, but they don't seem to work when the code is inline in a markdown doc. Here's an example:
```{r}
df <- data.frame(mydata= 1:10, yourdata = 20:29)
names(df) <- c("your data", "my data")
```
The first five values of your data are `r df$`your data`[1:5]`
Which when knitted gives:
Quitting from lines 7-9 (test-main.Rmd)
Error in base::parse(text = code, srcfile = NULL) :
2:0: unexpected end of input
1: df$
^
Calls: <Anonymous> ... <Anonymous> -> withVisible -> eval -> parse_only -> <Anonymous>
Execution halted
Note that this is different from showing the backticks. All I want to do is have the code executed when the the doc is knitted. My workaround is to assign the value of the odd-named variable to another object with a simple name in the chunk preceding the inline code. But I'm curious about how to directly call inline these objects with unusual names.

In this instance can use normal quotes,
The first five values of your data are `r df$"your data"[1:5]`
or rather
The first five values of your data are `r df[["your data"]][1:5]`

Related

"Error in kmeans(na.omit(reduced_data_numeric, 5)) : 'centers' must be a number or a matrix" message when attempting to knit an Rmd as a HTML

I am presented with an error message when trying to knit an Rmd script. I have tried to drop any NA's from the data being used for lines 363-364 but this did not work. It is annoying because the k-means has been run and I have been able to plot using some simple code, but for some reason it won't knit. This was the original code that worked:
KM <- kmeans(reduced_data_numeric, 5)
Here is the Code I am trying to use in order for it to knit:
KM <- kmeans(na.omit(reduced_data_numeric, 5))
Here is the message shown in 'output' section when trying to render the HTML knit:
Quitting from lines 363-364 (Movies-Analysis.Rmd)
Error in kmeans(na.omit(reduced_data_numeric, 5)) :
'centers' must be a number or a matrix
Calls: <Anonymous> ... withVisible -> eval_with_user_handlers -> eval -> eval -> kmeans
You've included the number of centers as an argument for na.omit rather than kmeans.
Note where the parenthesis are at the end of this line and where the 5 is:
KM <- kmeans(na.omit(reduced_data_numeric), 5)

Inexplicable error when trying to export my R notebook

Getting this error from R Markdown when trying to export my .RMD
"Error in filter(Gastropods, Species == "Cellana") : object 'Species' not found Calls: <Anonymous> ... withCallingHandlers -> withVisible -> eval -> eval -> filter"
However, all my plots are coming out successfully. I can clearly see in the data that the species column is there and that Cellana is a species. No spelling errors or anything.
My first 20 or so lines of code are below
###
---
title: " Lab Report 2 - z5016113"
output: html_notebook
i---
#1. Gastropod abundance vs. height on the shore
```{r}
Gastropods <- read.csv(file = "MaroubraZones.csv", header = TRUE)
library(ggplot2, dplyr)
```
```{r}
Gastropods$Zone <- factor(Gastropods$Zone, levels = c("Low", "Mid", "High"))
```
```{r}
Cellana <- filter(Gastropods, Species == "Cellana") ------> This line is causing the error
```
```{r}
ggplot(Cellana, aes(Zone, Abundance)) + geom_boxplot()
```
###
It looks like this might be a bigger issue with DPLYR and filter and I found other posts suggesting they had the same problem and the answer seemed to add dplyr::filter rather than just filter in the command. Link to a similar issue
It might also be worth testing this by filtering out the mollusc of interest before you convert it to a factor?
I have also had similar issues filtering items out and a restart of R fixed the issue.
dplyr::filter has not been found because you haven't loaded dplyr, but since there are other function named filter in other packages, it tries to apply those instead (and fails).
From ?library:
library(package, [...])
[...]
package the name of a package, given as a name or literal
character string, or a character string, depending on whether
character.only is FALSE (default) or TRUE).
This means you can only load one package at a time. Here, you are trying to load both ggplot2 and dplyr in the same call. Only ggplot2 is loaded. The correct way to do this is:
library(dplyr)
library(ggplot2)

Rmarkdown: writing inline dplyr code if column names have spaces defined with backticks

Problem
My inline code chunk breaks when I filter() or select() a column name that has white space that I would normally define with backticks in dplyr.
Example Data
```{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)
```
Inline code chunk
I'm trying something like `r df %>% filter(`a a` == 1) %>% select(`a a`) %>% 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 (the backticks end the inline code chunk). I could rename the columns in a code chunk after the intext calculations (I'm formatting them for a table), but it would be frustrating to have to break it up.
Costly lazyeval solution
This solves the problem r df %>% filter_(interp(~ which_column == 1, which_column = as.name("a a"))) %>% select_(as.name("a a")) %>% as.numeric(), but there has got to be a better way.
I am not sure how you are running things - here I provide an answer with respect to knitr.
There is no easy solution for this case, and the work-around of moving some code inside the chunks (as suggested in one of the comments) is probably the way to go.
For future reference and further insight, I'll still share the underlying problem and an alternative solution.
Note that knitr makes use of the following pattern for inline.code (given you are using Rmarkdown format):
knitr::all_patterns$md$inline.code
[1] "`r[ #]([^`]+)\\s*`"
Now the function knitr:::parse_inline matches this through a call to stringr::str_match_all, which will detect patterns of one or multiple non-backticks ([^`]+), followed by zero or multiple space-class elements (\\s*), followed by a back-tick.
So it will end on the first backtick following `r, more or less no matter what. This makes some sense, since the lines of input are collapsed in parse_inline and there could actually be multiple inline-code statements and plain text containing back-ticks in the resulting string.
If you however restrict yourself to some conventions, you could modify the pattern to detect the end of inline code pieces differently. Below I am assuming that I always break onto a new line following a piece of inline code, so e.g. following your setup chunk I only have the following:
Hello there.
`r DF %>% filter(`a a` == 1) %>% select(`a a`) %>% as.numeric()`
This should read 1 above here.
Then I can knit in the following way, modifying the pattern to take everything until a backtick followed by a new-line 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 pattern that works for everyone seems impossible though.

R Markdown inline code not executed

I have an inline code enclosed with single backticks on a single line.
However,
The cohort had r echo = FALSE load("../data/cohort.rda") nrow(cohort) subjects.
is not executed and thus gives me this output in html and pdf:
The cohort had r echo = FALSE load("../data/cohort.rda") nrow(cohort) subjects.
I want this output: The cohort had 477 subjects.
When I exclude echo=FALSE, I get this message:
Quitting from lines 33-35 (Manuscript.Rmd)
Error in base::parse(text = code, srcfile = NULL) :
1:25: unexpected symbol
1: load("../data/cohort.rda") nrow
^
Calls: ... inline_exec -> withVisible -> eval -> parse_only ->
Execution halted
The inline R code needs to be a single R statement, which you can achieve by surrounding the entire code chunk with brackets {} and separating commands with semicolons. I saved a 3-row data frame named tmp to file tmp.rda, rendered an Rmd file with this line
There are `r {load("tmp.rda"); nrow(tmp)}` observations
and got the expected output.

How to output to pdf using knitr/xtable when tex has square braces ( [ )?

I am trying to output the freq table generated by cut to a PDF file using knitr and xtable. However, when I include the option include.rownames=FALSE the output is not processed and an error is reported whereas the code works with include.rownames=TRUE. Test code is below:
\documentclass[12pt]{article}
\begin{document}
<<test_table, results = "asis",echo=FALSE>>=
library(xtable)
x <- sample(10,100,replace=TRUE)
breaks <- c(1,2,5,10)
x.freq <- data.frame(table(cut(x, breaks, right=FALSE)))
print(xtable(x.freq),include.rownames=TRUE)
#
\end{document}
When I use include.rownames=TRUE I get the output below.
1 [1,2) 5
2 [2,5) 35
3 [5,10) 49
whereas when I use include.rownames=FALSE I get an error:
Test.tex:71: LaTeX Error: \begin{tabular} on input line 58 ended by \end{document}.
I believe that I am getting the error because of the presence of the square braces ' [ ' in the text source.
Does anyone know how to solve this problem?
The problem is that the end of each row in the table is a \\ which has an optional argument to specify how much space to leave before the next row, for example, \\[1in]. There's allowed to be white space between the \\ and the [, so in this case, it's trying to read the [2,5) as that argument.
A simple workaround would be to change the labels of the factor to include some non-printing blank character first, however, if you do so, by default, print.xtable will "sanitize" it so that it actually does print, so you'd need to turn that off by passing a new sanitize function; identity will do none of this fixing.
levels(x.freq$Var1) <- paste0("{}", levels(x.freq$Var1))
print(xtable(x.freq),include.rownames=FALSE, sanitize.text=identity)

Resources