From friendly at yorku.ca  Wed Aug 27 19:51:11 2014
From: friendly at yorku.ca (Michael Friendly)
Date: Wed, 27 Aug 2014 13:51:11 -0400
Subject: [Rd] no visible binding for global variable for data sets in a
 package
In-Reply-To: <D13961DB-34D8-4A33-B01E-D8F8BECCB501@gmail.com>
References: <53FD030A.1020709@yorku.ca>	<21501.41940.216907.982935@stat.math.ethz.ch>
	<53FDDD55.1040807@yorku.ca> <53FDE608.40801@yorku.ca>
	<D13961DB-34D8-4A33-B01E-D8F8BECCB501@gmail.com>
Message-ID: <53FE1A8F.3060809@yorku.ca>

On 8/27/2014 10:41 AM, peter dalgaard wrote:
> Using data() in a package with lazyloaded data seems like asking for trouble to me. But you're making me curious (and I'm too lazy[*] to set up for rebuilding the package myself):
>
> Did you actually try putting battingLabels & friends in the namespace? What happened?
Well, I tried this, with NAMESPACE as

# all the rest is data, except we try to export the data sets used 
globally in these functions
export(battingStats,
     playerInfo,teamInfo,
     Label,
     battingLabels, pitchingLabels, fieldingLabels,
     Batting, Master, Teams
     )

R CMD check was even more unhappy, failing immediately, so the attempted 
cure was worse than the original disease.

* checking whether package 'Lahman' can be installed ...Warning: running 
command '"C:/R/R-3.0.3/bin/x64/Rcmd.exe" INSTALL -l 
"C:/eclipse/Lahman2013.Rcheck" --no-html 
"C:\DOCUME~2\WORKSP~1\LAHMAN~1"' had status 1
  ERROR
Installation failed.
See 'C:/eclipse/Lahman2013.Rcheck/00install.out' for details.

00install.out said:

Error in namespaceExport(ns, exports) :
   undefined exports: battingLabels, pitchingLabels, fieldingLabels, 
Batting, Master, Teams
Error: loading failed
Execution halted

My conclusions so far are:

- These are just NOTEs, so I will ignore them for now.  But they will 
probably trigger the CRAN
maintainers to notice them when I resubmit and I will have to plead 
guilty with an explanation.  This makes more useless work for all involved.

- Peter Dalgaard noted the change in R-devel, and nobody so far has 
suggested a working remedy, so a clean solution
seems warranted.  It mentions 'now by default' -- is there a switch for 
this?

The change would seem to be this

       \item \command{R CMD check} now by default checks code usage
       directly on the package namespace without loading and attaching
       the package and its suggests and enhances.

and perhaps the remedies could be stated more clearly?

Alternatively, it isn't common, but it is by no means rare for package 
functions to need to use data sets
in the package, so some mechanism to declare these, perhaps in NAMESPACE 
is needed.
>
> A workaround could be to use rbind(Lahman::battingLabels,....) which runs a bit against the grain for me.
>
> I think the right answer _is_ to export the lazy data; the question is how to do it. There's nothing particularly strange about exporting non-functions ("letters" would be an example, save for the special status of package:base). If you attach the package, the lazyloaded data appear in the same environment as the exported function so they are de facto already in the namespace for the purposes of library() and `::`. So I agree, something like exportData() would be useful. (Or some other mechanism. You might want to be able to export data selectively.)
>
> - pd
>
>
> [*] "Burdened with pressing obligations", if you like.
>
>
> On 27 Aug 2014, at 16:07 , Michael Friendly <friendly at yorku.ca> wrote:
>
>> On 8/27/2014 9:29 AM, Michael Friendly wrote:
>>>> It works in the sense that  Lahman::Label("yearID")  will
>>>> work even when Lahman is not in the search path,
>>>> but   R-devel CMD check   will still give the same NOTE,
>>>> though you can argue that that note is actally a "false positive".
>>> So, this would be version 1 of "2)":
>>>
>>> Label <- function(var, labels) {
>>>      stopifnot(require(Lahman, quietly=TRUE))
>>>      if(missing(labels)) labels <- rbind(battingLabels, pitchingLabels,
>>> fieldingLabels)
>>>      wanted <- which(labels[,1]==var)
>>>      if (length(wanted)) labels[wanted[1],2] else var
>>> }
>>>
>>> And this would be version 2, using data():
>>>
>>> Label <- function(var, labels) {
>>>      stopifnot(require(Lahman, quietly=TRUE))
>>>      if(missing(labels)) {
>>>          data(battingLabels); data(pitchingLabels); data(fieldingLabels)
>>>          labels <- rbind(battingLabels, pitchingLabels, fieldingLabels)
>>>          }
>>>      wanted <- which(labels[,1]==var)
>>>      if (length(wanted)) labels[wanted[1],2] else var
>>> }
>>>
>>>
>> Just to follow up:  R-devel likes this less than it does my initial version.  I still get no visible binding NOTES, and complaint about
>> using data() in a function:
>>
>> * checking R code for possible problems ... NOTE
>> Label: no visible binding for global variable 'battingLabels'
>> Label: no visible binding for global variable 'pitchingLabels'
>> Label: no visible binding for global variable 'fieldingLabels'
>> battingStats: no visible binding for global variable 'Batting'
>> battingStats: no visible global function definition for 'mutate'
>> playerInfo: no visible binding for global variable 'Master'
>> teamInfo: no visible binding for global variable 'Teams'
>>
>> Found the following calls to data() loading into the global environment:
>> File 'Lahman/R/Label.R':
>>   data(battingLabels)
>>   data(pitchingLabels)
>>   data(fieldingLabels)
>> See section 'Good practice' in '?data'.
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
Michael Friendly     Email: friendly AT yorku DOT ca
Professor, Psychology Dept. & Chair, Quantitative Methods
York University      Voice: 416 736-2100 x66249 Fax: 416 736-5814
4700 Keele Street    Web:http://www.datavis.ca
Toronto, ONT  M3J 1P3 CANADA



[Rd] no visible binding for global variable for data sets in a package
Michael Friendly