num<-18.7
guess<- -1
print("Can you guess the daily dose per 1000 inhabititants in the UK?")
while(guess !=num) {
guess<-readline(prompt = "Enter integer:")
if (guess== num)
cat(num, "is correct")
if (guess<num)
cat("it is bigger")
if (guess>num)
cat("It is smaller")
}
It works when I play it through r script but when I knit it into markdown it doesn't get an error or anything but its been running for about 30 minutes and still hasn't finished. Is there a way to change this?
As mentioned in the comments, the R code in a R Markdown document is executed when it is knitted, not when it is viewed. When talking about interactivity for R, one usually thinks about Shiny. For some cases it is also possible to combine Shiny directly with R Markdown, c.f. https://bookdown.org/yihui/rmarkdown/shiny-documents.html. A straight forward conversion of your script gives:
---
runtime: shiny
output: html_document
---
# Can you guess the daily dose per 1000 inhabititants in the UK?
```{r setup, include=FALSE}
num <- 18.7
```
```{r guessing-game, echo=FALSE}
numericInput("guess", label = "Enter number:", value = 0)
renderText({
if (input$guess == num)
paste(num, "is correct")
else if (input$guess<num)
"it is bigger"
else if (input$guess>num)
"It is smaller"
})
```
Such a document can either be run locally or deployed. BTW, == is not the best choice for comparing floating point numbers. It is better to use isTRUE(all.equal()):
> 0.3 == 0.1 + 0.1 + 0.1
[1] FALSE
> isTRUE(all.equal(0.3, 0.1 + 0.1 + 0.1))
[1] TRUE
Related
Uses:
install.packages("bookdown")
library(bookdown)
GitHub: https://github.com/MartinJLambert/r-markdown_function_test
Given that I need to reproduce these values multiple times within the same document, I have created a function that calculates a simple ANOVA and determines the F, df, p and n statistics, as well as an asterix indicator for significance based on the p-value.
---
output:
bookdown::pdf_document2
---
```{r include= FALSE}
# function for calculating and displaying statistics results from an ANOVA
func_aov_stats <- function(input_df, input_var, input_factor) {
aov_tmp <- aov(input_var ~ input_factor, input_df)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")}
else if(anova_tmp[1,5] < 0.01){print("**")}
else if(anova_tmp[1,5] <0.05){print("*")}
else {print("")}
paste(anova_tmp[1,1], anova_tmp[1,4], anova_tmp[1,5], temp_signif, anova_tmp[2,1]+2)
}
```
`r func_aov_stats(mtcars, mtcars$mpg, mtcars$cyl)`
This is simple enough and knitting this does exactly what I want it to do.
1 79.5610275293349 6.11268714258098e-10 *** 32
However, numbers alone are kinda useless, so I would like to report it as a string of text. Something along these lines:
ANOVA: F(df=anova_tmp[1,1]) = anova_tmp[1,4], p
= anova_tmp[1,5] temp_signif, n = anova_tmp[2,1]+2
I was thinking of simply pasting the inline r-markdown inside the function:
paste("ANOVA: F~(df=`r anova_tmp[1,1]`)~ = `r anova_tmp[1,4]`, p = `r paste(anova_tmp[1,5] temp_signif)`, n = `r anova_tmp[2,1]+2`")
But I get this:
ANOVA: F(df=r anova_tmp[1,1]) = r anova_tmp[1,4], p = r anova_tmp[1,5] temp_signif, n = r anova_tmp[2,1]+2
At least the markdown formatting worked, but it obviously doesn't paste the 'r' components as hoped.
What does work, is if I write it out manually outside of the function, elsewhere in the markdown document:
```{r outside_of_function, include= FALSE}
aov_tmp <- aov(mpg ~ cyl, mtcars)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")} else if(anova_tmp[1,5] < 0.01){print("**")} else if(anova_tmp[1,5] <0.05){print("*")} else {print("")}
```
ANOVA: F~(df=`r anova_tmp[1,1]`)~ = `r anova_tmp[1,4]`, p = `r paste(anova_tmp[1,5], temp_signif)`, n = `r anova_tmp[2,1]+2`
ANOVA: F(df=1) = 79.5610275, p = 6.11268714258098e-10 ***, n = 32
So the issue is within the function itself. While it does seem to be able to produce the formatting, the computation of the 'r' code seems to require something beyond my understanding.
The solution is: paste0().
Full code, updated and fully functioning:
---
output:
bookdown::pdf_document2
---
```{r include = FALSE}
# function for calculating and displaying statistics results from an ANOVA
func_aov_stats <- function(input_df, input_var, input_factor) {
aov_tmp <- aov(input_var ~ input_factor, input_df)
anova_tmp <- anova(aov_tmp)
temp_signif <- if(anova_tmp[1,5] < 0.001){print("***")}
else if(anova_tmp[1,5] < 0.01){print("**")}
else if(anova_tmp[1,5] <0.05){print("*")}
else {print("")}
paste0("ANOVA: F~(df=",anova_tmp[1,1],")~= ",anova_tmp[1,4],", p = ",anova_tmp[1,5]," ",temp_signif," n = ",anova_tmp[2,1]+2)
}
```
`r func_aov_stats(mtcars, mtcars$mpg, mtcars$cyl)`
I am extremely new to R.
This simple code prints two outputs:
ec_lineal = function(a,b){
print(sprintf('%i x + %i = 0',a,b))
paste(sprintf('x ='), -b / a)
}
ec_lineal(5,3)
[1] "5 x + 3 = 0"
[1] "x = -0.6"
When I knit the code to HTML, I get separate boxes for each of the outputs:
Is there any way to combine both outputs in a single white box?
Maybe editing the code chunk header ```{r} ?
I am using R 3.6.3 and the latest version of RStudio in Windows 10.
Thank you.
You may use cat.
ec_lineal = function(a,b) {
cat(sprintf('%i x + %i = 0',a,b),
paste(sprintf('x ='), -b / a),
sep="\n")
}
ec_lineal(5,3)
# 5 x + 3 = 0
# x = -0.6
I'm looking for a nicely formated markdown output of test results that are produced within a for loop and structured with headings. For example
df <- data.frame(x = rnorm(1000),
y = rnorm(1000),
z = rnorm(1000))
for (v in c("y","z")) {
cat("##", v, " (model 0)\n")
summary(lm(x~1, df))
cat("##", v, " (model 1)\n")
summary(lm(as.formula(paste0("x~1+",v)), df))
}
whereas the output should be
y (model 0)
Call:
lm(formula = x ~ 1, data = df)
Residuals:
Min 1Q Median 3Q Max
-3.8663 -0.6969 -0.0465 0.6998 3.1648
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.05267 0.03293 -1.6 0.11
Residual standard error: 1.041 on 999 degrees of freedom
y (model 1)
Call:
lm(formula = as.formula(paste0("x~1+", v)), data = df)
Residuals:
Min 1Q Median 3Q Max
-3.8686 -0.6915 -0.0447 0.6921 3.1504
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.05374 0.03297 -1.630 0.103
y -0.02399 0.03189 -0.752 0.452
Residual standard error: 1.042 on 998 degrees of freedom
Multiple R-squared: 0.0005668, Adjusted R-squared: -0.0004346
F-statistic: 0.566 on 1 and 998 DF, p-value: 0.452
z (model 0)
and so on...
There are several results discussing parts of the question like here or here suggesting the asis-tag in combination with the cat-statement. This one includes headers.
Closest to me request seems to be this question from two years ago. However, even though highly appreciated, some of suggestions are deprecated like the asis_output or I can't get them to work in general conditions like the formattable suggestion (e.g. withlm-output). I just wonder -- as two years have past since then -- if there is a modern approach that facilitates what I'm looking for.
Solution Type 1
You could do a capture.output(cat(.)) approach with some lapply-looping. Send the output to a file and use rmarkdown::render(.).
This is the R code producing a *.pdf.
capture.output(cat("---
title: 'Test Results'
author: 'Tom & co.'
date: '11 10 2019'
output: pdf_document
---\n\n```{r setup, include=FALSE}\n
knitr::opts_chunk$set(echo = TRUE)\n
mtcars <- data.frame(mtcars)\n```\n"), file="_RMD/Tom.Rmd") # here of course your own data
lapply(seq(mtcars), function(i)
capture.output(cat("# Model", i, "\n\n```{r chunk", i, ", comment='', echo=FALSE}\n\
print(summary(lm(mpg ~ ", names(mtcars)[i] ,", mtcars)))\n```\n"),
file="_RMD/Tom.Rmd", append=TRUE))
rmarkdown::render("_RMD/Tom.Rmd")
Produces:
Solution Type 2
When we want to automate the output of multiple model summaries in the rmarkdown itself, we could chose between 1. selecting chunk option results='asis' which would produce code output but e.g. # Model 1 headlines, or 2. to choose not to select it, which would produce Model 1 but destroys the code formatting. The solution is to use the option and combine it with inline code that we can paste() together with another sapply()-loop within the sapply() for the models.
In the main sapply we apply #G.Grothendieck's venerable solution to nicely substitute the Call: line of the output using do.call("lm", list(.)). We need to wrap an invisible(.) around it to avoid the unnecessary sapply() output [[1]] [[2]]... of the empty lists produced.
I included a ". " into the cat(), because leading white space like ` this` will be rendered to this in lines 6 and 10 of the summary outputs.
This is the rmarkdown script producing a *pdf that can also be executed ordinary line by line:
---
title: "Test results"
author: "Tom & co."
date: "15 10 2019"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Overview
This is an example of an ordinary code block with output that had to be included.
```{r mtcars, fig.width=3, fig.height=3}
head(mtcars)
```
# Test results in detail
The test results follow fully automated in detail.
```{r mtcars2, echo=FALSE, message=FALSE, results="asis"}
invisible(sapply(tail(seq(mtcars), -2), function(i) {
fo <- reformulate(names(mtcars)[i], response="mpg")
s <- summary(do.call("lm", list(fo, quote(mtcars))))
cat("\n## Model", i - 2, "\n")
sapply(1:19, function(j)
cat(paste0("`", ". ", capture.output(s)[j]), "` \n"))
cat(" \n")
}))
```
***Note:*** This is a concluding remark to show that we still can do other stuff afterwards.
Produces:
(Note: Site 3 omitted)
Context
I was hit by the same need as that of OP when trying to generate multiple plots in a loop, but one of them would apparently crash the graphical device (because of unpredictable bad input) even when called using try() and prevent all the remaining figures from being generated. I needed really independent code blocks, like in the proposed solution.
Solution
I've thought of preprocessing the source file before it was passed to knitr, preferably inside R, and found that the jinjar package was a good candidate. It uses a dynamic template syntax based on the Jinja2 templating engine from Python/Django. There are no syntax clashes with document formats accepted by R Markdown, but the tricky part was integrating it nicely with its machinery.
My hackish solution was to create a wrapper rmarkdown::output_format() that executes some code inside the rmarkdown::render() call environment to process the source file:
preprocess_jinjar <- function(base_format) {
if (is.character(base_format)) {
base_format <- rmarkdown:::create_output_format_function(base_format)
}
function(...) {
# Find the markdown::render() environment.
callers <- sapply(sys.calls(), function(x) deparse(as.list(x)[[1]]))
target <- grep('^(rmarkdown::)?render$', callers)
target <- target[length(target)] # render may be called recursively
render_envir <- sys.frames()[[target]]
# Modify input with jinjar.
input_paths <- evalq(envir = render_envir, expr = {
original_knit_input <- sub('(\\.[[:alnum:]]+)$', '.jinjar\\1', knit_input)
file.rename(knit_input, original_knit_input)
input_lines <- jinjar::render(paste(input_lines, collapse = '\n'))
writeLines(input_lines, knit_input)
normalize_path(c(knit_input, original_knit_input))
})
# Add an on_exit hook to revert the modification.
rmarkdown::output_format(
knitr = NULL,
pandoc = NULL,
on_exit = function() file.rename(input_paths[2], input_paths[1]),
base_format = base_format(...),
)
}
}
Then I can call, for example:
rmarkdown::render('input.Rmd', output_format = preprocess_jinjar('html_document'))
Or, more programatically, with the output format specified in the source file metadata as usual:
html_jinjar <- preprocess_jinjar('html_document')
rmarkdown::render('input.Rmd')
Here is a minimal example for input.Rmd:
---
output:
html_jinjar:
toc: false
---
{% for n in [1, 2, 3] %}
# Section {{ n }}
```{r block-{{ n }}}
print({{ n }}**2)
```
{% endfor %}
Caveats
It's a hack. This code depends on the internal logic of markdown::render() and likely there are edge cases where it won't work. Use at your own risk.
For this solution to work, the output format contructor must be called by render(). Therefore, evaluating it before passing it to render() will fail:
render('input.Rmd', output_format = 'html_jinja') # works
render('input.Rmd', output_format = html_jinja) # works
render('input.Rmd', output_format = html_jinja()) # fails
This second limitation could be circumvented by putting the preprocessing code inside the pre_knit() hook, but then it would only run after other output format hooks, like intermediates_generator() and other pre_knit() hooks of the format.
I am writing an R Markdown document using the Python engine of {reticulate}. I am quite happy with how it works.
The only thing is, I cannot use r as a Python object name that I'm going to use in multiple chunks.
---
title: "Untitled"
output: html_document
---
## Object name `r`
```{python}
r = 10
print(r) ##> 10
```
```{python}
print(r) ##> <__main__.R object at 0x119ad37d0>
```
I understand r is a good name when we use R objects from within a Python chunk. Since I know I am not going to do that in my project, I would like to use r as a name for my Python object.
Is there any way to change the name, r, for the R object created by reticulate? Or, to tell reticulate not to create r object?
I am aware of the two straightforward workarounds
Don't use r for Python objects.
Write everything in one big chunk and not share r between Python chunks.
but I'd like to have more freedom.
The object name r is special since it is used to communicate between R and python. The same holds for py in R:
---
title: "Untitled"
output: html_document
---
## Object name `r`
```{python}
foo = 10
print(foo) ##> 10
```
```{r}
library(reticulate)
py$foo ##> [1] 10
```
```{r}
foo <- 10
```
```{python}
print(foo) ##> 10
print(r.foo) ##> 10.0
```
Avoiding the use of r as an opject name is therefore the only good possibility I can see.
Still working on the details but I think setting source and output knit hooks may help. My dirty first try looks like this:
---
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
library(knitr)
knitr::knit_hooks$set(
source = function(x, options) {
if (!is.null(options$rsub)) x = gsub(options$rsub, 'r', x, fixed = TRUE)
sprintf('<div class="%s"><pre class="knitr %s">%s</pre></div>\n', "source", tolower(options$engine), x)
},
output = function(x, options) {
if (!is.null(options$rsub)) x = gsub(options$rsub, 'r', x, fixed = TRUE)
paste0('<pre><code>', x, '</code></pre>\n')
}
)
```
```{python, rsub='rrr'}
rrr = 10
print(rrr)
```
```{python, rsub='rrr'}
print(rrr)
```
I'm creating a R Markdown document using knitr and am running into trouble using xtable to create a table. My table is very large and I'm trying to reduce the size using the size command in the print statement. The issue I'm running into is that the command seems to add two extra curly braces which show up in the PDF, one before the table and one after.
Does anyone know a way to fix this?
MWE:
---
output:
pdf_document:
keep_tex: yes
tables: true
---
```{r, results='asis', echo=FALSE}
library(xtable)
my.df <- data.frame(matrix(c(1:18),nrow=2))
glossaryprint <- xtable(my.df, caption="Summary of Terms")
print(glossaryprint,
comment=FALSE,
floating=FALSE,
size="footnotesize"
)
```
Note: The issue that is subject of the question and this answer has been resolved in xtable 1.8-2.
Although the question has been self-answered with a workaround, I think for other users some more details might be helpful.
What happens?
To understand what is happening here, we need to take a close look at the conversion steps the document undergoes on its way from RMD to PDF. The steps are:
RMD --> MD --> TEX --> PDF
Let's look at the files in reversed order:
PDF: (generated from TEX by pdflatex)
TEX: (generated from MD by pandoc)
% …
\{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
\}
% …
MD (generated from RMD by knitr)
---
output:
pdf_document:
keep_tex: yes
---
{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
}
RMD: (source file)
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
print(mytable,
comment = FALSE,
floating = FALSE,
size = "footnotesize"
)
```
Recall: The problem is, that there are visible curly braces in the PDF. Where do they come from?
They are the result of the escaped curly braces in the TEX file (\{ and \}).
These curly braces also exist in the MD file, but there they are not escaped.
So we know two things by now: We see the curly braces because they are escaped and they are escaped by pandoc.
But why do these curly braces exist at all? print.xtable outputs them when a size is specified. The goal is to create a group and to apply size only within that group. (With floating = TRUE, no grouping by curly braces is required because there is a figure environment whithin which the size is set. The curly braces are printed anyways.)
And why does pandoc escape that pair of curly braces but leaves all the other curly braces (e.g. in \begin{tabular}) unescaped? This is because pandoc is supposed to escape special characters that are meant literally but leave raw LaTeX unescaped. However, pandoc does not know that the outer curly braces are LaTeX commands and not text.
(With floating = TRUE the problem does not occur because the curly braces are within a figure environment which is recognized as LaTeX.)
Solutions
After having understood the problem, what can we do about it? One solution has already been posted by the OP: Abstain from spefifying size in print.xtable and insert the footnotesize command manually:
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
cat("\\begin{footnotesize}")
print(mytable,
comment = FALSE,
floating = FALSE
)
cat("\\end{footnotesize}")
```
However, on the long run it would be nice if xtable (current version: 1.8-0) generated LaTeX code that survives the pandoc conversion. This is quite simple: print.xtable checks if size is set and if so, inserts { before the size specification and } at the end of the table:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("{", size, "\n", sep = "")
ESIZE <- "}\n"
}
This small modification replaces { with \begingroup and } with \endgroup:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("\\begingroup", size, "\n", sep = "")
ESIZE <- "\\endgroup\n"
}
For LaTeX, this makes no difference, but as pandoc recognizes \begingroup (as oppsed to {) it should solve the problem. I reported this as a bug in xtable and hopefully the issue will be fixed in future versions.
I was able to fix this by not including the size parameter in the print statement but rather directly before and after the chunk.
\begin{footnotesize}
#chunk
\end{footnotesize}