当编写使用Matrix包的R包时,为什么我必须指定Matrix :: t()而不是仅指定t()? [英] When writing an R package that uses the Matrix package, why do I have to specify Matrix::t() instead of just t()?

查看:132
本文介绍了当编写使用Matrix包的R包时,为什么我必须指定Matrix :: t()而不是仅指定t()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下在R会话中定义的简单函数:

Consider the following simple functions defined in an R session:

nathanvan@nathanvan-N61Jq:~$ R

R version 3.0.1 (2013-05-16) -- "Good Sport"
... snip ... 
> make.a.Matrix <- function(data, nrow, ncol) {
+    require(Matrix)
+    return( Matrix(data, nrow=nrow, ncol=ncol))
+ }
> 
> transpose.a.Matrix <- function(data, nrow, ncol  ) {
+   return(t( make.a.Matrix(data, nrow=nrow, ncol=ncol) ))
+ }
> 
> make.a.Matrix(1:12, 3, 4)
Loading required package: Matrix
Loading required package: lattice
3 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> transpose.a.Matrix(1:12, 3, 4)
4 x 3 Matrix of class "dgeMatrix"
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12

如果我们将这些相同的函数放入包中,则transpose.a.Matrix函数将不再起作用. 由于描述程序包创建过程太长,因此我只发布了程序包的副本

If we put those same functions into a package, the transpose.a.Matrix function no longer works. Since describing the package creation process would be too lengthy, I have simply posted a copy of the package here. I have posted the DESCRIPTION and NAMESPACE files at the end of the question. If other pieces are relevant, I'd be happy to post them too. Just let me know!

nathanvan@nathanvan-N61Jq:~$ R

R version 3.0.1 (2013-05-16) -- "Good Sport"
... snip ... 
> require(minimalbugexample)
Loading required package: minimalbugexample
Loading required package: Matrix
Loading required package: lattice
Loading required package: testthat
> make.a.Matrix(1:12, 3, 4)
3 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> transpose.a.Matrix(1:12, 3, 4)
Error in t.default(make.a.Matrix(data, nrow = nrow, ncol = ncol)) : 
  argument is not a matrix
> transpose.a.Matrix
function(data, nrow, ncol  ) {
  return(t( make.a.Matrix(data, nrow=nrow, ncol=ncol) ))
}
<environment: namespace:minimalbugexample>

我认为这里的关键是关于名称空间的怪异之处.请注意,如果我调试该函数,则可以手动调用Matrix::t,当base::t失败并出现相同错误时,它将起作用.

I think that the key here is something weird about the namespace. Notice that if I debug the function, I can manually call the Matrix::t and it will work while the base::t fails with the same error.

> debug(transpose.a.Matrix)
> transpose.a.Matrix(1:12, 3, 4)
debugging in: transpose.a.Matrix(1:12, 3, 4)
debug at /home/nathanvan/Ubuntu One/workspace/experimental-design/software/minimalbugexample/R/use-Matrix-package.R#31: {
    return(t(make.a.Matrix(data, nrow = nrow, ncol = ncol)))
}
Browse[2]> t(Matrix(1:12, 3, 4))
Error in t.default(Matrix(1:12, 3, 4)) : argument is not a matrix
Browse[2]> t
function (x) 
UseMethod("t")
<bytecode: 0x46b0a88>
<environment: namespace:base>
Browse[2]> Matrix::t(Matrix(1:12, 3, 4))
4 x 3 Matrix of class "dgeMatrix"
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
Browse[2]> base::t(Matrix(1:12, 3, 4))
Error in t.default(Matrix(1:12, 3, 4)) : argument is not a matrix

但是使用showMethods时,它建议仅使用t应该找到正确的,即使没有.

And yet using showMethods, it suggest that just using t should find the right one, even though it did not.

Browse[2]> showMethods('t')
Function: t (package base)
x="ANY"
x="CsparseMatrix"
x="dgeMatrix"
x="diagonalMatrix"
x="dppMatrix"
x="dsCMatrix"
x="dspMatrix"
x="dsTMatrix"
x="dsyMatrix"
x="dtpMatrix"
x="dtrMatrix"
x="dtTMatrix"
x="lgeMatrix"
x="lspMatrix"
x="lsTMatrix"
x="lsyMatrix"
x="ltpMatrix"
x="ltrMatrix"
x="ltTMatrix"
x="matrix"
    (inherited from: x="ANY")
