2012-01-17 30 views
29

Tôi đang nghiên cứu phát triển gói R, sử dụng devtools, testthat và roxygen2. Tôi có một vài tập dữ liệu trong thư mục dữ liệu (foo.txt và bar.csv).Có thể sử dụng dữ liệu gói R trong các thử nghiệm testthat hoặc run_examples() không?

cấu trúc tập tin của tôi trông như thế này:

/ mypackage 
    /data 
     * foo.txt, bar.csv 
    /inst 
     /tests 
      * run-all.R, test_1.R 
    /man 
    /R 

Tôi khá chắc chắn 'foo' và 'bar' được ghi nhận một cách chính xác:

#' Foo data 
    #' 
    #' Sample foo data 
    #' 
    #' @name foo 
    #' @docType data 
    NULL 
    #' Bar data 
    #' 
    #' Sample bar data 
    #' 
    #' @name bar 
    #' @docType data 
    NULL 

Tôi muốn sử dụng các dữ liệu trong ' foo 'và' bar 'trong các ví dụ về tài liệu và các bài kiểm tra đơn vị của tôi.

Ví dụ, tôi muốn sử dụng những bộ dữ liệu trong các thử nghiệm testthat của tôi bằng cách gọi:

data(foo) 
    data(bar) 
    expect_that(foo$col[1], equals(bar$col[1])) 

Và, tôi muốn các ví dụ trong tài liệu hướng dẫn để trông như thế này:

#' @examples 
    #' data(foo) 
    #' functionThatUsesFoo(foo) 

Nếu tôi cố gắng gọi dữ liệu (foo) trong khi phát triển gói, tôi nhận được lỗi "tập dữ liệu 'foo' không tìm thấy". Tuy nhiên, nếu tôi xây dựng các gói phần mềm, cài đặt nó, và tải nó - sau đó tôi có thể làm cho các bài kiểm tra và ví dụ làm việc.

hiện công việc ở quanh tôi là để không chạy ví dụ:

#' @examples 
    #' \dontrun{data(foo)} 
    #' \dontrun{functionThatUsesFoo(foo)} 

Và trong các bài kiểm tra, trước khi tải các dữ liệu sử dụng một đường dẫn cụ thể vào máy tính địa phương của tôi:

foo <- read.delim(pathToFoo, sep="\t", fill = TRUE, comment.char="#") 
    bar <- read.delim(pathToBar, sep=";", fill = TRUE, comment.char="#" 
    expect_that(foo$col[1], equals(bar$col[1])) 

này có vẻ không lý tưởng - đặc biệt là kể từ khi tôi cộng tác với những người khác - yêu cầu tất cả các cộng tác viên phải có cùng một đường dẫn đến 'foo' và 'bar'. Ngoài ra, các ví dụ trong tài liệu trông giống như chúng không thể chạy được, mặc dù khi gói được cài đặt, chúng có thể.

Mọi đề xuất? Cảm ơn nhiều.

+1

Không sử dụng dữ liệu(). Chỉ cần dựa vào tải chậm. – hadley

+0

Xin lỗi về nhận xét cuối cùng đó, tôi vẫn đang sử dụng định dạng này. Cảm ơn @hadley. Điều đó đã giúp với các bài kiểm tra testthat. Tôi vẫn đang thua lỗ về cách tạo một ví dụ trong tài liệu (sử dụng roxygen2) cho phép tôi tận dụng lợi thế của tập dữ liệu. – JPMac

+2

Nếu bạn chuyển đổi dữ liệu thành tệp '.Rdata', thì' load_all' sẽ tải nó cho bạn. – hadley

Trả lời

17

Nhập file không rdata trong ví dụ/kiểm tra

Tôi tìm thấy một giải pháp cho vấn đề này bằng cách nhìn vào the JSONIO package, mà rõ ràng là cần thiết để cung cấp một số ví dụ về đọc file khác hơn so với sự đa dạng .RData.

Tôi đã làm việc này trong các ví dụ cấp chức năng và đáp ứng cả hai số R CMD check mypackage cũng như testthat::test_package().

(1) Sắp xếp lại cấu trúc gói của bạn để thư mục dữ liệu mẫu nằm trong phạm vi inst. Tại một số điểm R CMD check mypackage đã yêu cầu tôi chuyển các tệp dữ liệu không phải RData thành inst/extdata, vì vậy trong cấu trúc mới này, cũng được đổi tên.

/ mypackage 
    /inst 
     /tests 
      * run-all.R, test_1.R 
     /extdata 
      * foo.txt, bar.csv 
    /man 
    /R 
    /tests 
     * run-testthat-mypackage.R 

(2) (Tùy chọn) Thêm một cấp cao nhất tests thư mục để kiểm tra testthat mới của bạn bây giờ cũng chạy trong R CMD check mypackage.

Kịch bản run-testthat-mypackage.R nên có tối thiểu hai dòng sau:

library("testthat") 
test_package("mypackage") 

Lưu ý rằng đây là phần cho phép testthat được gọi trong R CMD check mypackage, và không cần thiết khác. Bạn cũng nên thêm testthat làm phụ thuộc "Đề xuất:" trong tệp DESCRIPTION của mình.

(3) Cuối cùng, bí mật-sốt để xác định bạn đường trong gói:

barfile <- system.file("extdata", "bar.csv", package="mypackage") 
bar <- read.csv(barfile) 
# remainder of example/test code here... 

Nếu bạn nhìn vào đầu ra của lệnh system.file(), nó đang trở lại con đường toàn bộ hệ thống để gói của bạn trong vòng khung R. Trên Mac OS X này trông giống như sau:

"/Library/Frameworks/R.framework/Versions/2.15/Resources/library/mypackage/extdata/bar.csv" 

Lý do này có vẻ ổn với tôi là bạn làm mã không cứng bất kỳ đường dẫn tính năng khác hơn so với những người trong gói của bạn, vì vậy phương pháp này nên mạnh mẽ so với khác Cài đặt R trên các hệ thống khác.

data() cách tiếp cận

Đối với data() ngữ nghĩa, như xa như tôi có thể nói đây là đặc trưng cho R nhị phân (.RData) file trong top-level thư mục data. Vì vậy, bạn có thể phá vỡ ví dụ của tôi ở trên bằng cách nhập sẵn các tệp dữ liệu và lưu chúng với lệnh save() vào thư mục dữ liệu của bạn. Tuy nhiên, điều này giả định bạn chỉ cần hiển thị một ví dụ trong đó dữ liệu đã được nạp vào R, trái ngược với việc thể hiện rõ ràng quá trình ngược dòng của việc nhập các tệp.

+0

Cảm ơn câu trả lời chuyên sâu! – JPMac

+0

Bạn được chào đón. Tôi rất vui vì nó đã giúp. Nó trở nên hữu ích cho gói devel của riêng tôi, vì vậy tôi muốn chia sẻ. –

+0

Tôi đã cố gắng tìm ra cách làm cho "quá trình nhập khẩu thượng nguồn" có thể tái sản xuất. Một trường hợp sử dụng điển hình mà tôi có là tôi muốn làm việc với một phép biến đổi một số shapefile không tầm thường --- có thể mất một phút. Tôi có thể bao gồm các shapefile trong 'inst/extdata', nhưng tôi không bao giờ có thể tìm thấy đường dẫn đó từ mã thực thi bên trong' install() '. Ngoài ra, ngay cả 'document()' có vẻ muốn xây dựng lại tất cả các tệp '.r' bên trong' data/'. Tôi không muốn xây dựng lại chúng mỗi khi tôi thêm hoặc thay đổi tài liệu cho một hàm. Một 'dữ liệu/Makefile' nhưng có vẻ như kludgey. Mẹo được đánh giá cao! – dholstius

2

Mỗi nhận xét của @ hadley, chuyển đổi .RData sẽ hoạt động tốt.

Đối với câu hỏi rộng hơn về hợp tác nhóm với các môi trường khác nhau trong các thành viên nhóm, mẫu chung là đồng ý trên một biến môi trường, ví dụ: FOO_PROJECT_ROOT, mọi người trong nhóm sẽ thiết lập phù hợp trong môi trường của họ. Từ thời điểm đó, bạn có thể sử dụng các đường dẫn tương đối, bao gồm cả các dự án.

Cách tiếp cận cụ thể cho R sẽ là đồng ý về một số dữ liệu/chức năng mà mọi thành viên trong nhóm sẽ thiết lập trong các tệp .Rprofile của họ. Đó là, ví dụ, cách devtools tìm các gói ở các vị trí không chuẩn.

Cuối cùng nhưng không kém phần quan trọng, mặc dù nó không phải là tối ưu, bạn thực sự có thể đặt mã dành riêng cho nhà phát triển trong kho lưu trữ của mình. Nếu @hadley làm điều đó, nó không phải là một điều xấu. Xem ví dụ: cách anh ta activates certain behaviors trong testthat trong môi trường của riêng mình.

+0

Đây cũng là thông tin tuyệt vời, cảm ơn nhiều. – JPMac