R knitr Markdown: Output Plots within For Loop
Solution 1
Wrap the qplot
in print
.
knitr
will do that for you if the qplot
is outside a loop, but (at least the version I have installed) doesn't detect this inside the loop (which is consistent with the behaviour of the R command line).
Solution 2
Wish to add a quick note:
Somehow I googled the same question and get into this page.
Now in 2018, just use print()
in the loop.
for (i in 1:n){
...
f <- ggplot(.......)
print(f)
}
Solution 3
I am using child Rmd files in markdown, also works in sweave.
in Rmd use following snippet:
```{r run-numeric-md, include=FALSE}
out = NULL
for (i in c(1:num_vars)) {
out = c(out, knit_child('da-numeric.Rmd'))
}
```
da-numeric.Rmd looks like:
Variabele `r num_var_names[i]`
------------------------------------
Missing : `r sum(is.na(data[[num_var_names[i]]]))`
Minimum value : `r min(na.omit(data[[num_var_names[i]]]))`
Percentile 1 : `r quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[2]`
Percentile 99 : `r quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[100]`
Maximum value : `r max(na.omit(data[[num_var_names[i]]]))`
```{r results='asis', comment="" }
warn_extreme_values=3
d1 = quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[2] > warn_extreme_values*quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[1]
d99 = quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[101] > warn_extreme_values*quantile(na.omit(data[[num_var_names[i]]]),probs = seq(0, 1, 0.01))[100]
if(d1){cat('Warning : Suspect extreme values in left tail')}
if(d99){cat('Warning : Suspect extreme values in right tail')}
```
``` {r eval=TRUE, fig.width=6, fig.height=2}
library(ggplot2)
v <- num_var_names[i]
hp <- ggplot(na.omit(data), aes_string(x=v)) + geom_histogram( colour="grey", fill="grey", binwidth=diff(range(na.omit(data[[v]]))/100))
hp + theme(axis.title.x = element_blank(),axis.text.x = element_text(size=10)) + theme(axis.title.y = element_blank(),axis.text.y = element_text(size=10))
```
see my datamineR package on github https://github.com/hugokoopmans/dataMineR
Solution 4
As an addition to Hugo's excellent answer, I believe that in 2016 you need to include a print
command as well:
```{r run-numeric-md, include=FALSE}
out = NULL
for (i in c(1:num_vars)) {
out = c(out, knit_child('da-numeric.Rmd'))
}
`r paste(out, collapse = '\n')`
```
bnjmn
I was born and raised in Phoenix, Arizona. After graduating from Arizona State University, I relocated to Washington, DC for seven years. While there I: worked as a project manager at an educational non-profit; studied applied math and statistics at Georgetown University; built robust, predictive mathematical models across several industries; and learned to program Python and appreciate the wonders of modern computation. Next, Philadelphia, Pennsylvania became home for three years. I worked as a full stack engineer at a financial tech startup focused on Hard Money Lending. I learned so much while coding in Python and JavaScript alongside many talented people and truly enjoyed being part of a team. While working in Philly, I bought a house, a real fixer-upper, and learned even more through the opportunities and challenges provided by building equity with sweat. Two years later, I sold that house myself and decided to start living a less conventional, more purposeful minimal lifestyle. I now travel full time.
Updated on July 22, 2022Comments
-
bnjmn almost 2 years
I would like to create an automated knitr report that will produce histograms for each numeric field within my dataframe. My goal is to do this without having to specify the actual fields (this dataset contains over 70 and I would also like to reuse the script).
I've tried a few different approaches:
- saving the plot to an object,
p
, and then callingp
after the loop- This only plots the final plot
- Creating an array of plots,
PLOTS <- NULL
, and appending the plots within the loopPLOTS <- append(PLOTS, p)
- Accessing these plots out of the loop did not work at all
- Even tried saving each to a
.png
file but would rather not have to deal with the overhead of saving and then re-accessing each file
I'm afraid the intricacies of the plot devices are escaping me.
Question
How can I make the following chunk output each plot within the loop to the report? Currently, the best I can achieve is output of the final plot produced by saving it to an object and calling that object outside of the loop.
R markdown chunk using
knitr
in RStudio:```{r plotNumeric, echo=TRUE, fig.height=3} suppressPackageStartupMessages(library(ggplot2)) FIELDS <- names(df)[sapply(df, class)=="numeric"] for (field in FIELDS){ qplot(df[,field], main=field) } ```
From this point, I hope to customize the plots further.
- saving the plot to an object,
-
I Del Toro over 8 yearsHaving a similar problem. Trying to loop analyses and a ggplot figure into an .Rmd file. But after the loop runs no figures or analyses outputs print. Any ideas why?
-
Fabian almost 8 yearsHey :) Where does the knit_child() function come from?
-
merv over 5 yearsThis is literally what "wrap
qplot
inprint
" means, i.e., this just restates the accepted answer. -
Ricecakes about 5 yearsThis gives more flexibility to create figure captions and add other details than the accepted answer. You can use the options "fig.caption" and changing the chunk names for each iteration of the loop.
-
Skyler over 4 yearsthis works quite well, save for the fact that when I print the charts they are out of order. Any idea what might be going on there
-
jzadra over 4 yearsCan anyone explain why you have to wrap the whole thing rather than just piping to print at the end? eg ggplot(......) %>% print()
-
cbeleites unhappy with SX over 4 years@jzadra: you can do that as well. You'll still need to wrap (ggplot() + geom_* ()) in parentheses for the piping to work correctly - otherwise you'll only get a print of the last object you add tot he ggplot because of operator precedence. (As for why isn't this in the answer: Pipes weren't around yet when I wrote that answer).
-
jzadra over 4 years@cbeleitessupportsMonica Thanks. Man I wish Hadley would re-write ggplot3 to use pipes.
-
user3072843 about 4 yearsWould it be possible to reference a knit label instead of a separate file?
-
Peter almost 4 yearsSeeing the code is helpful as it is direct and makes the abstract visually obvious.
-
Lazarus Thurston about 2 yearsDoesn't work if we use
dygraph()
R function instead ofqplot
. -
Lazarus Thurston about 2 yearsThe
lapply
andtagList
approach solves this in a more general and robust way. See the solution here. stackoverflow.com/a/35235069/1972786 -
monkey almost 2 yearsThis makes sense to a beginner. The accepted answer does not. Therefore this answer is better.