Воспроизводимое исследование: преобразование файлов данных sas7bdat в файлы csv путем вызова statTransfer с помощью GNU make

ВОПРОС:

Я новичок в GNU Make. Есть ли лучший способ программно преобразовать наборы статистических данных из sas7bdat в файлы csv и синхронизировать их друг с другом с помощью GNU Make для содействия воспроизводимым исследованиям? Подойдете ли вы к этой проблеме иначе с точки зрения кодирования, или есть лучший способ продвигать воспроизводимые исследования? Могу ли я добавить дополнительное условие (например, statTransferOptions.txt) при использовании правил статического шаблона?

Решение должно:

  • Найдите все файлы sas7bdat во всех подкаталогах
  • Читать статистикуПараметры передачи
  • Преобразуйте файл sas7bdat в файл csv с помощью инструмента командной строки statTransfer с параметрами.
  • Given the current limitations of statTransfer, I think this will require a two step process:
    • Build statTransfer command file (.stcmd) for each SAS data file (.sas7bdat)
    • Создайте файл csv для каждого файла stcmd, выполнив statTransfer (st) с использованием параметров в файле stcmd
    • целевые файлы stcmd и csv должны находиться в том же подкаталоге, что и необходимый файл sas7bdat
    • Найдите устаревшие файлы stcmd и csv и обновите их, если существует новый файл sas7bdat или если файл базовых опций изменяется.

КОНТЕКСТ:

Мне в наследство достался большой статистический отчет, который публикуется ежегодно. В предыдущие годы анализ проводился в SAS. Теперь мы используем R. Некоторые из файлов sas7bdat, сгенерированных SAS Enterprise Guide, некорректно импортируются с пакет sas7bdat. StatTransfer, коммерческий продукт, имеет интерфейс командной строки и правильно конвертирует файлы sas7bdat в файлы csv; однако есть параметры, улучшающие преобразование (например, запись форматов даты). Файлы sas7bdat находятся в нескольких подкаталогах, соответствующих типу набора данных и году.

К такому подходу подтолкнули:

Гандруд, Кристофер (21.06.2013). Воспроизводимое исследование с помощью R и RStudio (Chapman & Hall / CRC The R Series) (стр. 104-105). Чепмен и Холл / CRC. Kindle Edition.

ИСПРАВЛЕНИЕ ПРОБЛЕМ:

ПРЕДЛАГАЕМЫЙ МАКЕФИЛЬ?

RDIR := .

######
#PREP#
######
# Use BASH shell to create list of source sas7bdat files
SASDATA = $(shell find $(RDIR) -type f -name '*.sas7bdat')

# Use pattern substring functions to define variable list of filenames
# to be used as targets in recipes
STCMD_OUT = $(patsubst $(RDIR)/%.sas7bdat, $(RDIR)/%.stcmd, $(SASDATA))
CSV_OUT = $(patsubst $(RDIR)/%.sas7bdat, $(RDIR)/%.csv, $(SASDATA))

#########
#TARGETS#
#########

all: $(STCMD_OUT) $(CSV_OUT)

# I think the name "static pattern rules" is misleading
# but I found this to be helpful:
# http://www.gnu.org/software/make/manual/make.html#Static-Pattern

# can I add statTransferOptions.txt as a pre-requisite while using static pattern rules?

$(STCMD_OUT): $(RDIR)/$(@D)/%.stcmd: $(RDIR)/$(@D)/%.sas7bdat
    cp $(RDIR)/statTransferOptions.txt $@
    echo copy $(RDIR)/$< delim $(RDIR)/$(basename $<).csv -v >> $@
    echo quit >> $@

$(CSV_OUT): $(RDIR)/$(@D)/%.csv: $(RDIR)/$(@D)/%.stcmd
    st $(RDIR)/$<

clean:
    rm $(STCMD_OUT)
    rm $(CSV_OUT)

ПЕРЕСМОТРЕННЫЙ МАКЕФАЙЛ ПОСЛЕ ВВОДА ОТ:

RDIR := .

######
#PREP#
######
# Create list of source sas7bdat files
SASDATA := $(shell find $(RDIR) -type f -name '*.sas7bdat')

