Стратегии для повторения большого объема анализа - PullRequest
22 голосов
/ 22 июня 2011

Я нахожусь в состоянии выполнить большой анализ, и теперь мне нужно повторить анализ с немного другими исходными предположениями.

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

Я считал:

  • Создание функции. Это не идеально, потому что тогда я должен изменить свой код, чтобы знать, оцениваю ли я в функции или родительской среде. Эти дополнительные усилия кажутся чрезмерными, затрудняют отладку и могут вызывать побочные эффекты.
  • Заверните это в цикл. Опять же, не идеально, потому что тогда я должен создать индексные переменные, которые также могут вводить побочные эффекты.
  • Создание некоторого предварительного кода, упаковка анализа в отдельный файл и source его. Это работает, но кажется очень уродливым и неоптимальным.

Цель анализа - закончить набором объектов (в списке или в отдельных выходных файлах), которые я могу проанализировать на предмет дальнейших различий.

Какова хорошая стратегия для решения этого типа проблемы?

Ответы [ 7 ]

17 голосов
/ 22 июня 2011

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

Вопрос о том, стоит ли инвестировать, вероятно, является ключевым вопросом в информатике (если не во многих других областях): я пишу сценарий для переименования 50 файлов аналогичным образом, или я продолжаю и переименовываю их вручную.

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

Тем не менее, в вашем конкретном случае: я бы выбрал вариант выбора источника: поскольку вы планируете повторно использовать код только в 2 раза больше, вероятно, будут потрачены большие усилия (вы указываете, что анализ довольно обширный). Так что, если это не элегантное решение? Никто никогда не увидит, как вы это делаете, и все будут довольны быстрыми результатами.

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

Если / когда я заранее знаю, что собираюсь повторно использовать код, я стараюсь помнить об этом при его разработке. В любом случае я вряд ли когда-нибудь напишу код, который не входит в функцию (ну, за исключением двух строк для SO и других готовых анализов): я считаю, что это облегчает мне структурирование моих мыслей.

10 голосов
/ 01 июля 2011

Если это вообще возможно, установите параметры, которые отличаются между наборами / прогонами / экспериментами во внешнем файле параметров. Затем вы можете получить исходный код, вызвать функцию, даже использовать пакет, но операции определяются небольшим набором внешних параметров.

Например, JSON отлично подходит для этого, а пакеты RJSONIO и rjson позволяют загружать файл в список. Предположим, вы загрузили его в список с именем параметровNN.json. Пример выглядит следующим образом:

{
 "Version": "20110701a",
 "Initialization":
 {
   "indices": [1,2,3,4,5,6,7,8,9,10],
   "step_size": 0.05
 },
 "Stopping":
 {
   "tolerance": 0.01,
   "iterations": 100
 }
}

Сохраните это как "parameters01.json" и загрузите как:

library(RJSONIO)
Params <- fromJSON("parameters.json")

и все готово. (NB: мне нравится использовать уникальные версии #s в моих файлах параметров, просто чтобы я мог определить набор позже, если я смотрю на список «параметров» в R.) Просто вызовите ваш скрипт и укажите на параметры файл, например:

Rscript --vanilla MyScript.R parameters01.json

затем в программе определите файл параметров из функции commandArgs().

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

Редактировать: если быть более точным, я бы даже указал входные и выходные каталоги или файлы (или имена / префиксы имен) в JSON. Это очень ясно показывает, как один набор параметров привел к одному конкретному выходному набору. Все, что между ними, - это просто код, который выполняется с заданной параметризацией, но код не должен сильно меняться, не так ли?


Обновление: Через три месяца и многие тысячи прогонов, мудрее моего предыдущего ответа, я бы сказал, что внешнее хранение параметров в JSON полезно для 1-1000 различных прогонов. Когда количество параметров или конфигураций исчисляется тысячами и более, лучше перейти на использование базы данных для управления конфигурацией. Каждая конфигурация может исходить из JSON (или XML), но для того, чтобы справиться с различными макетами параметров, требуется решение большего масштаба, для которого база данных, такая как SQLite (через RSQLite), является хорошим решением.

Я понимаю, что этот ответ является избыточным для первоначального вопроса - как повторить работу только пару раз, с несколькими изменениями параметров, но при масштабировании до сотен или тысяч изменений параметров в текущих исследованиях необходимы более обширные инструменты , :)

