3

The code below works fine if ran outside the function - everything is being evaluated correctly, and the comparison cloud can be converted to a ggplot. However, when I want to run this as a function, the expression can no longer find the variables that are defined inside the function (e.g., the term.matrix).

I've tried a bunch of combinations with expression() bquote() expr() etc., but have not been able to find the solution.

Can anyone help me?

library(tm)
library(ggplotify)
library(wordcloud)
library(ggplot2)

cloud_as_ggplot <- function(){
  
  data(SOTU)
corp <- SOTU
corp <- tm_map(corp, removePunctuation)
corp <- tm_map(corp, content_transformer(tolower))
corp <- tm_map(corp, removeNumbers)
corp <- tm_map(corp, function(x)removeWords(x,stopwords()))

term.matrix <- TermDocumentMatrix(corp)
term.matrix <- as.matrix(term.matrix)
colnames(term.matrix) <- c("SOTU 2010","SOTU 2011")

cloud <- expression(
  comparison.cloud(term.matrix,
                   max.words=40,
                   random.order=FALSE,
                   match.colors=TRUE))

title <- "as.ggplot is working"

ggplotify::as.ggplot(cloud) + 
  labs(title = title)
}

cloud_as_ggplot()

  • How did you figure out to wrap `comparison.cloud` in `expression` to make it work with `as.ggplot`? Without `expression` the error wouldn't arise, but then `as.ggplot` is not working. – TimTeaFan Mar 09 '22 at 12:59
  • 1
    It was in the ggplotify vignette: https://cran.r-project.org/web/packages/ggplotify/vignettes/ggplotify.html, the assignment to `https://cran.r-project.org/web/packages/ggplotify/vignettes/ggplotify.html`. – Stefan Musch Mar 09 '22 at 13:47

1 Answers1

0

I think it is an issue about the environment from which comparison.cloud is taking the parameters. It seems to be .GlobalEnv and not the one created by cloud_as_ggplot().

You can "fix" it by making term.matrix a global variable and at the end you can delete it. For my it is kind of dirty but it works.

library(tm)
library(ggplotify)
library(wordcloud)
library(ggplot2)

cloud_as_ggplot <- function(){
  
  data(SOTU)
  corp <- SOTU
  corp <- tm_map(corp, removePunctuation)
  corp <- tm_map(corp, content_transformer(tolower))
  corp <- tm_map(corp, removeNumbers)
  corp <- tm_map(corp, function(x)removeWords(x,stopwords()))
  
  term.matrix <<- TermDocumentMatrix(corp)
  term.matrix <<- as.matrix(term.matrix)
  colnames(term.matrix) <- c("SOTU 2010","SOTU 2011")
  
  cloud <- expression(
    comparison.cloud(term.matrix,
                     max.words=40,
                     random.order=FALSE,
                     match.colors=TRUE))
  
  
  
  title <- "as.ggplot is working"
  p<-ggplotify::as.ggplot(cloud) + 
    labs(title = title)
  rm(term.matrix,envir=.GlobalEnv)
  p
}

cloud_as_ggplot()
Dharman
  • 30,962
  • 25
  • 85
  • 135
LocoGris
  • 4,432
  • 3
  • 15
  • 30
  • That makes sense, however, my function has many more variables and paramaters that I pass onto the `comparison.cloud`. If I can't find another solution that allows me to adjust the environment of the cloud generation itself, I will probably resort to this as my final option. Thanks for investigating! – Stefan Musch Mar 09 '22 at 12:00
  • The problem does not stem from `comparison.cloud` it works totally fine, when not wrapped in `expression`. The question is how to make `as.ggplot` work without wrapping `comparison.cloud` in `expression`. – TimTeaFan Mar 09 '22 at 12:25
  • Right, @TimTeaFan I don't think there is a way, as the `comparison.cloud` function plots the object right away. If I wrap it directly in `as.ggplot` without the `expression()` function, it simply says it can't apply it to an object of type NULL. So the problem here is that, like Dharman noted, the `comparison.cloud` function only takes the global environment when wrapped in an `expression`, instead of the function environment. – Stefan Musch Mar 09 '22 at 12:50