2015-06-11 10 views
6

Tôi đang làm việc trên gói R hiện tại và cố gắng làm theo các hướng dẫn thực hành tốt nhất do Hadley Wickham cung cấp http://r-pkgs.had.co.nz. Là một phần của điều này, tôi muốn có tất cả các gói phụ thuộc trong phần Nhập khẩu của tệp DESCRIPTION thay vì Phụ thuộc vì tôi đồng ý với triết lý không cần thiết thay đổi môi trường toàn cầu (điều mà nhiều gói CRAN và Bioconductor don dường như không theo).Cách sử dụng các phương thức S3 từ gói khác sử dụng xuất thay vì S3method trong không gian tên của nó mà không sử dụng Phụ thuộc hoặc thư viện()

Tôi muốn sử dụng các hàm trong gói Bioconductor rhdf5 trong một trong các hàm gói của tôi, cụ thể là h5write(). Vấn đề tôi đã gặp phải là nó không có các phương thức S3 được khai báo như vậy trong NAMESPACE của nó. Họ được khai báo sử dụng (ví dụ)

export(h5write.default) 
export(h5writeDataset.matrix) 

hơn

S3method(h5write, default) 
S3method(h5writeDataset, matrix) 

Các h5write chung được định nghĩa là:

h5write <- function(obj, file, name, ...) { 
res <- UseMethod("h5write") 
    invisible(res) 
} 

Trong thực tế, điều này có nghĩa rằng các cuộc gọi đến rhdf5 :: h5write thất bại vì không có phương pháp h5write thích hợp nào được đăng ký.

Theo như tôi thấy, có ba giải pháp này:

  1. Sử dụng Depends hơn Imports trong file MÔ TẢ.
  2. Sử dụng library("rhdf5") hoặc require("rhdf5") trong mã cho hàm có liên quan.
  3. Sửa đổi tệp NAMESPACE cho rhdf5 để sử dụng S3methods() thay vì export().

Tất cả những điều này đều có nhược điểm. Tùy chọn 1 có nghĩa là gói được tải và được gắn vào môi trường toàn cục ngay cả khi chức năng liên quan trong gói của tôi không bao giờ được gọi. Tùy chọn 2 có nghĩa là sử dụng library trong một gói, trong khi một lần nữa gắn gói vào môi trường toàn cầu và cũng không được chấp nhận theo hướng dẫn của Hadley Wickham. Tùy chọn 3 có nghĩa là dựa vào tác giả gói khác để cập nhật gói của họ trên Bioconductor và cũng có nghĩa là các phương thức S3 không còn được xuất khẩu nữa mà có thể phá vỡ các gói khác dựa vào việc gọi chúng một cách rõ ràng.

Tôi đã bỏ lỡ một giải pháp thay thế khác? Tôi đã tìm ở đâu đó trên StackOverflow và tìm thấy các câu hỏi có liên quan sau đây Importing S3 method from another packageHow to export S3 method so it is available in namespace? nhưng không có gì trực tiếp giải quyết vấn đề của tôi. Lưu ý, sự khác biệt chính từ đầu tiên của hai là chung chung và phương pháp là cả hai trong cùng một gói, nhưng vấn đề là việc sử dụng export thay vì S3method.

Mẫu mã để tạo lại lỗi (mà không cần phải tạo ra một gói phần mềm):

loadNamespace("rhdf5") 
rdhf5::h5write(1:4, "test.h5", "test") 

Error in UseMethod("h5write") : 
no applicable method for 'h5write' applied to an object of class 
"c('integer', 'numeric') 

Ngoài ra, có một gói xương ở https://github.com/NikNakk/s3issuedemo mà cung cấp một chức năng duy nhất demonstrateIssue() mà tái tạo thông báo lỗi. Nó có thể được cài đặt bằng cách sử dụng devtools::install_github("NikNakk/s3issuedemo").

+0

Tôi không chắc câu hỏi chính xác của bạn là gì, bạn có đang cố gắng sử dụng các phương pháp gói không? Bạn đang cố gắng tạo các phương pháp mới? Mục tiêu của bạn là gì? Câu hỏi của bạn được chi tiết nhưng không rõ ràng. – cdeterman

+0

Xin lỗi nếu tôi không rõ ràng. Tôi muốn sử dụng hàm rhdf5 :: h5write trong một hàm trong gói của tôi. Mọi thứ hoạt động tốt nếu tôi đính kèm gói rhdf5 vào môi trường toàn cầu bằng cách sử dụng 'Depends' hoặc' library() '. Nó cũng hoạt động tốt nếu tôi thay đổi tệp NAMESPACE của gói khác để sử dụng 'S3method()' thay vì 'export()'. Nhưng nếu không, nó không thành công. Tôi đã sửa đổi câu hỏi của mình ở trên. –

+0

Bạn có thể cung cấp ví dụ tái sản xuất không? Đây là gói của bạn trên github, nơi chúng tôi có thể nhìn thấy mã nguồn của bạn? – cdeterman

Trả lời

6

Chìa khóa ở đây là nhập các phương thức cụ thể ngoài loại chung bạn muốn sử dụng.Đây là cách bạn có thể làm cho nó hoạt động cho phương thức mặc định.

Lưu ý: điều này giả định rằng tệp test.h5 đã tồn tại.

#' @importFrom rhdf5 h5write.default 
#' @importFrom rhdf5 h5write 
#' @export 
myFun <- function(){ 
    h5write(1:4, "test.h5", "test") 
} 

Tôi cũng đã đưa gói nhỏ của riêng mình chứng minh điều này here.

+0

Rất cám ơn. Điều đó khắc phục được sự cố. –

Các vấn đề liên quan