Closed WHMan closed 7 years ago
I wasn't able to reproduce this issue, although perhaps I wasn't clear on your instructions. With an R Markdown document containing this:
---
title: "Untitled"
output: html_document
---
```{r}
test_df <- data.frame(taxa = rep(LETTERS[1:5], 2),
count = 1:10,
count2 = 11:20)
test_taxa <- unique(test_df$taxa)
test_list <- list()
for (z in test_taxa) {
test_list[[z]] <- sum(test_df[which(test_df$taxa == z), c("count", "count2")]) /
sum(rowSums(test_df[, c("count", "count2")]))
}
test_list
```
```{r}
library("phyloseq")
data(GlobalPatterns)
test2_taxa <- get_taxa_unique(GlobalPatterns, "Phylum")[1:5]
test2_list <- list()
for (x in test2_taxa) {
test2_list[[x]] <- sum(sample_sums(subset_taxa(GlobalPatterns, Phylum == x))) /
sum(sample_sums(GlobalPatterns)) }
test2_list
```
I was able to successfully render this document with this:
# Method 1
my_render <- function(input) {
rmarkdown::render(input = input)
}
my_render(input = "~/scratch/test.Rmd")
Perhaps the issue is with phyloseq
-- I tested with phyloseq_1.16.2.
@kevinushey: Thanks for your response! Sorry for my unclear explanation of the problem, but you interpreted it correctly.
I've updated my phyloseq
package to version 1.19.1, but I still get the same error-message, while rendering the R Markdown document with:
# Method 1
my_render <- function(input) {
rmarkdown::render(input = input)
}
my_render(input = "~/scratch/test.Rmd")
Sounds like an environment issue. How about passing envir = parent.frame()
to render()
in my_render()
?
Thanks @yihui! That solved my problem.
However, I do not really understand why this solves the problem as envir = parent.frame()
seems to be default in rmarkdown::render()
. It probably comes down to my poor knowledge of environments and lexical scoping in R :laughing:.
I can definitely see why you feel confused. It is related to the delayed evaluation of function arguments. In a recent interview of @jcheng5, he said:
But, if we had a time machine and could go back, the one change that I would make – well the most important change I would make – to R would be to have delayed evaluation be a feature that you opt into rather than being the default. As I said before, delayed evaluation for function arguments is really awesome and it makes things easy in R that are quite unnatural to do in other languages. But, I feel it’s a tool that you usually don’t want to use. When you want it, it’s awesome to have, but it would be nicer to have all function arguments evaluated except for those which have been annotated for lazy evaluation.
Even though render()
has a default envir = parent.frame()
, this argument won't be evaluated until it is actually used inside render()
, and by that time, parent.frame()
will point to the frame (environment) outside render()
, which means the inside environment of your my_render()
. What you actually want is the environment outside my_render()
.
If you pass an explicit envir = parent.frame()
to render()
, R knows this parent frame refers to the parent of the current environment: the "current" environment is the internal environment of my_render()
, and the parent will be the outside environment of my_render()
.
That said, whenever someone runs into an issue similarly, I'm relatively sure it is a bug of the third-party package that is used in R Markdown (the package can not work with well objects in parent frames, e.g. it might have assumed objects must be in the global environment). In this case, phyloseq might be the culprit, but I know nothing about it, so I'm not entirely sure.
Wow, thanks again @yihui! I did not expect (such) an (extensive) answer and really appreciate the effort you put into it. Your explanation is very clear and I will try to look into the assumptions of the phyloseq functions.
@yihui Thanks so much man! This answer just saved the day for me also!
This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.
Hi,
I have a minor issue concerning a function I wrote containing
rmarkdown::render
. Specifically when using that function in combination with phyloseq-formatted data in a for-loop (or apply) gives an error while rendering.Minimal example
Function containing
rmarkdown::render
, that gives the error:rmarkdown::render on its own does not give the error:
Test example that always works
If test.Rmd contains this for-loop, everything is fine:
Test example with phyloseq data
However, if test.Rmd wants to loop phyloseq-data:
"Error in eval(expr, envir, enclos) : object 'x' not found"
.sessionInfo()
I am not really sure whether this is a rmarkdown or phyloseq issue, though. Any support is appreciated. Thanks!