STCMD_OUT := $(patsubst $(RDIR)/%.sas7bdat, $(RDIR)/%.stcmd, $(SASDATA))
CSV_OUT := $(patsubst $(RDIR)/%.sas7bdat, $(RDIR)/%.csv, $(SASDATA))

#########
#TARGETS#
#########

all: $(STCMD_OUT) $(CSV_OUT)

$(STCMD_OUT): %.stcmd: %.sas7bdat statTransferOptions.txt
    cp $(RDIR)/statTransferOptions.txt $@
    echo copy $(RDIR)/$< delim $(RDIR)/$(basename $<).csv -v -y >> $@
    echo quit >> $@

$(CSV_OUT): %.csv: %.stcmd
    st $(RDIR)/$<

clean:
    rm $(STCMD_OUT)
    rm $(CSV_OUT)

Однако правильным вариантом может быть отладка пакета CRAN sas7bdat, чтобы была доступна вся цепочка инструментов, а не запуск проприетарного statTransfer.


person penguinv22    schedule 16.12.2013    source источник
comment
Сообщали ли вы об ошибке импорта разработчику sas7bdat с примером файла sas?   -  person Spacedman    schedule 16.12.2013
comment
К сожалению нет. Пакет работает с другими файлами sas7bdat, а неудачные файлы имеют большой размер (›100 МБ) и содержат конфиденциальную информацию, которой нельзя поделиться.   -  person penguinv22    schedule 16.12.2013
comment
Если дело в структуре данных (а не в чистом размере), то может быть легко создать небольшой файл, который не работает точно так же. Но не бери в голову.   -  person Spacedman    schedule 16.12.2013
comment
Я не думаю, что включение StatTransfer в рабочий процесс, необходимый для воспроизведения, - хорошая идея. Он запатентован и, следовательно, несет в себе все связанные с этим минусы. Лучше выполнить преобразование, сохранить сценарий, необходимый для этого преобразования, а затем распространить этот код вместе с набором данных, сохраненным в лучшем формате. Воспроизводимость означает, что любой может воспроизвести анализ, поэтому требуются ограничения StatTransfer, которые могут его воспроизвести.   -  person Thomas    schedule 16.12.2013
comment
@ Томас, я согласен. После того, как отчет, над которым я работаю, будет готов, мне нужно будет вернуться к вопросу о том, почему преобразование не удалось с пакетом sas7bdat (отменено после нескольких часов работы на i7 с 16 ГБ оперативной памяти). Это показалось сложным процессом - свести его к минимально воспроизводимому примеру, которым я мог бы поделиться с сопровождающим пакета.   -  person penguinv22    schedule 16.12.2013


Ответы (1)


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

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

SASDATA = $(shell find $(RDIR) -type f -name '*.sas7bdat')

Здесь вам следует использовать := форму назначения. Вероятно, вам следует использовать его также при настройке STCMD_OUT и CSV_OUT, хотя это менее важно.

Но самое главное, что эти правила неверны:

$(STCMD_OUT): $(RDIR)/$(@D)/%.stcmd: $(RDIR)/$(@D)/%.sas7bdat

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

$(STCMD_OUT): %.stcmd: %.sas7bdat

? То же самое для другого правила статического шаблона?

Что касается вашего вопроса, да, вполне нормально добавить дополнительные предварительные условия, такие как statTransferOptions.txt, в правило статического шаблона.

person MadScientist    schedule 16.12.2013
comment
Я боролся с этим Makefile большую часть двух дней и хотел поделиться своими исследованиями и получить отзывы. Из предыдущей версии я думал, что научил себя, что $(STCMD_OUT): %.stcmd: %.sas7bdat либо не найдет зависимость, либо выгрузит цель в базовом каталоге, а не в том же каталоге, что и файл sas7bdat; однако я пробовал ваше решение, и оно работает. Спасибо. - person penguinv22; 16.12.2013
comment
Согласно комментарию @MadScientist, следующее работает и запустит рецепт, если файл базовых опций будет обновлен: $(STCMD_OUT): %.stcmd: %.sas7bdat statTransferOptions.txt - person penguinv22; 16.12.2013