x="Matrix"
x="ngeMatrix"
x="nspMatrix"
x="nsTMatrix"
x="nsyMatrix"
x="ntpMatrix"
x="ntrMatrix"
x="ntTMatrix"
x="pMatrix"
x="RsparseMatrix"
x="TsparseMatrix"

现在,我可以通过编辑包的源代码来修复"它,以便transpose.a.Matrix函数指定它需要Matrix::t方法:

For now, I can "fix" it by editing the source for the package so that the transpose.a.Matrix function specifies that it needs the Matrix::t method:

transpose.a.Matrix <- function(data, nrow, ncol  ) {
  require(Matrix)
  return(Matrix::t( make.a.Matrix(data, nrow=nrow, ncol=ncol) ))
}

但是,似乎不需要它.我想念什么?

But that seems like it should not be needed. What am I missing?

我的DESCRIPTION文件是

My DESCRIPTION file is

Package: minimalbugexample
Title: 
Description: 
Version: 0.1
Author: Nathan VanHoudnos <nathanvan@letterafterFmail.com>
Maintainer: Nathan VanHoudnos <nathanvan@letterafterFmail.com>
Depends:
    R (>= 3.0.1),
    Matrix (>= 1.0),
    testthat
License: GPL
LazyData: true
Collate:
    'minimalbugexample-package.r'
    'use-Matrix-package.R'

我的NAMESPACE文件是

My NAMESPACE file is

export(make.a.Matrix)
export(transpose.a.Matrix)

,我可以应要求发布其他作品.

and I can post additional pieces upon request.

推荐答案

关于gitHub的工作示例

我在gitHub上放置了一个工作示例,以便轻松浏览不同文件.

仅供参考,由于它是使用devtools构建的,因此它并不是一个最小的示例. 附加"是(1)roxygen2注释是构建NAMESPACE文件的基础,以及(2)它结合了testthat的单元测试.在本示例中,所有这些都可以忽略.

FYI, it's not quite a minimal example since it was built with devtools. The "extras" are (1) that roxygen2 comments are what builds the NAMESPACE file, and (2) it incorporates unit testing with testthat. All of that can be ignored for the purposes of this example.

事实上,我所做的简短回答需要将我的NAMESPACE文件更改为:

The short answer that I did, in fact, need to change my NAMESPACE file to:

export(make.a.Matrix)
export(transpose.a.Matrix)
importFrom(Matrix,Matrix)
importFrom(Matrix,t)

以便R可以找到正确的转置版本.有关R如何搜索的详细说明,请参见此帖子功能.

So that R could find the right version of transpose. See this post for a great description of how R searches for functions.

尽管并非绝对必要,但我将我的DESCRIPTION文件修改为一点点清洁器:

Although not strictly necessary, I modified my DESCRIPTION file to be a tad bit cleaner:

Package: minimalbugexample
Title: 
Description: 
Version: 0.1.3
Author: Nathan VanHoudnos <nathanvan@letterafterFmail.com>
Maintainer: Nathan VanHoudnos <nathanvan@letterafterFmail.com>
Depends:
    R (>= 3.0.1),
    Matrix (>= 1.0)
Suggests:
    testthat (>= 0.7.1.99)
License: GPL
LazyData: true
Collate:
    'minimalbugexample-package.r'
    'use-Matrix-package.R'

请注意,我将Depends:用于Matrix而不是Imports:,以便用户将能够使用函数返回的Matrix对象.如果此示例仅在内部使用Matrix东西而不向用户展示,则我将使用Imports:.

Note that I am using Depends: for Matrix instead of Imports: so that the user will be able to use the Matrix objects that the functions return. If this example only used the Matrix stuff internally without presenting it to the user, I'd have used Imports:.

> require(minimalbugexample)
> make.a.Matrix(1:12, 3, 4)
3 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> transpose.a.Matrix(1:12, 3, 4)
4 x 3 Matrix of class "dgeMatrix"
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
> t( make.a.Matrix(1:12, 3, 4))
4 x 3 Matrix of class "dgeMatrix"
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12

请注意,如果我在Imports:中而不是Depends:中指定了Matrix,则最后一条命令将失败.

Note that the last command would have failed if I had specified Matrix in Imports: and not Depends:.

这篇关于当编写使用Matrix包的R包时,为什么我必须指定Matrix :: t()而不是仅指定t()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