Georgi,
Brilliant, thank you very much for the helpful reply and explanation! I added
'importFrom("Matrix","as.matrix")' to my NAMESPACE and all worked fine! As my
'as.matrix' method is used entirely internally to the 'testmat' function (and
not "used outside the package"), I don't think I actually need to export it. In
my case, testmat is defined inside the package, and not in the global workspace
(nothing is defined in the global workspace in my example).
To your point that I should just "import the 'Matrix'", I thought adding Matrix
to the Depends field in the DESCRIPTION would do that for me, but apparently I
need to study the WRE manual more thoroughly, as it clearly does not.
It's also worth pointing out that R CMD check did not actually warn that I
should have imported as.matrix, at least in the case where I have 'Depends:
Matrix' in DESCRIPTION and only 'exportPattern("^[[:alpha:]]+")' in the
NAMESPACE file.
Last, for anyone who took issue, apologies for implying a bug where none
exists, or that there was something wrong with Matrix or S4.
Thanks again,
Robert
-Original Message-
From: Georgi Boshnakov [mailto:georgi.boshna...@manchester.ac.uk]
Sent: Sunday, January 29, 2017 1:40 PM
To: r-devel@r-project.org
Cc: Robert McGehee
Subject: RE: R-devel Digest, Vol 167, Issue 25
Hi,
Short answer: import 'as.matrix' and export your method(s) for it. From WRE:
"All S4 classes to be used outside the package need to be listed in an
exportClasses directive. Alternatively, they can be specified using
exportClassPattern.(46) in the same style as for exportPattern. To export
methods for generics from other packages an exportMethods directive can be
used."
Details: the precise details depend on what exactly is in your NAMESPACE file.
The curious difference you observe is due to the fact that as.matrix is defined
in 'base' as S3 generic.
When you set an S4 method for it you effectively create your own as.matrix S4
generic and your settings in NAMESPACE probably export everything you "own".
When you depend on package 'Matrix', 'as.matrix' is made S4 generic by it and
you are defining a method for An imported function, so you need to use
exportMethods (see the above excerpt), otherwise your method is not exported.
(Indeed, in your example the arror is from array() in the default method).
Note also that it matters where you define the test function. I am pretty sure
that you defined it in the global workspace (not in the package) to get the
error.
It is very useful practice to run 'R CMD check' (or its devtools equivalent).
In this case it would have warned you to import as.matrix. Also, to make your
life easier during initial development, import the whole 'Matrix' and when
things work think about cleaning up and importing only stuff that you need.
Best regards,
Georgi Boshnakov
--
Message: 15
Date: Fri, 27 Jan 2017 22:41:10 +
From: Robert McGehee
To: "r-devel@r-project.org"
Subject: [Rd] Matrix package breaks as.matrix method
Message-ID:
<30d28a63376088428e8318dd67fd407f705...@ny-mailstore1.walleyetrading.net>
Content-Type: text/plain; charset="us-ascii"
Hi,
The Matrix package and the as.matrix method do not seem to be compatible inside
of a package.
Here's an example. I've created a simple package "mat" that defines an
eponymous class and as.matrix method on that class. All is well, unless that
package has the Matrix package in its Depends or Imports (and imports, e.g. the
"Diagonal" function). Then my as.matrix method stops working, even if I'm not
using any part of the Matrix package.
Here's an example on R 3.3.2:
First, create an empty package "mat" (e.g. with package.skeleton) with one file
in mat/R/mat.R with the following contents:
setClass("mat", representation(H="matrix")) mat <- function(H) new("mat", H=H)
setMethod("as.matrix", signature("mat"), function(x, ...) crossprod(x@H))
testmat <- function() {
H <- matrix(1:3, 1, 3)
M <- mat(H)
as.matrix(M)
}
Then install the mat package :
> require(mat)
> testmat()
[,1] [,2] [,3]
[1,]123
[2,]246
[3,]369
All works fine!
Now add "Depends: Matrix" into the package's DESCRIPTION file (alternatively
add "Imports: Matrix" and 'importFrom("Matrix","Diagonal")' in the NAMESPACE).
Try again:
> require(mat)
> testmat()
Error in as.vector(data) :
no method for coercing this S4 class to a vector
Bug? If not, can anyone provide a work around? In my case, I'd like to