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