Last active
October 16, 2018 01:48
-
-
Save moodymudskipper/ec838d6b87ad823c9089dc1ed9d601a6 to your computer and use it in GitHub Desktop.
pass parameters and run a rmd report in a "clean environment"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this function will run a rmd report in a "clean environment", which means it | |
# ignores what's in the global environment and what packages have been attached. | |
# It can be fed adhoc parameters however. | |
# | |
# "clean environment" is between quotes because loaded namespaces in the | |
# original environment CAN influence the report, and the rmd rendering CAN alter | |
# the loaded namespaces. | |
# | |
# In practice this should not be an issue in most cases but let it be said that | |
# the only known way to be sure about the reproduciblity of a report is to knit | |
# it in a new session. | |
# | |
# As a last note, the following overwrites library locally and uses attach | |
# (2 times!), you've been warned. | |
# | |
# Read on below for an example (result : https://jsfiddle.net/cLya01qu/ ) | |
create_report <- function(.rmd, .html, ..., unload = FALSE){ | |
# get loaded packages "package:*" strings | |
packages <- grep("^package:",search()[1:(match("package:stats",search())-1)],value = TRUE) | |
# cleanup and save search path | |
sapply(packages, detach, character.only = TRUE) | |
search_ <- search() | |
# set back to normal in the end | |
on.exit({ | |
# remove whatever was attached during the rendering | |
sapply(setdiff(search(),search_),detach, character.only = TRUE) | |
# reattach the original packages | |
sapply(rev(gsub("^package:","",packages)), library, character.only=TRUE) | |
}) | |
# define a new library function locally so our rmd attaches packages after | |
# our attached environment | |
library2 <- function(...) { | |
dots <- alist(...) | |
if("pos" %in% names(dots)) dots$pos <- dots$pos + 1 | |
else dots$pos <- 3 | |
do.call(base::library,dots) | |
} | |
attach(list(library = library2),pos = 2,name = "library_env") | |
attach(list(...), pos = 2,name = "render_env") | |
rmarkdown::render(.rmd, output_format = "html_document", | |
output_file = .html, | |
envir = as.environment("render_env")) | |
detach("render_env") | |
detach("library_env") | |
} | |
###################################### | |
# EXAMPLE # | |
###################################### | |
rmd_input <- tempfile(fileext = ".Rmd") | |
html_output <-tempfile(fileext = ".html") | |
# create the rmd file | |
# you must correct the indentation if you copy this in R Studio! | |
# (Alt + select and suppr is your friend!) | |
cat( | |
'--- | |
title: "Parametric report" | |
output: html_document | |
--- | |
```{r} | |
library("data.table") | |
search() # only data.table, no tidyverse package! | |
ls() # clean workspace, contains only fed parameters | |
x <- "don\'t you ignore me!" | |
for (obj in c("x","y","z","as_tibble","as.data.table")){ | |
if(is.null(get0(obj))) | |
print(paste(obj,"was NOT found")) | |
else | |
print(paste(obj,"was found")) | |
} | |
ggplot2::qplot(0,0, geom="text", | |
label="I can also call use \'fun::pkg\' notation for unattached packages") | |
```',file = rmd_input) | |
# if you want to open it: | |
# file.edit(rmd_input) | |
# let's populate our search path | |
library(tidyverse) | |
library(rlang) | |
search() | |
# [1] ".GlobalEnv" "package:rlang" "package:forcats" "package:stringr" | |
# [5] "package:dplyr" "package:purrr" "package:readr" "package:tidyr" | |
# [9] "package:tibble" "package:ggplot2" "package:tidyverse" "tools:rstudio" | |
# [13] "package:stats" "package:graphics" "package:grDevices" "package:utils" | |
# [17] "package:datasets" "package:methods" "Autoloads" "package:base" | |
# now let's populate the workspace | |
y <- "I will be fed to the report" | |
z <- "I won't" | |
# and now create a report from `y` only : | |
create_report(rmd_input, html_output, y = y) | |
# and open the result : works on windows, not sure on other systems! | |
shell(html_output) | |
# we get our clean path back | |
search() | |
# cleanup | |
# file.remove(rmd_input) | |
# file.remove(html_output) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment