【问题标题】:When writing an R package that uses the Matrix package, why do I have to specify Matrix::t() instead of just t()?在编写使用 Matrix 包的 R 包时,为什么我必须指定 Matrix::t() 而不仅仅是 t()?
【发布时间】:2013-07-08 23:46:16
【问题描述】:

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

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 函数将不再起作用。 由于描述包创建过程太冗长,我只是发布了包here 的副本。我已经在问题末尾发布了DESCRIPTIONNAMESPACE 文件。如果其他文章是相关的,我也很乐意发布它们。让我知道!

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 失败并出现相同错误时工作。

> 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 应该找到正确的,即使它没有。

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 方法:

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

但这似乎不需要它。我错过了什么?

我的说明文件是

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 文件是

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

我可以根据要求发布其他作品。

【问题讨论】:

  • 尝试从您的命名空间中的Matrix 导入t
  • Matrix 包使用 S4 方法,需要特别注意导入和导出。您是否阅读了 R-exts 手册中标题为 Namespaces with S4 classes and methods 的部分?
  • @JoshO'Brien 我没有。我已经让它工作了。你想让我写一个答案,还是你愿意? (这样你就可以得到'接受')。谢谢!
  • @NathanVanHoudnos -- 如果你能写出有效的步骤,那就太好了。感谢您抽出宝贵时间以这种方式结束!
  • @JoshO'Brien 完成。如果您有时间,您能否检查一下我的答案是否正确?

标签: r namespaces sparse-matrix


【解决方案1】:

一个关于 gitHub 的工作示例

I put a working example on gitHub so that it is easy to browse the different files

仅供参考,因为它是使用devtools 构建的,所以这并不是一个简单的示例。 “附加”是 (1) roxygen2 cmets 是构建 NAMESPACE 文件的内容,以及 (2) 它结合了单元测试与 testthat。出于本示例的目的,所有这些都可以忽略。

关键修复

我做的简短回答,其实需要把我的NAMESPACE文件改成:

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

这样 R 就可以找到正确的转置版本。请参阅post,了解 R 如何搜索函数的详细说明。

虽然不是绝对必要,但我修改了我的DESCRIPTION文件以使其更清晰:

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:

证明它有效

> 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: 中指定了 Matrix 而不是 Depends:,那么最后一个命令将会失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 2020-08-10
    • 2020-02-10
    相关资源
    最近更新 更多