Включить исходный код для работы из внешнего файла в R

У меня есть стандартная процедура анализа данных, которую мне нужно запустить на различных (~ 50 наборах данных). Я разрабатывал его в течение некоторого времени, и теперь я дошел до того, что хотел бы превратить его в функцию, которая берет набор данных и выдает какую-то разумную таблицу для каждого набора данных. Однако выполненная процедура охватывает четыре файла сценария, и до сих пор я использовал source от одного к другому для ее запуска, но кажется, что это невозможно с function.

У меня есть следующая проблема:

foo <- function(data) {
  a <- somevariable
  source("..somefile..") #The code in there uses a, but a is not in the workspace...
  ..
  continue
  ..
}

Код дает сбой, когда вы запускаете его в наборе данных.

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

Спасибо


person krhlk    schedule 20.02.2013    source источник
comment
Почему бы не сделать файлы, которые вы сейчас используете source, аргументами функции? Похоже, вы близки к тому моменту, когда вам нужно начать формализовать вещи как функции, выполняющие определенные задачи, и, возможно, создать из них небольшой пакет (или, по крайней мере, получить все свои функции, а затем использовать их в других функциях).   -  person Bryan Hanson    schedule 20.02.2013
comment
Нет, это всего лишь одноцелевой код, делать пакет бесполезно, я уже сделал довольно большой пакет для этого анализа. ;) Существует ли в R функция, которая включает только некоторый текст при компиляции?   -  person krhlk    schedule 20.02.2013
comment
Я не совсем уверен, что вы подразумеваете под «включает только текст при компиляции». Конечно, есть функции, которые включают блоки текста для передачи другой функции или записывают блоки текста в файлы, например файлы html.   -  person Bryan Hanson    schedule 20.02.2013
comment
Ах, у вас проблема с областью действия больше всего на свете. ..some file.. необходимо записать как функцию, чтобы аргументы можно было заменять, и они не должны были иметь одинаковые имена во всех контекстах. Ясно, что среда исходной функции не совпадает с вызывающей функцией, иначе вы не получили бы ту ошибку, которую делаете. Исправление проблемы с окружением потребует больше работы и больше подвержено ошибкам, чем просто кусание пули и переписывание исходных скриптов как функций.   -  person Bryan Hanson    schedule 20.02.2013
comment
Я предполагаю, что другим вариантом было бы поместить все это в файл Rnw и использовать sweave или knitr для анализа (без источника, просто включите полный код в фрагменты кода). Преимущество этого заключается в возможности писать хорошие отчеты и графики, если это важно.   -  person Bryan Hanson    schedule 20.02.2013
comment
Другими словами, такой функции не существует?   -  person krhlk    schedule 20.02.2013
comment
Если я понимаю, что вы хотите, я не думаю, что такая функция существует или даже может существовать (как общая функция может прочитать случайный фрагмент кода и получить его правильно без какой-то таблицы, которая отображает имена вещи в каждой среде?Что, кстати, является точной целью использования функций внутри функций). Возможно, вас заинтересует эта статья о дизайне языка R. Каждый раз, когда я ее перечитываю (первая часть, вторая слишком тяжелая для меня!) я получаю новую оценку. См. r.cs.purdue.edu/pub/ecoop12.pdf.   -  person Bryan Hanson    schedule 20.02.2013
comment
Я бы предложил обернуть код в какой-то файл в функцию с данными, которые будут в качестве аргумента.   -  person seandavi    schedule 20.02.2013


Ответы (3)


Я предлагаю начать с минимального примера, чтобы вы поняли, что влечет за собой написание функции, как загрузить функцию в R с помощью source(), как использовать аргументы и как вызывать функцию. После этого, надеюсь, будет более очевидно, куда идти дальше.

Чтобы ответить на ваш вопрос, если ваш скрипт включает в себя 200 строк кода и делает только одну вещь (то есть, он выполняет одну ФУНКЦИЮ), вы должны подумать о том, чтобы обернуть это в функцию, да. Это на самом деле повысит удобство для пользователя, а не снизит его, поскольку ваши сценарии теперь могут включать только одну строку (вызов функции), а не исходные 200 строк кода.

person seandavi    schedule 20.02.2013
comment
Да, я мог бы переписать это как функцию, но это заняло бы много времени, и мне было интересно, существует ли команда, которая включает только тексты? - person krhlk; 20.02.2013
comment
Я не думаю, что это займет много времени, когда вы узнаете, как это сделать, и это навык, который вы ХОТИТЕ изучить :), но source() — это то, что вы бы использовали для запуска кода из другого файла внутри вашей функции, если вы думаете, что это как-то проще. - person seandavi; 20.02.2013

Я предполагаю здесь, но что-то вроде этого:

myfunc <- function() {
if (something) source("path to script")
} else {
if (another thing) source("path to another script")
}
Do calcs and return the result
}

Или пути к сценариям могут быть аргументами функции.

person Bryan Hanson    schedule 20.02.2013

Я понимаю ваш вопрос, я предполагаю, что вы хотите использовать процедуру внутри функции, используя функцию source, поэтому вам нужно только добавить параметр local = T

Пример

#This is your source code
y<-x+1
#save in your favorite path as "your_path.R"

#Function where you will call the above code
your_function<-function(x){
source("your_path.R",local=T) #plus 1 to x. IMPORTANT: local=T
return(y)
}
person Henry Navarro    schedule 16.05.2018