47

I noticed in checking a package that I obtain notes "no visible binding for global variable" when I use functions like subset that use verbatim names of list elements as arguments.

For example with a data frame:

foo <- data.frame(a=c(TRUE,FALSE,TRUE),b=1:3)

I can do silly things like:

subset(foo,a)
transform(foo,a=b)

Which work as expected. The R code check in R CMD however doesn't understand that these refer to elements and complains about there not being any visible bindings of global variables.

While this works ok, I don't really like having notes in my package and prefer for it to pass the check with no errors, warnings and notes at all. I also don't really want to rework my code too much. Is there a way to write these codes so that it is clear the arguments do not refer to global variables?

Sacha Epskamp
  • 46,463
  • 20
  • 113
  • 131
  • This may have some justification in making packages "more compilable" for the sake of future R evolution... – mbq Nov 11 '11 at 16:48
  • I note that this question has been duplicated more recently: http://stackoverflow.com/questions/9439256/how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when but the answers there have further information which others may find useful. – cboettig Jul 17 '14 at 22:39
  • Possible duplicate of [How can I handle R CMD check "no visible binding for global variable" notes when my ggplot2 syntax is sensible?](https://stackoverflow.com/questions/9439256/how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when) – C8H10N4O2 Sep 24 '18 at 18:08

5 Answers5

51

To get it past R CMD check you can either :

  • Use get("b") (but that is onerous)
  • Place a=b=NULL somewhere higher up in your function (that's what I do)

There was a thread on r-devel a while ago where somebody from r-core basically said (from memory) "NOTES are ok, you know. The assumption is that the author checked it and is ok with the NOTE.". But, I agree with you. I do prefer to have CRAN checks return a clean "OK" on all platforms. That way the user is left in no doubt that it passes checks ok.

EDIT :

Here is the r-devel thread I was remembering (from April 2010). So that appears to suggest that there are some situations where there is no known way to avoid the NOTE, but that's ok.

Matt Dowle
  • 58,872
  • 22
  • 166
  • 224
  • Thanks. I will use this until I have time to recode in a proper way:) – Sacha Epskamp Nov 11 '11 at 16:43
  • 1
    I'm not sure there is a proper way ;) I think of the `a=b=NULL` thing as like C variable declaration. It makes me think a bit harder and has caught some bugs for me, so I don't mind it. – Matt Dowle Nov 11 '11 at 16:48
  • 3
    @MattDowle Seems like the opposite of C variable declaration, because it's saying to the user "these are NULL" when in fact the function will rely on them being not NULL as accessed. – tim Feb 11 '14 at 17:53
  • 2
    thanks, this one has been annoying me for a long time when using `:=` inside data.table driven functions. – Matt Bannert Sep 15 '14 at 17:11
  • 1
    According to [this post](https://github.com/r-lib/devtools/issues/1714), using `utils::globalVariables()` as outlined in @seancarmody's answer is the correct way to address this issue. – wurli Apr 09 '21 at 12:01
17

This is one of the potential "unanticipated consequences" of using subset non-interactively. As it says in the Warning section of ?subset:

This is a convenience function intended for use interactively. For programming it is better to use the standard subsetting functions like ‘[’, and in particular the non-standard evaluation of argument ‘subset’ can have unanticipated consequences.

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
12

From R version 2.15.1 onwards there is a way around this:

if(getRversion() >= "2.15.1")  utils::globalVariables(c("a", "othervar"))
seancarmody
  • 6,182
  • 2
  • 34
  • 31
  • 6
    yikes.. that's quite a side-effect just to to fake subset being evaluated correctly... Be nice if CRAN just allowed authors to mark notes about apparently (but not actually) missing globals as spurious… – tim Feb 11 '14 at 17:51
9

As per the warning section of ?subset it is better to use subset interactively, and [ for programming.

I would replace a command like

subset(foo,a)

with

foo[foo$a]

or if foo is a dataframe:

foo[foo$a, ]

you might also like to use with if foo is a dataframe and the expression to be evaluated is complex:

with(foo, foo[a, ])

tekumara
  • 8,357
  • 10
  • 57
  • 69
  • I'm pretty sure `with` will cause the exact same problem since `a` is still not defined in the environment, only in the data. – BrodieG Feb 17 '18 at 21:00
2

I had this issue and traced it to my ggplot2 section.

This code provided the error:

ggplot2::ggplot(data = spec.df, ggplot2::aes(E.avg, fraction)) +
  ggplot2::geom_line() +
    ggplot2::ggtitle(paste0(title))

Adding the data name to the parameters eliminated the not:

ggplot2::ggplot(data = spec.df, ggplot2::aes(spec.df$E.avg, spec.df$fraction)) +
  ggplot2::geom_line() +
    ggplot2::ggtitle(paste0(title))

markhogue
  • 1,056
  • 1
  • 6
  • 16