Вопрос по r, namespaces, sparse-matrix – При написании пакета R, который использует пакет Matrix, почему я должен указывать Matrix :: t () вместо просто t ()?

7

Рассмотрим следующие простые функции, определенные в сеансе R:

[email protected]:~$ R

R version 3.0.1 (2013-05-16) -- "Good Sport"
... snip ... 
> make.a.Matrix  
> transpose.a.Matrix  
> 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 функция больше не работает.Поскольку описание процесса создания пакета будет слишком длинным, я просто разместил копию пакетаВот, Я разместилDESCRIPTION а такжеNAMESPACE файлы в конце вопроса. Если другие части актуальны, яБуду рад опубликовать их тоже. Просто дай мне знать!

[email protected]:~$ 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) ))
}

Я думаю, что ключ здесь что-то странное в пространстве имен. Обратите внимание, что если я отлаживаю функцию, я могу вручную вызвать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")


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

и я могу разместить дополнительные части по запросу.

Попробуйте импортироватьt отMatrix в вашем ИМЕННОМ ПРОСТРАНСТВЕ. Thomas
матрица Пакет использует методы S4, которые требуют особого внимания при импорте и экспорте. Читали ли вы раздел руководства R-exts под названиемПространства имен с классами и методами S4? Josh O'Brien
@NathanVanHoudnos - я могуне могу сказать, но похоже, что это сработало для вас, так чтохорошо! (Изучение того, как это работает, является одним из тех мостов, которые яЯ понял, что яЯ перейду, когда и если я доберусь до него. Теперь, благодаря тебе, яу меня будет несколько ориентиров, если я сделаю.) Josh O'Brien
@JoshO»Брайен Готово. Если у вас есть минутка, не могли бы вы проверить, что мой ответ на самом деле правильный? Nathan VanHoudnos

Ваш Ответ

1   ответ
3
Рабочий пример на gitHub

Я поместил рабочий пример на gitHub, чтобы было легко просматривать разные файлы.

К вашему сведениюне совсем минимальный пример, так как он был построен сdevtools, "дополнительные услуги» являются (1) чтоroxygen2 комментарии - это то, что создает файл NAMESPACE, и (2) он включает в себя модульное тестирование сtestthat, Все это может быть проигнорировано для целей этого примера.

Ключ исправить

Короткий ответ, который я действительно сделал, должен изменить мой файл NAMESPACE на:

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

Чтобы R мог найти правильную версию транспонирования. Видеть этосообщение для отличного описания того, как R ищет функции.

Хотя это не является строго необходимым, я изменил свой файл DESCRIPTION, чтобы немного чище:

Package: minimalbugexample
Title: 
Description: 
Version: 0.1.3
Author: Nathan VanHoudnos <[email protected]>
Maintainer: Nathan VanHoudnos <[email protected]>
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'
</[email protected]></[email protected]>

Обратите внимание, что я использую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

Обратите внимание, что последняя команда потерпела бы неудачу, если бы я указалMatrix вImports: и не .Depends:

Похожие вопросы