3 голосов
/ 29 июня 2011

Мне нравится работать с комбинацией небольшого сценария оболочки, программы обрезки PDF и Sweave в этих случаях. Это дает вам хорошие отчеты и призывает вас к источнику. Обычно я работаю с несколькими файлами, почти как создание пакета (по крайней мере, мне кажется, что так :). У меня есть отдельный файл для манипулирования данными и отдельные файлы для различных типов анализа, например, descriptiveStats.R, regressions.R.

Кстати, вот мой маленький сценарий оболочки,

 #!/bin/sh
 R CMD Sweave docSweave.Rnw
 for file in `ls pdfs`;
 do pdfcrop  pdfs/"$file" pdfs/"$file"
 done
 pdflatex docSweave.tex
 open docSweave.pdf 

Файл Sweave обычно содержит R файлы, упомянутые выше, когда это необходимо. Я не уверен, что это то, что вы ищете, но это моя стратегия до сих пор. Я, по крайней мере, считаю, что создание прозрачных, воспроизводимых отчетов - это то, что помогает следовать, по крайней мере, стратегии.

2 голосов
/ 04 июля 2011

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

    setup1 <- local({
          x <- rnorm(50, mean=2.0)
          y <- rnorm(50, mean=1.0)
          environment()
          # ...
        })

    setup2 <- local({
          x <- rnorm(50, mean=1.8)
          y <- rnorm(50, mean=1.5)
          environment()
          # ...
        })

attach(setup1) и запустите / введите код анализа

plot(x, y)
t.test(x, y, paired = T, var.equal = T)
...

Когда закончите, detach(setup1) и присоедините второй.

Теперь, по крайней мере, вы можете легко переключаться между настройками. Помог мне несколько раз.

1 голос
/ 04 июля 2011

Слишком поздно для вас здесь, но я часто использую Sweave, и, скорее всего, я бы использовал файл Sweave с самого начала (например, если бы я знал, что конечный продукт должен быть своего рода отчетом).

Для повторения частей анализа во второй и третий раз, есть два варианта:

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

  • если мне нужно сделать то же самое один или два раза снова в одном файле Sweave, я бы подумал о повторном использовании кусков кода. Это похоже на уродливый цикл for.

    Причина в том, что тогда, конечно, результаты объединяются для сравнения, которое затем будет последней частью отчета.

  • Если с самого начала будет ясно, что будут некоторые наборы параметров и сравнение, я напишу код таким образом, что, как только я буду в порядке с каждой частью анализа, он будет заключен в функция (т.е. я пишу функцию в окне редактора, но оцениваю строки непосредственно в рабочей области при написании функции).

Учитывая, что вы находитесь в описанной ситуации, я согласен с Ником - ничего плохого в source, а все остальное означает гораздо больше усилий, теперь, когда у вас уже есть сценарий.

1 голос
/ 03 июля 2011

Я склонен помещать такие результаты в глобальный список.Я использую Common Lisp, но тогда R не так уж отличается.

0 голосов
/ 04 марта 2014

Я не могу комментировать ответ Итератора, поэтому я должен опубликовать его здесь. Мне очень нравится его ответ, поэтому я сделал короткий скрипт для создания параметров и их экспорта во внешние файлы JSON. И я надеюсь, что кто-то найдет это полезным: https://github.com/kiribatu/Kiribatu-R-Toolkit/blob/master/docs/parameter_configuration.md

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...