Подтвердить что ты не робот

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

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

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

Я подумал:

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

Например, 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: Мне нравится использовать уникальные версии # в моих файлах параметров, чтобы я мог позже определить набор, если я смотрю список "параметров" внутри R.) Просто позвоните в свой script и укажите на файл параметров, например:

Rscript --vanilla MyScript.R parameters01.json

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

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

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


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

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

Ответ 3

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

btw здесь моя маленькая оболочка script,

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

Ответ 4

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

    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) и присоедините второй.

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

Ответ 5

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

Ответ 6

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

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

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

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

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

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

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

Ответ 7

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