2012-01-17 3 views
29

Я работаю над разработкой пакета R, используя devtools, testthat и roxygen2. У меня есть несколько наборов данных в папке с данными (foo.txt и bar.csv).Возможно ли использовать данные пакета R в тестах testthat или run_examples()?

Моя файловая структура выглядит следующим образом:

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

Я уверен, что «Foo» и «бар» задокументированы правильно:

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

Я хотел бы использовать эти данные в ' foo 'и' bar 'в моих примерах документации и модульных тестах.

Например, я хотел бы использовать эти наборы данных в моих testthat тестов по телефону:

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

И я хотел бы примеры в документации выглядеть следующим образом:

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

Если я пытаюсь вызывать данные (foo) при разработке пакета, я получаю ошибку «набор данных» foo «не найден». Однако, если я создам пакет, устанавливаю его и загружаю, то я могу сделать тесты и примеры работать.

Мои текущие обходные должны не запустить пример:

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

А в тестах, предварительно загрузить данные, используя путь, специфичные для моего локального компьютера:

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

Этом не кажется идеальным - особенно потому, что я сотрудничаю с другими людьми, требуя, чтобы все соавторы имели одинаковые полные пути к «foo» и «bar». Кроме того, примеры в документации выглядят так, что они не могут быть запущены, хотя после установки пакета они могут.

Любые предложения? Большое спасибо.

+1

Не используйте данные(). Просто полагайтесь на ленивую загрузку. – hadley

+0

Извините, что последний комментарий, я все еще использую это форматирование. Спасибо @hadley. Это помогло с тестами testthat. Я все еще не понимаю, как сделать пример в документации (используя roxygen2), который позволяет мне воспользоваться набором данных. – JPMac

+2

Если вы преобразуете данные в файлы '.Rdata', тогда' load_all' загрузит его для вас. – hadley

ответ

17

Импорт не-RDATA файлов в примерах/тесты

Я нашел решение этой проблемы, вглядываясь в the JSONIO package, что, очевидно, необходимый для обеспечения некоторых примеров чтения, отличные от многообразия .rdata файлов.

Я получил это, чтобы работать на примерах функционального уровня и удовлетворять как R CMD check mypackage, так и testthat::test_package().

(1) Восстановите структуру своего пакета, чтобы каталог данных примеров находился в пределах inst. В какой-то момент R CMD check mypackage сказал мне переместить файлы данных не RData в inst/extdata, поэтому в этой новой структуре, которая также переименована.

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

(2) (Необязательно) Добавление верхнего уровня tests каталога, так что ваши новые тесты testthat теперь также работать во время R CMD check mypackage.

run-testthat-mypackage.R скрипт должен иметь, как минимум, следующие две строки:

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

Обратите внимание, что это та часть, которая позволяет testthat называться во время R CMD check mypackage, да и не нужно иначе. Вы должны добавить testthat в качестве зависимости «Предлагает:» в вашем файле DESCRIPTION.

(3) И, наконец, секрет соуса для указания вашего внутригрупповой пакета путь:

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

Если вы посмотрите на вывод команды system.file(), он возвращается полный системный путь к пакету в R-рамки. В Mac OS X это выглядит примерно так:

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

Причина этого, кажется, хорошо для меня является то, что вы не жесткий код любого пути доступа, кроме тех, в пределах пакета, поэтому такой подход должен быть устойчивым по отношению к другим R на других системах.

data() подход

Что касается data() семантики, насколько я могу сказать, что это относится только к R двоичном (.RData) файлов в верхнем уровне data каталога. Таким образом, вы можете обойти мой пример выше, предварительно импортируя файлы данных и сохраняя их с помощью команды save() в свой каталог данных. Тем не менее, это предполагает, что вам нужно показать только пример, в котором данные уже загружены в R, в отличие от того, чтобы воспроизводимо демонстрировать восходящий процесс импорта файлов.

+0

Спасибо за подробный ответ! – JPMac

+0

Добро пожаловать. Я рад, что это помогло. Это стало полезным для моего собственного пакета, поэтому я хотел поделиться. –

+0

Я пытался выяснить, как сделать «восходящий процесс импорта» воспроизводимым. Типичный случай использования, который у меня есть, заключается в том, что я хочу работать с преобразованием некоторых шейп-файлов, которые не являются тривиальными - может быть, это занимает минуту или около того. Я могу включить шейп-файлы в 'inst/extdata', но я никогда не могу найти этот путь из кода, выполняемого внутри' install() '. Кроме того, даже 'document()', похоже, хочет перестроить все файлы '.r' внутри' data/'. Я не хочу перестраивать их каждый раз, когда я добавляю или изменяю документацию для функции. «Данные/Makefile», но это кажется kludgey. Советы оценены! – dholstius

2

Комментарий от Per @ hadley, преобразование .RData будет работать хорошо.

Что касается более широкого вопроса о коллективном сотрудничестве с различными средами между членами команды, то общей схемой является согласование одной переменной окружения, например, FOO_PROJECT_ROOT, что каждый человек в команде будет настроен соответствующим образом в своей среде. С этого момента вы можете использовать относительные пути, в том числе по всем проектам.

R-специфический подход заключается в согласовании некоторых данных/функций, которые каждый член команды будет устанавливать в своих файлах .Rprofile. Это, например, то, как devtools находит пакеты в нестандартных местах.

И последнее, но не менее важное: хотя это не оптимально, вы можете на самом деле добавить код разработчика в свой репозиторий. Если @hadley делает это, это не так уж плохо. См. Например, как он activates certain behaviors в testthat в своей собственной среде.

+0

Это отличная информация, спасибо большое. – JPMac

 Смежные вопросы

  • Нет связанных вопросов^_^