43
votes

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?

5
This may have some justification in making packages "more compilable" for the sake of future R evolution...mbq
I note that this question has been duplicated more recently: stackoverflow.com/questions/9439256/… but the answers there have further information which others may find useful.cboettig

5 Answers

45
votes

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.

17
votes

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.

12
votes

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

if(getRversion() >= "2.15.1")  utils::globalVariables(c("a", "othervar"))
9
votes

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, ])

2
votes

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))