Стратегии для повторения большого объема анализа

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

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

Я считал:

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

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

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

7 ответов

Решение

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

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

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

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

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

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

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

Например, 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) это прекрасное решение.

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

Мне нравится работать с комбинацией небольшого сценария оболочки, программы обрезки 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 файлы, упомянутые выше, когда это необходимо. Я не уверен, что это то, что вы ищете, но это моя стратегия до сих пор. Я, по крайней мере, считаю, что создание прозрачных, воспроизводимых отчетов - это то, что помогает следовать по крайней мере стратегии.

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

    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) и прикрепить второй.

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам