Bug 16583

Summary: Stats heatmap add.expr only looks in global environment
Product: R Reporter: Justin Bass <justin.alexander.bass>
Component: Low-levelAssignee: R-core <R-core>
Status: UNCONFIRMED ---    
Severity: normal CC: murdoch
Priority: P5    
Version: R 3.2.2   
Hardware: All   
OS: All   
Attachments: Heatmap bug R file

Description Justin Bass 2015-10-28 12:48:29 UTC

I wanted to report a possible bug in the heatmap function of stats 3.2.2 that deals with the additional argument evaluation passed in through “add.expr”.

When heatmap is called from within another function, the add.expr evaluation only looks for variable names in the global environment, instead of the parent environment. For example:

EDA_Heatmap = function(data, some input stuff, etc.){
 temp = colnames(data)
  heatmap(stuff, add.expr = text(x=1:5, y=-0.2, labels=temp))

Of course, the initial necessary inputs are correct in place where stuff is, but really just showing the add.expr portion. This will error out if the variable “temp” is not defined in the global environment. 

Looking at the heatmap function code, it looks like a quick change in line 144 (when looking in the source viewer) would work in the eval(substitute(add.expr)) call, changing it to eval.parent(substitute(add.expr), n=1). 

If you need further descriptions of the setup to replicate the issue, let me know and I can send a more detailed description.

Thank you,
Comment 1 Duncan Murdoch 2015-12-14 21:29:04 UTC
Could you please post a reproducible example?
Comment 2 Justin Bass 2015-12-21 15:01:04 UTC
Created attachment 1949 [details]
Heatmap bug R file
Comment 3 Justin Bass 2015-12-21 15:03:27 UTC
(In reply to Duncan Murdoch from comment #1)
> Could you please post a reproducible example?

Hi Duncan,

I've attached an example that creates this bug, and pasted the code below as well. The "assign" function is commented out, but uncommenting this will get the function to work.

Thank you,

#Heatmap example of bug

Heatmap_bug = function(x, col1, col2) {
  # Matrix of relative frequencies of cooccurrence, normalized by rows
  rcm = prop.table(table(x[, col1], x[, col2]), margin=1)
  # Assign rcm to global environment so that add.expr in heatmap function can
  #   access it
  #assign(x="rcm", value=rcm, envir=.GlobalEnv)
  # Plot heatmap
  heatmap(rcm, Rowv = NA, Colv = NA, revC = 1, margins = c(7, 7),
          labCol = "", xlab = col2, ylab = col1, cexRow = 0.9,
          col = grey(seq(1, 0, -0.01)),
          add.expr = text(x = seq_along(colnames(rcm)),
                          y = -0.2,
                          cex = 0.8,
                          labels = colnames(rcm),
                          xpd = TRUE))
  # Remove relative co-occurrence matrix from global environment
  #with(.GlobalEnv, rm(rcm))

#Create sample data
data = data.frame(Var1 = sample(LETTERS[1:4], size=100, replace=T),
                  Var2 = sample(LETTERS[1:4], size=100, replace=T))

# Heatmap
Heatmap_bug(x=data, "Var1", "Var2")
Comment 4 Duncan Murdoch 2015-12-22 22:39:36 UTC
Thanks for the extra detail.  Your analysis is right; I've committed the fix to R-devel, and will soon commit to R-patched.